⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pipel.c

📁 Linux下实现shell的部分功能
💻 C
字号:
#include "ysh.h"
#include "extern.h"

int pipel(char *input,int len)
{
	char *argv[10][30],*filename[0];
	int i,j,k,is_bg=0;
	int li_cmd=0,fd[10][1],pipe_in=-1,pipe_out=-1,flag=0;
	pid_t pid;

/********************命令解析********************/
	/*此部分功能和结构与重定向时的命令解析相似*/
	for (i=0,j=0,k=0;i<=len;i++) {
		if (input[i]==' '||input[i]=='\t'||input[i]=='\0'||input[i]=='|'||input[i]=='>'||input[i]=='\n') {
			if (input[i]=='|'||input[i]=='>') {
				if (input[i]=='>') flag=1;
				if (j>0) {
					buf[j++]='\0';
					argv[li_cmd][k]=(char *) malloc(sizeof(char)*j);
					strcpy(argv[li_cmd][k],buf);
					k++;
				}
				argv[li_cmd][k]=(char *) 0;
				li_cmd++;
				k=0;
				j=0;
			}
			if (j==0)
				continue;
			else{
				buf[j++]='\0';
				if (flag==0) { /*flag==0命令中不含“>”、“<”重定向命令*/
					argv[li_cmd][k]=(char *) malloc(sizeof(char)*j);
					strcpy(argv[li_cmd][k],buf);
					k++;
				}else { /*flag==1命令中包含“>”、“<”重定向命令,重定向命令后为文件名*/
					filename[0]=(char *) malloc (sizeof(char)*j);
					strcpy(filename[0],buf);
				}
			}
			j=0;
		}else{
			if (input[i]=='&'&&input[i++]=='\0'){ /*带后台符号的命令*/
				is_bg=1;
				continue;
			}
			buf[j++]=input[i];
		}
	}

	argv[li_cmd][k++]=(char *) 0; /*最后一参数置空*/

	for (i=0;i<=10;i++) { /*初始化文件描述符*/
		fd[i][FD_READ]=NO_PIPE;
		fd[i][FD_WRITE]=NO_PIPE;
	}

	for (i=0;i<li_cmd;i++) { /*为命令建立相应的管道*/
		if (pipe(fd[i])==-1) {
			printf("Can not open pipe!\n");
			return 0;
		}
	}

/********************寻找命令文件,执行命令*******/
	for (i=0;i<=li_cmd;i++) {
		if (is_founded(argv[i][0])==0) {
			printf("Can not found command!\n");
			break;
		}

		/*将pipe_in指向到管道的读端(第一条命令除外)*/
		if (i!=0)
			pipe_in=fd[i-1][FD_READ];
		else pipe_in=NO_PIPE;/*第一条命令除外*/

		/*将pipe_out指向到管道的写端(最后一条命令除外)*/
		if (i!=li_cmd)
			pipe_out=fd[i][FD_WRITE];
		else 
			if (flag==1) { /*包含重定向命令*/
				/*将pipe_out指向到文件*/
				if ((pipe_out=open(filename[0],O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR))==-1){
				printf ("Can not open %s \n",filename[0]);
				break;
				}
			}else pipe_out=NO_PIPE; /*最后一条命令除外*/

		if ((pid=fork())<0){
			printf("Fork failed!\n");
			return 0;
		}

		if (pid==0) {
			if (pipe_in==NO_PIPE)
				close(pipe_in);
			if (pipe_out==NO_PIPE)
				close(pipe_out);

			if (pipe_out!=NO_PIPE) {
				/*将标准输出重定向到管道的写端,这样该子进程的输出就写入管道了*/
				dup2(pipe_out,1);
				close(pipe_out);
			}

			if (pipe_in!=NO_PIPE) {
				/*将标准输入重定向到管道的读端,这样管道的数据就可以被读到了*/
				dup2(pipe_in,0);
				close(pipe_in);
			}
			execv(buf,argv[i]);
		}else {
			if (is_bg==0)
				waitpid(pid,NULL,0);
				close(pipe_in);
				close(pipe_out);
		}
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -