2015-05-24 30 views
1

我的目标是通过FIFO在孩子和父母之间建立IPC。孩子应该运行如何使用execl()函数通过cut命令来运行stdin?

execl ("/bin/cat", "cat", "/etc/passwd", (char *)0); 

其输出重定向到家长输入和家长应该用这个命令:

cut -l : -f 1 

和输出这命令行。

现在,我已经成功地链接了我的FIFO,并将我的子进程的输出重定向到了父进程的输入。我已经完成了多个测试,并且连接正常。问题是与execl剪切,应该看起来像这样:

execlp("/bin/cut", "cut", "-l:", "-f", "1", NULL); 

但我很确定它不是。

int cut(){ 

    // 
    int myfifo;  
    char buf[MAX_BUF]; 


    printf("\nCut opening FIFO"); 
    if((myfifo = open("/tmp/myfifo", O_RDONLY | O_TRUNC))<0){ 
     perror("open FIFO at cut"); 
     quit(EXIT_FAILURE);} 
    else{printf("\nCut has FIFO opened and is reading\n");} 

    //read(myfifo, buf, MAX_BUF); outputting buf goes as supposed to 

    if(dup2(myfifo, 0) < 0){ 
     perror("dup2 at cut"); 
     quit(EXIT_FAILURE);} 

    //read(STDIN_FILENO, buf, MAX_BUF); 

    close(myfifo); 

    execlp("/bin/cut", "cut", "-l:", "-f", "1", NULL); 

    //this is for testing buf, but i guess the program shouldn't even get here 
    printf("\nCut has received: %s\nAnd is closing FIFO", buf); 

    return -1; 

} 


int cat(){ 

    int myfifo; 
    //OPEN FIFO 
    printf("\nCat opening FIFO"); 
    if((myfifo = open("/tmp/myfifo", O_WRONLY | O_TRUNC))<0){ 
     perror("open FIFO at cat"); 
     quit(EXIT_FAILURE); 
    } 
    else{ 
     printf("\nCat has opened FIFO"); 
    //WRITE OUTPUT OF "cat \etc\passwd" TO FIFO 
     dup2(myfifo, 1); 
     execl ("/bin/cat", "cat", "/etc/passwd", (char *)0); 
    } 
    close(myfifo); 


    return 0; 
} 

当前主要只创建fifo(mkfifo),forks()并调用该函数。 我的问题可能与父(streak)的标准输入(运行切割),但我不这么认为,或者我假设execl()直接从标准输入读取,而事实并非如此。 我认为这是真的,因为我没有正确地通过execl()写“剪切”。

对代码的任何更正,甚至我表达一些想法的方式都可能表明我没有正确理解某些内容,将不胜感激。 感谢您的帮助

+0

为什么使用FIFO或命名管道而不是普通的普通匿名管道? –

+0

哪个版本的'cut'支持'-l'选项? GNU'cut'和BSD(Mac OS X)'cut'都没有。您似乎将其用作等效于“-d”选项(字段分隔符),这对读取密码文件有意义。另外,在你机器上的'/ bin'中是否被剪切?它在我的'/ usr/bin'中,这两个目录是不同的。 –

回答

0

正如在评论中指出的,GNU和BSD(和POSIX)下的cut命令不支持-l选项;您需要的选项是分隔符-d

此代码适用于我。在我的机器,/bin/cat是正确的,但/usr/bin/cut是正确的(不/bin/cut),所以我不得不与编译:

$ rmk cutcat UFLAGS=-DCUT_CMD=/usr/bin/cut && ./cutcat 
    gcc -O3 -g -std=c11 -Wall -Wextra -Werror -DCUT_CMD=/usr/bin/cut cutcat.c -o cutcat 
$ 

使用的make定制的变种(称为rmk)和一个自定义makefile,但位置通过UFLAGS(用户标志)宏在命令行上指定了cut命令。 C代码中的STRINGEXPAND宏是令人讨厌的,但并不像试图通过调用make(或rmk)的shell获得双引号,然后调用make调用的shell来运行编译器。

代码:

#include <stdio.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <sys/stat.h> 

#ifndef CUT_CMD 
#define CUT_CMD /bin/cut 
#endif 
#ifndef CAT_CMD 
#define CAT_CMD /bin/cat 
#endif 
#define EXPAND(x) #x 
#define STRING(x) EXPAND(x) 

static const char cut_cmd[] = STRING(CUT_CMD); 
static const char cat_cmd[] = STRING(CAT_CMD); 

static inline void quit(int status) { exit(status); } 

enum { MAX_BUF = 4096 }; 

static void cut(void) 
{ 
    int myfifo; 

    printf("\nCut opening FIFO"); 
    if ((myfifo = open("/tmp/myfifo", O_RDONLY | O_TRUNC)) < 0) 
    { 
     perror("open FIFO at cut"); 
     quit(EXIT_FAILURE); 
    } 
    printf("\nCut has FIFO opened and is reading\n"); 

    if (dup2(myfifo, 0) < 0) 
    { 
     perror("dup2 at cut"); 
     quit(EXIT_FAILURE); 
    } 

    close(myfifo); 

    execlp(cut_cmd, "cut", "-d:", "-f", "1", NULL); 
    fprintf(stderr, "Failed to execute %s\n", cut_cmd); 
    exit(1); 
} 

static 
void cat(void) 
{ 
    int myfifo; 

    printf("\nCat opening FIFO"); 
    if ((myfifo = open("/tmp/myfifo", O_WRONLY | O_TRUNC)) < 0) 
    { 
     perror("open FIFO at cat"); 
     quit(EXIT_FAILURE); 
    } 
    printf("\nCat has opened FIFO"); 
    dup2(myfifo, 1); 
    close(myfifo); 
    execl(cat_cmd, "cat", "/etc/passwd", (char *)0); 
    fprintf(stderr, "Failed to execute %s\n", cat_cmd); 
    exit(1); 
} 

int main(void) 
{ 
    mkfifo("/tmp/myfifo", 0600); 
    if (fork() == 0) 
     cat(); 
    else 
     cut(); 
    /*NOTREACHED*/ 
    fprintf(stderr, "You should not see this message\n"); 
    return 0; 
} 

输出示例:

大部分截断

… 
nobody 
root 
daemon 
_uucp 
_taskgated 
_networkd 
… 

的代码是不是真的从你有什么很大的不同。我删除了一些混乱。我确保close(myfifo)cat()执行;它不是原来的。这可能很重要。

+0

是的,当我复制我的代码时,我正在使用-l标志来检查我从控制台获得的错误。我的错。/usr/bin/cut完美工作。 –