####やりたいこと
UNIXで子プロセスを起動して任意のコマンドをexecで実行したい。
そのコマンドの標準入力に対してパイプでデータを渡したい。
####プログラム例
子プロセスを起動してcatを引数なしで呼ぶ。catは引数なしなので標準入力を待つ。
親プロセスからは"Hello, World."をパイプで流す。
つまり、shellで
$ echo "Hello, World" | cat
を実行したのと同じ。
コード
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(void)
{
int fd[2];
// pipe を作成する。fd[0]は受信用、fd[1]は送信用
pipe(fd);
// プロセス生成
switch(fork()) {
case -1:
perror("fork");
return 1;
case 0: // 子プロセス
{
close(fd[1]); // 送信用fdを閉じる
// 受信用fdをstdinのfdに上書きする
if (dup2(fd[0], STDIN_FILENO)==-1) {
perror("cannot redirect stdin");
exit(1);
}
close(fd[0]); // 受信用fdは複数いらないので閉じる
// cat を実行する
execlp("cat", "cat", NULL) ;
perror("execlp: failed."); // ここに来たということはexeclpに失敗した
}
default:
{ // 親プロセス
const char send_str[] = "Hello, World.\n";
close(fd[0]); // 受信側fdを閉じる
write(fd[1], send_str, strlen(send_str)+1);
close(fd[1]); // 送信後は必ず閉じる ★①
int status;
wait(&status);
}
}
return (0);
}
####はまったこと
"Hello, World"は出力されるが、子プロセスが終了しない。
####原因
親プロセスがwrite()後にfd[1]に対してcloseをしていなかった。(上記ソースの★①)
子プロセス側は標準入力をずっと待っている状態だった。
###参考になったもの
http://stackoverflow.com/questions/22245237/execlp-redirect-stdin-in-c
以上。