2016-02-12 54 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); 
     } 
    } 
} 

我很高興接受另一個答案是清潔劑和/或更正確。