我正在编写一个简单的代码来实现unix / linux shell的管道功能。
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
void
cisshPipe(char* command1[], char* command2[])
{
int fd[2];//create array for two file descritors
pid_t childPid;//To set for child process
pipe(fd);//To create pipeline here
if((childPid=fork())==-1)
{
perror("fork here");
exit(1);
}
//The below is the real meat for this subroutine
if(childPid==0)//If child process
{
close(fd[0]);//To close the input of child
dup(fd[0]);//To duplicate the input, for the later process
}
else//For the real output
{
close(fd[1]);//To close the parent output first
execvp(command2[],command2);
}
}
但是,我在“execvp(command2 [],command2)”上获得了一些关于预期表达式的编译错误。我认为这是由于我用来将子输出传递给父输入的dup()函数。有什么建议可以解决吗?
一些更新:
感谢约翰的回答。我解决了编译问题。但是当我输入“ls | sort”时它正在执行管道功能,我认为这仍然是dup()问题的传递。
答案 0 :(得分:3)
execvp(command2[],command2);
空[]
是语法错误。也许你的意思是:
execvp(command2[0], command2);
答案 1 :(得分:1)
此代码有效,但不会执行所有可能的错误检查。类似于在将标准输入从(或标准输出)重定向到文件后关闭文件描述符的方式,当您使用管道时,如果dup()
或dup2()
管道的一端对于标准输入或输出,您需要在执行命令之前关闭管道的两端。在子进程中创建管道时,您需要确保管道的两端也在父进程中关闭。
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
static inline void error(const char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}
static void
cisshPipe(char **command1, char **command2)
{
int fd[2];
pid_t childPid;
if (pipe(fd) != 0)
error("failed to create pipe");
if ((childPid = fork()) == -1)
error("failed to fork");
if (childPid == 0)
{
dup2(fd[1], 1);
close(fd[0]);
close(fd[1]);
execvp(command1[0], command1);
error("failed to exec command 1");
}
else
{
dup2(fd[0], 0);
close(fd[0]);
close(fd[1]);
execvp(command2[0], command2);
error("failed to exec command 2");
}
}
int main(void)
{
char *ls[] = { "ls", 0 };
char *sort[] = { "sort", "-r", 0 };
cisshPipe(ls, sort);
return 0;
}
示例输出:
xx.dSYM
xx.c
xx
xma.dSYM
xma.c
xma
ws-c11.c
…
am-pm.pl
2dv.dSYM
2dv.c
2dv
2da.dSYM
2da.c
2da