【发布时间】:2012-12-27 09:01:36
【问题描述】:
我正在尝试使用 execvp 运行 ls|wc。所以我创建了一个管道然后 fork 来创建一个孩子。我关闭父/子中的适当(读/写)端,然后将另一端映射到标准输出/标准输入。然后我在子进程中使用 execvp 和 wc 在父进程中运行 ls。当我运行程序时它说
wc:standard input:bad file descriptor.
0 0 0
wc: -:Bad file descriptor
这是我的代码:
int main()
{
//int nbBytes = 0; //stream length
int pfd_1[2]; //file descriptor
//char buffer[MAX_FILE_LENGTH];
char* arg[MAX_FILE_LENGTH];
pid_t processPid;
//Create a pipe
if(pipe(pfd_1) == -1)
{
printf("Error in creating pipe");
return 0;
}
//Create a child
processPid = fork();
if(processPid == -1)
{
printf("Erro in fork");
exit(1);
}
else if(processPid == 0) //Child
{
//redirect read end file descriptor to standard input
dup2(pfd_1[0],0);
//Close the write end
if(close(pfd_1[1] == -1))
{
printf("Error in closing the write end file descriptor");
exit(1);
}
arg[0] = "wc";
//arg[1] = "-l";
arg[1] = '\0';
if(execvp(arg[0],arg) == -1)
{
printf("Error in executing ls");
}
}
else //Parent
{
//redirect standard output to the file descriptor
dup2(pfd_1[1],1);
//Close the read end
if(close(pfd_1[0] == -1))
{
printf("Error in closing the read end from parent");
exit(1);
}
//Command
arg[0] = "ls";
arg[1] = "/proc/1/status";
arg[2] = '\0';
if(execvp(arg[0],arg) == -1)
{
printf("Error in executing ls");
}
}
}
知道可能出了什么问题吗?为什么它会将标准输入视为错误的文件描述符?我的理解是因为标准输入和读取结束文件描述符是别名,所以 wc -l 会读取父进程的任何输出。我是否需要进行 scanf 才能从标准输入中读取?
【问题讨论】:
-
错误信息属于标准错误。不要使用
printf来显示它们。相反,请使用perror。这还将显示系统错误消息,告诉您错误的原因。此外,您将打开文件描述符。尝试:dup2( pfd_1[0], 0 ); close( pfd_1[0]); close( pfd_1[1]);并检查 dup2 是否成功。
标签: c unix pipe file-descriptor