コマンドライン引数で渡されたコマンドのstdin、stdout、およびstderrをキャプチャするC(Unix)でプログラムを作成する必要があります。
例えば、
./capture echo Hi
== stdout ===
Hi
== end of stdout ==
./capture bc -q
== stdin ==
1+2
== end of stdin ==
== stdout ==
3
== end of stdout ==
私はすでに stdout と stderr にそのような動作を実装しています:
int pipe_out[2];
int pipe_in[2];
int finished = 0;
void sig_handler(int signo)
{
if (signo == SIGCHLD)
{
finished = 1;
wait(NULL);
}
}
void ChildProcess (char * argv[], char * env[])
{
dup2(pipe_out[1], 1);
dup2(pipe_out[1], 2);
dup2(pipe_in[0], 0);
close(pipe_out[0]);
close(pipe_out[1]);
close(pipe_in[0]);
close(pipe_in[1]);
int return_code = execvpe(argv[0], argv, env);
printf("This should not appear: %d\n", return_code);
printf("Error: %s\n\n", strerror(errno));
}
void ParentProcess(pid_t pid)
{
int status;
char buf[10000];
fd_set out_fds;
fd_set in_fds;
signal(SIGCHLD, sig_handler);
do
{
FD_ZERO(&out_fds);
FD_ZERO(&in_fds);
FD_SET(pipe_in[1], &in_fds);
FD_SET(pipe_out[0], &out_fds);
int cnt = select(max(pipe_out[0], pipe_out[0]) + 1, &out_fds, NULL, NULL, NULL);
if (cnt > 0 && FD_ISSET(pipe_out[0], &out_fds))
{
puts("== stdout ==");
read(pipe_out[0], buf, sizeof(buf));
printf("%s", buf);
puts("== end of stdout == ");
continue;
}
if (0 && FD_ISSET(pipe_in[1], &in_fds))
{
puts("== stdin ==");
write(pipe_in[1], "1+2\n", sizeof("1+2\n"));
puts("== end of stdin ==");
continue;
}
} while (!finished);
}
親プロセスが select() を呼び出し、子プロセスの出力を待ちます。その後、親プロセスは追加情報 (== stdout ==) と子プロセスの出力を出力します。
標準入力に同じ動作を実装しようとするとin_fds
、子プロセスが必要とするものとは常に独立して準備ができていることがわかります。そのcapture
ため、常に標準入力から読み取ります。子プロセスが何かを出力する必要がある場合でも。
だから私の質問は、そのような動作を実装する方法ですか?
子プロセスが入力を必要とする時期を示す特別なシグナルが必要だと思いますが、何も見つかりません。