【问题标题】:C Pipe to STDIN of Another ProgramC管道到另一个程序的标准输入
【发布时间】:2013-11-25 08:25:56
【问题描述】:

我几乎无法理解管道的手册页,所以我需要帮助了解如何在外部可执行文件中获取管道输入。

我有 2 个程序:ma​​in.o & log.o

我写了 ma​​in.o 来分叉。这是它正在做的事情:

  • 父分叉管道数据给子
  • 子分叉执行 log.o

我需要子叉子用于主管道到 log.o

的 STDIN

log.o 只需将带有时间戳的 STDIN 和日志记录到文件中。

我的代码由我不记得的各种 StackOverflow 页面中的一些代码和管道的手册页组成:

printf("\n> ");
while(fgets(input, MAXINPUTLINE, stdin)){
   char buf;
   int fd[2], num, status;
   if(pipe(fd)){
      perror("Pipe broke, dood");
      return 111;
   }
   switch(fork()){
   case -1:
      perror("Fork is sad fais");
      return 111;

   case 0: // Child
      close(fd[1]); // Close unused write end
      while (read(fd[0], &buf, 1) > 0) write(STDOUT_FILENO, &buf, 1);

      write(STDOUT_FILENO, "\n", 1);
      close(fd[0]);
      execlp("./log", "log", "log.txt", 0); // This is where I am confused
      _exit(EXIT_FAILURE);

   default: // Parent
      data=stuff_happens_here();
      close(fd[0]); // Close unused read end
      write(fd[1], data, strlen(data));
      close(fd[1]); // Reader will see EOF
      wait(NULL); // Wait for child
   }
   printf("\n> ");
}

【问题讨论】:

    标签: c pipe


    【解决方案1】:

    我想这就是你要做的:
    1. 主分叉,父级通过管道向子级传递消息。
    2. 子进程从管道接收消息,将消息重定向到标准输入,执行日志。
    3. 记录从 STDIN 接收到的消息,做一些事情。

    执行此操作的关键是dup2 将文件描述符从管道重定向到 STDIN。

    这是修改后的简单版本:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    
    int main(int argc, char *argv[]) {
        int fd[2];
        char buf[] = "HELLO WORLD!";
        if(pipe(fd)){
          perror("pipe");
          return -1;
        }
        switch(fork()){
            case -1:
                perror("fork");
                return -1;
            case 0:
                // child
                close(fd[1]);
                dup2(fd[0], STDIN_FILENO);
                close(fd[0]);
                execl("./log", NULL);
            default:
                // parent
                close(fd[0]);
                write(fd[1], buf, sizeof(buf));
                close(fd[1]);
                wait(NULL);
        }
        printf("END~\n");
        return 0;
    }  
    

    【讨论】:

      【解决方案2】:

      我可以建议一种更简单的方法。有一个函数叫做popen()。它的工作原理与system() 函数非常相似,只是您可以读取或写入子stdin/stdout

      示例:

      int main(int argc, char* argv[])
      {
          FILE* fChild = popen("logApp.exe", "wb"); // the logger app is another application
          if (NULL == fChild) return -1;
      
          fprintf(fChild, "Hello world!\n");
      
          pclose(fChild);
      }
      

      在您的控制台中写入“ma​​n popen”以获得完整说明。

      【讨论】:

        【解决方案3】:
        猜你喜欢
        • 2017-07-24
        • 1970-01-01
        • 2013-06-25
        • 1970-01-01
        • 2018-05-04
        • 2012-02-23
        • 2017-02-03
        • 2013-10-20
        • 1970-01-01
        相关资源
        最近更新 更多