Unix上用C程序实现pipe管道命令“ | “(pipe,fork,dup2,close,execl,重定向)

Posted 狱典司

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unix上用C程序实现pipe管道命令“ | “(pipe,fork,dup2,close,execl,重定向)相关的知识,希望对你有一定的参考价值。

#include<errno.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>

int main(void){

pid_t childpid;
int fd[2];

if((pipe(fd) == -1) || ((childpid = fork()) == -1)){
//{ int pipe(int filedes[2])}: fd[0]先进先出的读,fd[1]写; pipe函数若成功返回0,否则返回-1
// {pid_t fork()}:在父进程中函数会返回fork出的子进程的pid;在子进程中会返回0
	perror("Fail to setup pipeline");
	return 1;
}

if(childpid == 0){	//说明是子进程(ls)
	if(dup2(fd[1],STDOUT_FILENO) == -1){
		//{int dup2(int oldfd, int newfd)}:将进程的文件描述符定点复制;
		//调用成功返回newfd,否则返回-1
		perror("Fail to redirect stdout of ls");
		//对ls的管道输入fd重定向到标准输出失败
	}else if( (close(fd[0]) == -1) || (close(fd[1]) == -1) ){
		perror("Fail to close extra pipe descriptors on ls");
		//关闭ls的多余管道IO描述符失败
	}else{
		execl("/bin/ls","ls","-l",NULL); //更新子进程用户空间
		perror("Fail to exec ls");
	}
	return 1;//子进程退出,但需要注意此时父进程还未退出
}

//以下是对父进程sort的操作
if(dup2(fd[0],STDIN_FILENO) == -1)
	perror("Fail to redirect stdin of sort");
else if(close(fd[0]) == -1 || close(fd[1]) == -1 )
	perror("Fail to close extra pipe description on sort");
else {
	execl("/bin/sort","sort","-n",NULL); //更新父进程用户空间
	perror("Fail to exec sort");
}
return 1;
}

重定向后的示意图:

编译后执行,结果和使用命令行敲是一样的,需要关注的地方都写在注释中了。

以上是关于Unix上用C程序实现pipe管道命令“ | “(pipe,fork,dup2,close,execl,重定向)的主要内容,如果未能解决你的问题,请参考以下文章

Unix/Linux进程间通信:匿名管道有名管道 pipe()mkfifo()

Golang 管道

实验八进程间通信

gulp使用学习记录

popen() 可以制作像 pipe() + fork() 这样的双向管道吗?

Linux管道(Pipes)