Cygwin 上令人困惑的代码流顺序
Confusing sequence of Code flow on Cygwin
在 C 中有这个非常简单的程序(在 Cygwin 上用 gcc 构建)::
// This program is a tutorial to Stack-based overflow, that's why "gets"
#include <stdio.h>
void test()
{
char buff[4];
printf("Some input: ");
gets(buff);
puts(buff);
}
int main(int argc, char** argv)
{
test();
return 0;
}
现在当我 运行 在 Windows 控制台上执行此操作时,printf
首先执行并等待输入::
但是当我在 Cygwin 终端下 运行 相同的 exe 时,它等待输入然后 printf
执行::
为什么会这样?
EDIT:: \n
附加到 printf
语句中的字符串,行为保持不变::
因此,经过一些阅读和研究,我得出了针对此行为的最终理论。
简答:: stdout
被缓冲,所以做
void test()
{
char buff[4];
setvbuf(stdout, NULL, _IONBF, 0); // <--- setting stdout to _IONBF
printf("Some input: ");
gets(buff);
puts(buff);
}
在向控制台打印任何内容之前,或者,
void test()
{
char buff[4];
printf("Some input: ");
fflush(stdout); // <--- force the stdout to flush
gets(buff);
puts(buff);
}
printf
语句后问题解决。
长答案::
当我 运行 与 Bash.exe
相同的 exe 时,stdout 没有被缓冲::
与 mintty.exe
相同的 exe,stdout 被缓冲::
现在的问题是,
- 为什么
stdout
在一个中没有缓冲而在另一个中缓冲?
As you can see the tty
output on both, bash shows as console session
/dev/cons0
, whereas the mintty shows as pseudo-terminal session
/dev/pty0
.
所以,
- 它如何回答无缓冲和缓冲标准输出的问题?
My browsing re-re-and-re searches landed me here, stating, If I type tty
in the respective Cygwin windows, I see that mintty
and xterm
are both
pseudo-terminals whereas bash
is a console session - I believe
procServ
uses forkpty()
. So I think it boils down to Windows treating
a Cygwin pty as non-interactive and thus buffering both stdout
and
stderr
.
我不确定,这有多精确,但是是的,这似乎是对这种行为的实用且最好的解释。
根据 Section 7.9.13/7 of c99
指出:
At program start-up, three text streams are predefined and need not be
opened explicitly - standard input (for reading conventional input),
standard output (for writing conventional output), and standard error
(for writing diagnostic output).
As initially opened, the standard error stream is not fully buffered;
the standard input and standard output streams are fully buffered if
and only if the stream can be determined not to refer to an
interactive device.
*粗体强调是我的
在 C 中有这个非常简单的程序(在 Cygwin 上用 gcc 构建)::
// This program is a tutorial to Stack-based overflow, that's why "gets"
#include <stdio.h>
void test()
{
char buff[4];
printf("Some input: ");
gets(buff);
puts(buff);
}
int main(int argc, char** argv)
{
test();
return 0;
}
现在当我 运行 在 Windows 控制台上执行此操作时,printf
首先执行并等待输入::
但是当我在 Cygwin 终端下 运行 相同的 exe 时,它等待输入然后 printf
执行::
为什么会这样?
EDIT:: \n
附加到 printf
语句中的字符串,行为保持不变::
因此,经过一些阅读和研究,我得出了针对此行为的最终理论。
简答:: stdout
被缓冲,所以做
void test()
{
char buff[4];
setvbuf(stdout, NULL, _IONBF, 0); // <--- setting stdout to _IONBF
printf("Some input: ");
gets(buff);
puts(buff);
}
在向控制台打印任何内容之前,或者,
void test()
{
char buff[4];
printf("Some input: ");
fflush(stdout); // <--- force the stdout to flush
gets(buff);
puts(buff);
}
printf
语句后问题解决。
长答案::
当我 运行 与 Bash.exe
相同的 exe 时,stdout 没有被缓冲::
与 mintty.exe
相同的 exe,stdout 被缓冲::
现在的问题是,
- 为什么
stdout
在一个中没有缓冲而在另一个中缓冲?
As you can see the
tty
output on both, bash shows as console session/dev/cons0
, whereas the mintty shows as pseudo-terminal session/dev/pty0
.
所以,
- 它如何回答无缓冲和缓冲标准输出的问题?
My browsing re-re-and-re searches landed me here, stating, If I type
tty
in the respective Cygwin windows, I see thatmintty
andxterm
are both pseudo-terminals whereasbash
is a console session - I believeprocServ
usesforkpty()
. So I think it boils down to Windows treating a Cygwin pty as non-interactive and thus buffering bothstdout
andstderr
.
我不确定,这有多精确,但是是的,这似乎是对这种行为的实用且最好的解释。
根据 Section 7.9.13/7 of c99
指出:
At program start-up, three text streams are predefined and need not be opened explicitly - standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output).
As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.
*粗体强调是我的