[問題] 請教一下 popen+fgets

作者: gn00618777 (非常念舊)   2022-05-31 23:02:04
板友們晚安,我想透過Linux C, popen執行一個binary,並獲得binary的stdout
單執行binary 是正常的。會印出 start test,也會每隔3秒印出
但我如果透過另支程式 popen 加 fgets就會卡住,試著 fflush(fp)也無用,請問
有人知道是啥問題嗎? 謝謝。
binary code:
int main () {
int ret = 0;
struct pollfd fds[1] = {0};
int fd = timerfd_create(CLOCK_MONOTONIC, 0);
char rbuf[1024] = {0};
struct itimerspec itval;
itval.it_interval.tv_sec = 3;
itval.it_interval.tv_nsec = 0;
itval.it_value.tv_sec = 3;
itval.it_value.tv_nsec = 0;
fd[0].fd = fd;
fds[0]│events = POLLIN;
timerfd_settime (fd, 0, &itval, NULL);
printf("start test\n");
while(1) {
ret = poll(fds, 1, -1);
if(ret < 0) {
printf("poll fail\n");
} else if(ret == 0) {
printf("time out\n");
} else {
read(fds[0].fd, &rbuf, 1024);
}
printf("finish poll\n");
}
}
test.c:
int main()
{
char line[1024] = {0};
FILE *fp = popen("./burn", "r");
fflush(fp);
while(fgets(line, 1022, fp) != NULL) {
printf("line:%s\n", line);
}
printf("123\n");
return 0;
}
作者: LPH66 (-6.2598534e+18f)   2022-06-01 00:21:00
popen 會繼承父行程你沒開 pipe 的那一端的標準輸出入以你開讀為例, 子行程的寫端會進 pipe, 但讀端會繼承父行程因此子行程等於 poll 了鍵盤輸入 stdinhmmm, 仔細想想這樣跟你直接執行好像一樣...這樣就不知道了
作者: b0920075 (Void)   2022-06-01 04:18:00
是不是卡在你的 binary stdout 的 buffer ?試試看 flush 掉你 binary 輸出的 fd?
作者: gn00618777 (非常念舊)   2022-06-01 06:38:00
我忘記說明,他放很久後會輸出請問我用fflush(fp),是不是已經做flush了
作者: b0920075 (Void)   2022-06-01 10:31:00
我是說 binary code 不是 test
作者: LPH66 (-6.2598534e+18f)   2022-06-01 12:15:00
喔, 結果是 buffer...查了一下 \n flush 似乎只有 terminal輸出會, 如果是接去其他地方 (像這裡接到 pipe 裡) 就不會原 PO 試試 binary 裡全部 printf 後都加 fflush(stdout);另外之前看時沒注意, fflush 不能用在輸入串上你的 test 中的 fp 是輸入, 對它 fflush 是 UB
作者: gn00618777 (非常念舊)   2022-06-05 20:59:00
我在加了fflush到print後面,就可以了。謝謝
作者: yvb   2022-06-23 12:52:00
setbuf(), setlinebuf()

Links booklink

Contact Us: admin [ a t ] ucptt.com