2014-11-06 70 views
0

我正在写一个简单的代码来实现unix/linux外壳的管道功能。简单的外壳与管道()函数

#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

请张贴的确切消息。错误是什么告诉你什么是错的... – clcto 2014-11-06 20:17:29

+0

谢谢你的回复。现在修复它。 – 2014-11-06 20:21:21

+0

您是否阅读过您要拨打的功能的文档[execvp(3)](http://man7.org/linux/man-pages/man3/execvp.3.html)?您应该按照记录调用它... – 2014-11-06 20:23:20

回答

1

此代码有效,但不会执行所有可能的错误检查。类似于在将标准输入从(或标准输出)重定向到文件后关闭文件描述符的方式,当您使用管道时,如果将管道的一端连接到标准输入或输出,则需要然后在执行命令之前关闭管道的两端。当管道在父子流程中创建时,您需要确保父管道的两端都已关闭。

#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 
+0

非常感谢您的回答。 – 2014-11-07 15:25:39

3
execvp(command2[],command2); 

空的[]是语法错误。也许你的意思是:

execvp(command2[0], command2);