作为 Unix 编程的一个练习,我编写了一个程序,它创建两个管道,分叉一个孩子,然后通过管道向孩子发送和接收一些文本。如果在子进程中我使用函数中的代码读取和写入数据,它就可以工作filter
。但是,如果孩子试图将管道重定向到其标准输入和标准输出(使用dup2
)并执行(使用execlp
)tr
实用程序,那么它不起作用,它会卡在某个地方。此代码在filter2
函数中。问题是,为什么?这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
void err_sys(const char* x) { perror(x); exit(1); }
void upper(char *s) { while((*s = toupper(*s))) ++s; }
void filter(int input, int output)
{
char buff[1024];
bzero(buff, sizeof(buff));
size_t n = read(input, buff, sizeof(buff));
printf("process %ld: got '%s'\n", (long) getpid(), buff);
upper(buff);
write(output, buff, strlen(buff));
}
void filter2(int input, int output)
{
if (dup2(input, 0) != 0) err_sys("dup2(input, 0)");
if (dup2(output, 1) != 1) err_sys("dup2(output, 1)");
execlp("/usr/bin/tr", "tr", "[a-z]", "[A-Z]" , (char*)0);
}
int main(int argc, char** argv)
{
int pipe1[2];
int pipe2[2];
if (pipe(pipe1) < 0) err_sys("pipe1");
if (pipe(pipe2) < 0) err_sys("pipe2");
pid_t pid;
if ((pid = fork()) < 0) err_sys("fork");
else if (pid > 0)
{
close(pipe1[0]);
close(pipe2[1]);
char* s = "Hello there, can you please uppercase this and send it back to me? Thank you!";
write(pipe1[1], s, strlen(s));
char buff[1024];
bzero(buff, sizeof(buff));
size_t n = read(pipe2[0], buff, sizeof(buff));
pid_t mypid = getpid();
printf("process %ld: got '%s'\n", (long) mypid, buff);
} else
{ // Child.
close(pipe1[1]);
close(pipe2[0]);
filter(pipe1[0], pipe2[1]);
//filter2(pipe1[0], pipe2[1]); // FIXME: This doesn't work
}
return 0;
}