C语言实现pipe功能时调用close()返回Invalid argument错误求助
问题根因分析
核心错误:系统调用返回值判断逻辑完全反向
所有POSIX标准下的系统调用(close/dup2/execve/pipe/fork等)遵循统一返回规则:
- 执行成功时返回
0(涉及文件描述符的创建类调用会返回非负整数的有效句柄) - 执行失败时返回
-1,同时设置全局变量errno标识具体错误原因
你代码中所有的错误判断条件都写反了:if (!close(pipe_fd[1]))等价于if (close(pipe_fd[1]) == 0),也就是close执行成功的时候才会触发错误退出逻辑。这时候errno并没有被本次close调用修改,保留的是之前其他函数执行后的残留值,才会出现莫名其妙的Invalid argument、Undefined error: 0报错。
修复方案
把所有系统调用的判断条件全部修正,改为判断返回值是否等于-1,示例修改如下:
// 原错误写法 if (!close(pipe_fd[1])) perror_exit("close 1 1st cmd"); if (!dup2(pipe_fd[0], STDIN_FILENO)) perror_exit("dup2 1st cmd"); // 修正后写法 if (close(pipe_fd[1]) == -1) perror_exit("close 1 1st cmd"); if (dup2(pipe_fd[0], STDIN_FILENO) == -1) perror_exit("dup2 1st cmd");
其余close、dup2、execve的判断逻辑全部按上述规则修改即可解决报错问题。
其他注意事项
- 子进程中执行
cmd = cmd->next前需要判断cmd->next是否非空,否则存在空指针访问风险 execve调用成功后不会返回,只有失败才会有返回值,因此子进程中execve后的exit(EXIT_SUCCESS)永远不会被执行,可以删除- 如果要实现标准shell管道逻辑,父进程执行
execve前需要确认子进程回收逻辑,避免产生僵尸进程
内容的提问来源于stack exchange,提问作者FoReal
相关产品推荐
相关产品推荐

