[英]C exec/pipe/select program - missing input from child
我有一個生成子腳本的程序。 子腳本只需將1/2的輸入重新重新指定回STDOUT和STDERR。 另一半時間,它悄悄地消耗了它。 我得到的是對寫給孩子的結果的計時錯誤:
Line1: STDOUT Line number 1
Line3: STDERR Line number 1
Line3: STDOUT Line number 3
Getting leftovers
endLine: STDERR Line number 3
行號1應該已經通過相同的Line1讀取來讀取。 同樣,第3行也應由相同的Line3嘗試拾取。
我要解決的問題是我希望能夠向孩子寫一行數據,檢查是否有任何響應並重復。 以下是測試程序:
子腳本:
#! /usr/bin/perl
$| = 1;
select (STDERR);
$|=1;
my $i = 0;
open (F,">> e.out");
select F;
$|=1;
select (STDOUT);
while (<>) {
chomp;
print F "($_)\n";
if ($i++) {
print "STDOUT $_\n";
print STDERR "STDERR $_\n";
}
$i %= 2;
}
close F;
父C程序:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
main () {
pid_t pid;
int p2child[2];
int c2parent[2];
pipe (p2child);
pipe (c2parent);
if ((pid = fork()) < 0) {
fprintf (stderr, "Fork error: %s\n", strerror(errno));
/*
Child Process
*/
} else if (pid == 0) {
close (p2child[1]);
dup2 (p2child[0], STDIN_FILENO);
close (c2parent[0]);
dup2 (c2parent[1], STDOUT_FILENO);
dup2 (c2parent[1], STDERR_FILENO);
if (execlp ("./e", "./e", 0 )) {
perror("Exec failed");
}
/*
Parent Process
*/
} else {
FILE* istream;
FILE* ostream;
char line[80];
fd_set set;
struct timeval timeout;
int ret;
int counter;
close (p2child[0]);
close (c2parent[1]);
ostream = fdopen (p2child[1], "w");
istream = fdopen (c2parent[0], "r");
for (counter = 0; counter < 5; counter++) {
fprintf (ostream, "Line number %d\n", counter);
fflush (ostream);
do {
FD_ZERO(&set);
FD_SET(c2parent[0], &set);
timeout.tv_sec = 0;
timeout.tv_usec = 500000;
ret = select(FD_SETSIZE, &set, NULL, NULL, &timeout);
if (ret > 0) {
fgets(line, 80, istream);
fprintf (stdout, "Line%d: %s", counter, line);
fflush (stdout);
}
} while (ret > 0);
}
fprintf (stdout, "Getting leftovers\n");
while (fgets(line, 80, istream)) {
fprintf (stdout, "endLine: %s", line);
fflush (stdout);
}
close (p2child[1]);
close (c2parent[0]);
waitpid (pid, NULL, 0);
}
fprintf (stderr, "Exiting\n");
}
當調用fgets()時,您從流中讀取了一行輸入,但stdio本身可能已讀取並緩沖了更多內容 ; 這是你的問題。 select()比預期的要早返回0,因為先前的fgets()調用導致stdio吸收了所有剩余的輸入。 作為測試,更換
fgets(line, 80, istream);
在選擇循環中
char *p = line;
do {
read(c2parent[0], p, 1);
} while (*p++ != '\n');
並且您應該看到讀取和寫入陷入鎖步,沒有剩余輸入。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.