私は、信号処理が適切であるとは思いません。適切なのは、パイプが適切に閉じられていることを確認することです。書き込み終了のプロセスがある場合、プロセスはパイプの読み取り側でEOFを取得しません。それには現在のプロセスが含まれます。プロセスがパイプの読み取りと書き込みの両方の端を開いている場合、理論的には書き込み可能なプロセスが存在するため、パイプの読み取り側でEOFを取得することはありません。したがって、そのようなプロセスはパイプ上のread()
に永続的に掛かります。
あなたのコードのこのバージョンは、私のために正常に動作します:
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
int pdesk[2];
int pipedesk[2];
int pid;
if (pipe(pipedesk) == -1 || pipe(pdesk) == -1)
{
perror("Pipe");
exit(1);
}
//fprintf(stderr, "PID %d: controller\n", (int)getpid());
switch (pid = fork())
{
case -1:
perror("Creating process");
exit(1);
case 0:
//fprintf(stderr, "PID %d: will be 'ls'\n", (int)getpid());
dup2(pdesk[1], STDOUT_FILENO);
close(pdesk[0]); // JL
close(pdesk[1]);
close(pipedesk[0]); // JL
close(pipedesk[1]); // JL
execlp("ls", "ls", "-al", (char *)NULL);
perror("ls");
exit(1);
default:
//fprintf(stderr, "PID %d: ls process PID = %d\n", (int)getpid(), pid);
if ((pid = fork()) == 0)
{
//fprintf(stderr, "PID %d: about to fork 'tr'\n", (int)getpid());
if ((pid = fork()) == 0)
{
//fprintf(stderr, "PID %d: will be 'tr'\n", (int)getpid());
dup2(pdesk[0], STDIN_FILENO);
close(pdesk[0]);
close(pdesk[1]); // JL
dup2(pipedesk[1], STDOUT_FILENO);
close(pipedesk[0]); // JL
close(pipedesk[1]);
execlp("tr", "tr", "a-z", "A-Z", (char *)NULL);
perror("tr");
exit(1);
}
//fprintf(stderr, "PID %d: about to exec 'grep'\n", (int)getpid());
dup2(pipedesk[0], STDIN_FILENO);
close(pdesk[0]); // JL
close(pdesk[1]); // JL
close(pipedesk[0]);
close(pipedesk[1]); // JL
int desk = open("testing", O_WRONLY | O_CREAT, 0644);
if (desk == -1)
{
perror("opening file");
exit(1);
}
dup2(desk, STDOUT_FILENO);
if (close(desk) == -1)
{
perror("closing file");
exit(1);
}
execlp("grep", "grep", "X", (char *)NULL);
perror("grep");
exit(1);
}
//fprintf(stderr, "PID %d: closing pipes\n", (int)getpid());
close(pdesk[0]); // JL
close(pdesk[1]); // JL
close(pipedesk[0]); // JL
close(pipedesk[1]); // JL
break;
}
int status;
int corpse;
while ((corpse = wait(&status)) != -1)
fprintf(stderr, "PID %d: child %d died 0x%.4X\n", (int)getpid(), corpse, status);
return 0;
}
注すべての線が近い操作です// JL
をマーク。おそらくあなたが離れていくことができるのは間違いありませんが(最初の子供のものはおそらく「オプション」です)、使用していないすべてのパイプを日常的に閉じておくべきです。特に、元の親プロセスのクローズ(最後の4つ)は重要です。複数のパイプで作業するときに十分なパイプ記述子を閉じていない
は、最も一般的なミスの一つです。標準の入力または出力をパイプディスクリプタを複製するdup2()
(又はdup()
)を使用する場合、一般的に、元のパイプの両方端を閉じなければなりません。また、プロセスがパイプ記述子をまったく使用していない場合は、それらを閉じる必要があります。プログラムから
出力例:
$ ./pp61
PID 35665: child 35666 died 0x0000
PID 35665: child 35667 died 0x0000
$
testing
ファイルのサンプル内容:ここ
DRWXR-XR-X 44 JLEFFLER STAFF 1496 NOV 23 17:28 .
DRWXR-XR-X 137 JLEFFLER STAFF 4658 NOV 23 17:28 ..
DRWXR-XR-X 18 JLEFFLER STAFF 612 OCT 23 20:00 .GIT
DR-XR-XR-X 4 JLEFFLER STAFF 136 AUG 14 23:27 SAFE
DRWXR-XR-X 35 JLEFFLER STAFF 1190 NOV 23 09:19 UNTRACKED
-RW-R--R-- 1 JLEFFLER STAFF 81 NOV 20 20:53 ANIMALS.TXT
DRWXR-XR-X 3 JLEFFLER STAFF 102 SEP 12 00:03 DOC
DRWXR-XR-X 8 JLEFFLER STAFF 272 NOV 10 20:58 ETC
DRWXR-XR-X 17 JLEFFLER STAFF 578 JUL 15 19:06 INC
-RW-R--R-- 1 JLEFFLER STAFF 1217 NOV 21 21:26 IX37.SQL
DRWXR-XR-X 5 JLEFFLER STAFF 170 JUL 9 23:47 LIB
-RWXR-XR-X 1 JLEFFLER STAFF 9052 NOV 19 13:01 LL73
DRWXR-XR-X 3 JLEFFLER STAFF 102 NOV 6 15:40 LL73.DSYM
-RWXR-XR-X 1 JLEFFLER STAFF 8896 NOV 6 10:38 LL83
DRWXR-XR-X 3 JLEFFLER STAFF 102 NOV 6 10:10 LL83.DSYM
-RW-R--R-- 1 JLEFFLER STAFF 108 NOV 20 20:53 NEWANIMAL.TXT
-RWXR-XR-X 1 JLEFFLER STAFF 9124 NOV 20 20:38 PD43
DRWXR-XR-X 3 JLEFFLER STAFF 102 NOV 20 20:38 PD43.DSYM
-RWXR-XR-X 1 JLEFFLER STAFF 9148 NOV 23 17:28 PP61
DRWXR-XR-X 3 JLEFFLER STAFF 102 NOV 23 14:11 PP61.DSYM
-RWXR-XR-X 1 JLEFFLER STAFF 9016 NOV 23 11:07 RS19
DRWXR-XR-X 3 JLEFFLER STAFF 102 NOV 23 10:03 RS19.DSYM
DRWXR-XR-X 146 JLEFFLER STAFF 4964 OCT 9 17:06 SRC
-RWXR-XR-X 1 JLEFFLER STAFF 8760 NOV 23 13:12 STP83
DRWXR-XR-X 3 JLEFFLER STAFF 102 NOV 23 13:04 STP83.DSYM
DRWXR-XR-X 6 JLEFFLER STAFF 204 NOV 6 21:52 TMP
-RWXR-XR-X 1 JLEFFLER STAFF 8808 NOV 23 10:38 TR37
DRWXR-XR-X 3 JLEFFLER STAFF 102 NOV 23 10:38 TR37.DSYM
-RWXR-XR-X 1 JLEFFLER STAFF 26772 NOV 21 20:18 XY73
DRWXR-XR-X 3 JLEFFLER STAFF 102 NOV 21 20:18 XY73.DSYM
-RW-R--R-- 1 JLEFFLER STAFF 467 NOV 21 20:18 XY73.L
は動作しません? –
[* magic numbers *](https://en.wikipedia.org/wiki/Magic_number_(プログラミング))は使用しないでください。代わりに 'STDIN_FILENO'や' STDOUT_FILENO'のような定義済みのマクロを使用してください。また、重要なヘッダーファイルインクルードがありません。 –
あなたの問題については、* 2本のパイプが必要です。既存のパイプを再利用することはできません。 –