C - 将输入从一个程序传送到另一个程序

标签 c pipe fork

我应该创建两个程序(main 和 aux),其中 main fork 一个子程序来执行 aux。父进程从用户处获取输入,直到空行“\n”,并且子进程执行 aux,这应该将输入打印回来。我可以使用注释代码而不是 execlp() 让它在 main 中工作,但无法让 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;
}

“aux.c”

#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

最佳答案

您调用write(2)是错误的(你总是 100字节,即使是较短的-s):

                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) 是 100,因为您声明了 char data[100];

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

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

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

顺便说一句,编译时包含所有警告和调试信息:gcc -Wall -Wextra -g 并学习 use the gdb debuggerstrace(1) (和valgrind)。一般来说,是scaredundefined behavior (然而,乍一看,你的程序似乎没有UB)。

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

关于C - 将输入从一个程序传送到另一个程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47150237/

相关文章:

linux - 在 fork 之前或之后在磁盘文件上调用 mmap() 有什么区别?

c - 分配结构体矩阵的内存结构

python - 使用 numpy 扩展的 C 程序的 Makefile

c - 用户选择的数学函数

像 Cat 一样在 Windows 中获取二进制数据作为字符串的命令行工具?

c - 涉及for循环的fork函数

android - 使用预先构建的静态库android

c - 为什么这个 Forking 示例不需要互斥锁?

r - flextable 包在没有 <- 的情况下分配更改

c - Unix 系统调用按升序然后降序打印数字