C - 从一个程序到另一个程序的管道输入

时间:2017-11-07 04:55:06

标签: c pipe fork

我应该创建两个程序(main和aux),其中main要求孩子执行aux。父母从用户那里获取输入,直到空行' \ n'并且孩子执行aux,其应该打印输出。我能够使用注释代码而不是execlp()来使用它,但是无法使execlp(aux)正常工作。任何帮助表示赞赏。

" main.c中"

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    int fd[2], i;
    char line[100], buffer[100];

    pipe(fd);

    pid_t pid = fork();

    if (pid < 0) {
            printf("Fork Failed\n");
            exit(-1);
    }
    else if (pid > 0) {
            close(fd[0]);
            while(fgets(line, sizeof(line), stdin) && line[0] != '\n') {
                    write(fd[1], line, sizeof(line));
            }
            close(fd[1]);
    }
    else {
            close(fd[1]);
            dup2(fd[0], STDIN_FILENO);

            //while(read(fd[0], buffer, sizeof(buffer)))
            //      printf("> %s", buffer);

            execlp("./aux", "aux", (char *)0);
    }
    return 0;
}

&#34; aux.c&#34;

#include <stdio.h>
#include <stdlib.h>

int main() {
    char data[100];

    while(fgets(data, sizeof(data), stdin))
            printf(">%s\n", data);

    return 0;
}

示例输入/输出

this
>this

is a test
>
> test

only prints larger text with random \n
>
>ts larger text with random \n

1 个答案:

答案 0 :(得分:0)

您对write(2)的来电是错误的(即使是较短的write - s,您总是line 100字节:

                write(fd[1], line, sizeof(line)); // WRONG

应该使用strlen(3)

            size_t ll = strlen(line);
            ssize_t wc = write(fd[1], line, ll);
            if (wc != ll)
              fprintf(stderr, "write was wrong (only %d, wanted %d) - %s\n",
                      (int) wc, (int) ll, strerror(errno));

因为你只想写line缓冲区的填充字节,每次都不总是100字节(其中一些没有被初始化)。

在您确定sizeof(data)

的情况下char data[100];为100

请仔细阅读每个使用过的函数的文档(以及ALP或其他关于Unix / POSIX / Linux编程的书籍)。 strerror(3)errno(3)的文档告诉您需要添加:

  #include <string.h>
  #include <errno.h>

实际上,如果你想直接使用read(2)write(2)(没有stdio(3)),你应该更喜欢使用更大的缓冲区(例如每个至少为4K字节效率),你需要管理部分read - s和write - s并自己做缓冲。

BTW,使用所有警告和调试信息进行编译:{{1​​}}并学习use the gdb debuggerstrace(1)(以及valgrind)。一般情况下,scaredundefined behavior(但是,乍一看,您的计划似乎没有UB)。

请注意execlp(3)可能会失败。考虑在其之后添加一些对perror(3)的调用。

相关问题