【问题标题】:dup return error (c programming in linux)dup 返回错误(linux 中的 c 编程)
【发布时间】:2013-05-19 22:18:01
【问题描述】:

我正在尝试创建一个简单的程序来模拟终端中的“ls -l | tail -n 2”调用。为此,我正在使用“fork”和“execvp”。 好了,代码如下:

int main(int argc, char *argv[])
{
    int pipefd[2];
    pid_t child1;
    pid_t child2;
    char* com1[] = {"ls", "-l",NULL};
    char* com2[] = {"tail", "-n","2",NULL};

    if (!(child1 = fork())) 
    { 
       close(STDOUT);
       dup(pipefd[1]); 
       close(pipefd[1]); 
       execvp (com1[0], com1);
       _exit(EXIT_SUCCESS);
    }
    else
    {
        close(pipefd[1]);
        if (!(child2 = fork())) 
        { 
            close(STDIN);
            dup(pipefd[0]); /* dupWR now holds the lowest fd available, meaning STDOUT's */
            perror("dup 2");
            close(pipefd[0]); /* reader will see EOF */
            execvp (com2[0], com2);
            _exit(EXIT_SUCCESS);
        }
        else
        {
            close(pipefd[0]);
            waitpid(child2,0,0);
        }
        waitpid(child1,0,0);
    }


    return 0;
}

我收到以下错误:

dup 2: Bad file descriptor
tail: cannot fstat `standard input': Bad file descriptor
tail: -: Bad file descriptor

在我看来,同步存在问题。事实上,如果我声明: com2[] = {"ls", "-l",NULL};它工作正常(我的意思是在普通外壳中)。此外,我发现第二个“fork”中的第二个“dup”返回错误。这是为什么?我不知道这段代码的问题在哪里。请帮忙!

编辑: 我添加了这段代码(忘记创建管道):

if (pipe(pipefd) == -1) {
    perror("pipe");
    exit(EXIT_FAILURE);
}

谢谢,没用!

【问题讨论】:

  • 我只想指出,您根本不是在“模拟”ls -l | tail -n 2,您实际上是在运行它。您只是以非常冗长的方式输入命令。 :-)
  • 您是否在某处定义了 STDIN 和 STDOUT?
  • 任何有兴趣进一步阅读此主题的人都应该真正查看man7.org/tlpi 的第 44 章。具体来说,“使用管道连接过滤器”概述了整个过程,并显示了以下解决方案如何不完全正确。下面的解决方案假定 STDOUT 是打开的,这不能保证。此外,它假定 pipefd[1] != STDOUT_FILENO,这也不能保证。

标签: c linux fork dup


【解决方案1】:
close(STDOUT);
dup(pipefd[1]); 
close(pipefd[1]); 

由于dup返回新的文件描述符,而你没有使用返回值,你将它丢弃。

您想像这样替换标准输出吗?

dup2(pipefd[1], STDOUT_FILENO);

如果是这样,pipefd[] 应该首先初始化。您的意思是在某个地方给pipe 打电话吗?

【讨论】:

  • 他丢弃 FD 并不重要,因为它是 STDOUT 或 STDIN 的已知值,对吧?但显然需要先创建管道。虽然 dup2 比 dup 好,但它应该仍然可以正常工作(在实际调用管道之后)
  • 不,dup知道您想替换标准输出,是吗?它返回一个新的文件描述符,它的值可能为 1,但可能不是必需的。
猜你喜欢
  • 1970-01-01
  • 2016-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多