2016-02-12 15 views
0

我有两个进程,一个父母和一个孩子。父母执行子进程并使用stdin/out来传达和控制子进程。如何登录并将所有stdio代理到子流程?

我想通过记录它们之间发生的所有io(stdin,out,err)来检查这两个进程之间使用的协议。

我必须指定命令父进程高管启动子过程的能力,所以我的问题是:

是否有一个命令行工具,和/或简单的C/Java的/ Python程序,可以“包装”子命令和日志(文件)的所有标准输入+标准输出,同时也转发所有IO二者之间

图形,我有什么考虑(这样子进程继续工作?):

当前:Parent <-io-> Child

点子:Parent <-io-> Wrapper/Proxy <-io-> Child

在此先感谢!

回答

0

这不是很漂亮,但它的工作。它不关机非常好,但它让我用我自己的可执行包裹子进程的命令检查父和子进程之间的通信:

概述:

  • ,预计子命令(和它的参数)作为包装参数
  • 它设置了3个管道来重新路由+拦截std {in,out,err}
  • 它在内部多次分支以使进程消耗并记录每个stdio流
  • 写出到文件stdin.logstdout.logstderr.log
  • 最终叉预期的可执行文件,建立拦截标准输入输出管道

用法:./wrapper /bin/othercommand -a -b -c

#include <stdio.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <signal.h> 

int ioin[2]; 
int ioout[2]; 
int ioerr[2]; 

void handler(int sig) 
{ 
    printf("Closing everything!\n"); 

    close(ioin[0]); 
    close(ioin[1]); 
    close(ioout[0]); 
    close(ioout[1]); 
    close(ioerr[0]); 
    close(ioerr[1]); 
} 

int main(int argc, const char * argv[]) { 
    pipe(ioin); 
    pipe(ioout); 
    pipe(ioerr); 

    // execvp(argv[1], argv+1); 

    signal(SIGHUP, &handler); 

    if(fork() == 0) 
    { 
     close(ioin[0]); // close in read 
     close(ioout[1]); // close in write 
     close(ioerr[1]); // close in write 

     if(fork() == 0) 
     { 
      if(fork() == 0) 
      { 
       char buf; 
       FILE* f = fopen("stdin.log", "w+"); 
       // fprintf(f, "%d\n", getpid()); 
       // fflush(f); 
       while (read(STDIN_FILENO, &buf, 1) > 0) { 
        write(ioin[1], &buf, 1); 
        fwrite(&buf, 1, 1, f); 
        fflush(f); 
       } 
       fprintf(f, "Done\n"); 

       fclose(f); 
       close(ioin[1]); 
       close(0); 

       kill(0, SIGHUP); 

       _exit(0); 
      } 
      else 
      { 
       char buf; 
       FILE* f = fopen("stdout.log", "w+"); 
       // fprintf(f, "%d\n", getpid()); 
       // fflush(f); 
       while (read(ioout[0], &buf, 1) > 0) { 
        write(STDOUT_FILENO, &buf, 1); 
        fwrite(&buf, 1, 1, f); 
        fflush(f); 
       } 
       fprintf(f, "Done\n"); 

       fclose(f); 
       close(ioout[0]); 
       _exit(0); 
      } 
     } 
     else 
     { 
      char buf; 
      FILE* f = fopen("stderr.log", "w+"); 
      // fprintf(f, "%d\n", getpid()); 
      // fflush(f); 
      while (read(ioerr[0], &buf, 1) > 0) { 
       write(STDERR_FILENO, &buf, 1); 
       fwrite(&buf, 1, 1, f); 
       fflush(f); 
      } 
      fprintf(f, "Done\n"); 


      fclose(f); 
      close(ioerr[0]); 
      _exit(0); 
     } 
    } 
    else 
    { 
     close(ioin[1]); // close in write 
     close(ioout[0]); // close in read 
     close(ioerr[0]); // close in read 

     if(fork() == 0) 
     { 
      close(0); 
      dup(ioin[0]); 

      close(1); 
      dup(ioout[1]); 

      close(2); 
      dup(ioerr[1]); 

      execvp(argv[1], argv+1); 
     } 
     else 
     { 
      wait(NULL); 
     } 
    } 
} 

我很高兴接受另一个答案是清洁剂和/或更正确。