【发布时间】:2015-08-09 05:26:22
【问题描述】:
我正在尝试使用 c 语言实现管道。 我正在通过创建子进程为由管道分隔的每个命令执行一个循环
以下是我的代码:
int main(int argc, char **argv)
{
char *cmd,*splitcmd;
int i,j,nargc=0,characters;
char **cmdArray;
size_t bufsize = 1024;
int *pipefd;
int pipeArrCount;
pid_t pid,wpid;
int status = 0;
int savestdoutfd = dup(fileno(stdout));
int savestdinfd = dup(fileno(stdin));
cmd = (char *)malloc(bufsize * sizeof(char));
characters = getline(&cmd,&bufsize,stdin);
// printf("%s%d",cmd,characters);
if(cmd[characters-1]=='\n')
{
// printf("in c");
cmd[characters-1]='\0';
characters--;
}
cmdArray = (char**)malloc(sizeof(char *) * 100);
splitcmd=strtok(cmd,"|");
// printf("%s\n",cmd);
while((splitcmd))
{
cmdArray[nargc] = splitcmd;
if(cmdArray[nargc][(strlen(cmdArray[nargc]))-1]==' ')
cmdArray[nargc][(strlen(cmdArray[nargc]))-1]='\0';
printf("%d %s",nargc,cmdArray[nargc]);
nargc++;
splitcmd = strtok(NULL,"|");
}
pipefd=(int*)malloc(2*nargc*sizeof(int));
printf("%d\n",nargc);
pipeArrCount=2*(nargc-1);
printf("%d\n",pipeArrCount);
//exit(0);
for(i=0;i<pipeArrCount;i)
{
printf("making pipe for process %d\n",i);
pipe(pipefd+i);
i=i+2;
}
//exit(0);
for(i=0;i<nargc;i)
{
printf("parent count %d\n",i);
if(i==0)
{
printf("Creating child %d\n",i);
// As it is first process we need to make write end of the pipe as stdout.
if ((pid=fork()) == 0)
{
printf("Creating first child %d for command %s\n",i,cmdArray[i]);
printf("EXECUTING FIRST PROCESS\n");
printf("Writing in pipe[%d]\n",2*i+1);
//close(pipefd[0]);
dup2(pipefd[2*i+1],fileno(stdout));
//closing all other pipes
for(j=0;j<(2*nargc);j++)
{
//if(j!=2*i+1)
close(pipefd[j]);
}
system(cmdArray[i]);
//dup2(savestdoutfd,fileno(stdout));
printf("Stdout is again restored\n");
//printf("pipe [%d] contains %d ",2*i+1,pipefd[2*i+1]);
exit(0);
}
}
else if(i!=nargc-1)
{
if (fork() == 0)
{
printf("EXECUTING MIDDLE PROCESS\n");
printf("Command to execute %s \n",cmdArray[i]);
printf("Reading from pipe[%d]\n",(2*(i-1)));
printf("writing on pipe[%d]\n",(2*i)+1);
dup2(pipefd[(2*(i-1))], 0); //Read end of the previous process pipe as stdin
dup2(pipefd[(2*i)+1], 1); //Write end of the pipe of current process as stdout
//closing all other pipes
for(j=0;j<(2*nargc);j++)
{
//if((j!=(2*(i-1))) && (j!=(2*i)+1))
close(pipefd[j]);
}
system(cmdArray[i]);
exit(0);
}
}
else
{
if (fork() == 0)
{
printf("Creating last child %d for command %s\n",i,cmdArray[i]);
printf("Reading from pipe[%d]\n",(2*(i-1)));
//close(pipefd[1]);
dup2(pipefd[(2*(i-1))],fileno(stdin)); //Read from the end of the previous process pipe as stdin
//printf("EXECUTING LAST PROCESS\n");
//closing all other pipes
for(i=0;j<(2*nargc);j++)
{
//if(j!=(2*(i-1)))
close(pipefd[j]);
}
dup2(savestdoutfd,fileno(stdout));
close(savestdoutfd);
system(cmdArray[i]);
dup2(savestdinfd,fileno(stdin));
close(savestdinfd);
exit(0);
}
}
i=i+1;
sleep(1);
}
while ((wpid = wait(&status)) > 0);
}
没有得到第二个命令的任何输出 现在我正在尝试执行这个'A | B ' 命令类型 如果你执行代码,命令和管道之间的空间是必要的
【问题讨论】:
-
你能说得更具体些吗?期望什么?出了什么问题?
-
我正在尝试使用 c 实现 unix 管道 ('|')。
-
我正在尝试使用 c 实现 unix pipe ('|')。为此,我使用 pipe() 函数进行不同命令之间的通信。所以首先我尝试扫描命令并查看我需要多少个管道然后我多次调用管道函数。现在例如我有命令'cat out.c | sort' 这个程序所做的是得到一个管道,父进程为两个命令分叉两个进程,第一个命令是使用系统调用执行的,但是这个命令的输出应该在管道的写端,即 p[1] 然后关闭所有管道。一旦完成它.......
-
........ 使用系统调用执行第二个命令并从管道的读取端读取,即 p[0]。
-
请适当地提出问题