先来看看下面的这张图:
当进行I/O重定向时,只是将不同进程表的不同fd指向同一文件表结构。
关于I/O重定向,要用到以下的重要函数:
int dup( int oldfd ); int dup2( int oldfd, int targetfd )
利用函数dup,我们可以复制一个描述符。传给该函数一个既有的描述符,它就会返回一个新的描述符,这个新的描述符是传给它的描述符的拷贝,即他们将共享同一个文件表。
而dup2,则会复制oldfd所指向的文件表结构到targetfd所指向的文件表结构,这样就使targetfd重定向到oldfd了,并且是指向oldfd所指的文件表结构的。
下面的程序就是利用管道及重定向来进行2个进程间的通信的。
在父进程中创建了2个子进程A、B,并在父进程中创建了管道A_to_B[2],
我们的任务是将进程A的输出做为进程B的输入 。
为此,首先在子进程A中将其标准输出重定向到管道的写端A_to_B[1],然后在子进程B中将管道的读端A_to_B[0]重定向到B的标准输入,如此即可。
下面是代码:
int A_to_B[2];//保存管道描述符if(pipe(A_to_B)<0)//创建管道
{
printf("创建管道失败!");
exit(0);
}
if(fork()==0){//这是子进程1
close(A_to_B[0]);//关闭读端
if(dup2(A_to_B[1],STDOUT_FILENO)!=STDOUT_FILENO){//子进程1的输出重定向到管道的输入
printf("重定向失败!");
exit(0);
}
close(A_to_B[1]);
execvp(cmd_A->exe_path,cmd_A->argv);
}
if(fork()==0){//这是子进程2
close(A_to_B[1]);//为进程2关闭写端
dup2(A_to_B[0],STDIN_FILENO);//管道的输出重定向到子进程2的输入
close(A_to_B[0]);
execvp(cmd_B->exe_path,cmd_B->argv);
}
else{//父进程
wait(NULL);
}