我有两个过程,父母和孩子。父进程执行子进程并使用stdin / out来通信和控制子进程。
我想通过记录它们之间发生的所有io(stdin,out,err)来检查这两个进程之间使用的协议。
我能够指定父进程执行以启动子进程的命令,所以我的问题是:
是否有命令行工具和/或简单的C / Java / python程序可以“包装”子命令并记录(到文件)所有stdin + stdout,同时还在它们之间转发所有io(所以子过程继续工作?)
从图形上看,我的想法是:
目前:Parent <-io-> Child
想法:Parent <-io-> Wrapper/Proxy <-io-> Child
提前致谢!
答案 0 :(得分:0)
它不漂亮,但它奏效了。它没有很好地关闭,但它允许我通过使用我自己的可执行文件包装子进程命令来检查父进程和子进程之间的通信:
概述:
stdin.log
,stdout.log
,stderr.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);
}
}
}
我很高兴接受另一个更清洁和/或更正确的答案。