这不是很漂亮,但它的工作。它不关机非常好,但它让我用我自己的可执行包裹子进程的命令检查父和子进程之间的通信:
概述:
- ,预计子命令(和它的参数)作为包装参数
- 它设置了3个管道来重新路由+拦截std {in,out,err}
- 它在内部多次分支以使进程消耗并记录每个stdio流
- 写出到文件
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);
}
}
}
我很高兴接受另一个答案是清洁剂和/或更正确。