《unix环境中的高级编程》一书在第15章讨论了管道,它表明我们在处理标准I/O函数时应该注意缓冲类型。
不同打开的标准 I/O 流的缓冲类型是(在本书的第 5 章中讨论):
- 标准误是
unbuffered
- 连接到终端设备的流是
line-buffered
- 所有其他流是
fully-buffered
当父/子连接到 a时,他们用来通信pipe
的端(应该是类型对象,根据接口)应该根据上面的规则列表(因为它是连接到的流)。但是那一章中示例代码的行为似乎不是。FILE *
fully-buffered
pipe
fully-buffered
这是示例代码:
myuclc.c:
1 #include "apue.h"
2 #include <ctype.h>
3 int
4 main(void)
5 {
6 int c;
7 while ((c = getchar()) != EOF) {
8 if (isupper(c))
9 c = tolower(c);
10 if (putchar(c) == EOF)
11 err_sys("output error");
12 if (c == '\n')
13 fflush(stdout);
14 }
15 exit(0);
16 }
popen1.c:
1 #include "apue.h"
2 #include <sys/wait.h>
3 int
4 main(void)
5 {
6 char line[MAXLINE];
7 FILE *fpin;
8
9 if ((fpin = popen("myuclc", "r")) == NULL) // "myuclc" is executable file compile-link by "myuclc.c"
10 err_sys("popen error");
11 for ( ; ; ) {
12 fputs("prompt> ", stdout);
13 fflush(stdout);
14
15 if (fgets(line, MAXLINE, fpin) == NULL) /* read from pipe */
16 break;
17 if (fputs(line, stdout) == EOF)
18 err_sys("fputs error to pipe");
19 }
20 if (pclose(fpin) == -1)
21 err_sys("pclose error");
22 putchar('\n');
23 exit(0);
24 }
所以我的问题是:fgets()
在第 15 行popen1.c
应该fully-buffered
根据缓冲规则,为什么它的行为类似于line-buffered
或unbuffered
:
此外,我之前也尝试setvbuf()
过fgets()
专门将缓冲类型设置为_IOFBF
(full-buffered) of fpin
,还是不行。
prompt> abc
abc
prompt> ABC
abc
prompt> efg
efg
prompt> EFG
efg
prompt>