Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.unix.programmer > #1200 > unrolled thread
| Started by | tm <thomas.mertes@gmx.at> |
|---|---|
| First post | 2011-09-02 02:20 -0700 |
| Last post | 2011-09-03 09:08 +0100 |
| Articles | 7 — 5 participants |
Back to article view | Back to comp.unix.programmer
How to automatically flush stdout when a read from stdin occurs. tm <thomas.mertes@gmx.at> - 2011-09-02 02:20 -0700
Re: How to automatically flush stdout when a read from stdin occurs. Rainer Weikusat <rweikusat@mssgmbh.com> - 2011-09-02 13:50 +0100
Re: How to automatically flush stdout when a read from stdin occurs. tm <thomas.mertes@gmx.at> - 2011-09-03 02:10 -0700
Re: How to automatically flush stdout when a read from stdin occurs. Nobody <nobody@nowhere.com> - 2011-09-03 13:05 +0100
Re: How to automatically flush stdout when a read from stdin occurs. Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-09-02 20:43 -0400
Re: How to automatically flush stdout when a read from stdin occurs. gordonb.j3p91@burditt.org (Gordon Burditt) - 2011-09-02 23:56 -0500
Re: How to automatically flush stdout when a read from stdin occurs. Nobody <nobody@nowhere.com> - 2011-09-03 09:08 +0100
| From | tm <thomas.mertes@gmx.at> |
|---|---|
| Date | 2011-09-02 02:20 -0700 |
| Subject | How to automatically flush stdout when a read from stdin occurs. |
| Message-ID | <500542b0-0d1d-4f96-9c17-2d77aacfd1b9@k29g2000yqf.googlegroups.com> |
The standard behaviour of stdin and stdout is (when a program is started from a shell window): Whenever I read from stdin a fflush(stdout) is automatically done, before data is read from stdin. This allows nice interactive behaviour. But when I connect to the same program via two pipes no such flushing occurs. My man page about stdio contains the following paragraph: Output streams that refer to terminal devices are always line buffered by default; pending output to such streams is written automatically whenever an input stream that refers to a terminal device is read. Okay, a pipe is not a terminal device. I could change the child program to contain a fflush(stdout) before every read from stdin, but I hope that a simpler solution is possible. Can a parent process tell a child process: The stdin and stdout file descriptors should be handled as terminal devices? The child process could find out that stdin and stdout are connected with pipes (fstat() and check st_mode for S_IFIFO) and set stdout to line buffering (with setvbuf()), but how can I get the read from stdin causes flush of stdout behaviour? Can the child process do something like: interactive_io(stdin, stdout); To get the automatic flush behaviour? With such an behaviour I could avoid changing all interactive I/O in the child program. Many thanks in advance. Greetings Thomas Mertes -- Seed7 Homepage: http://seed7.sourceforge.net Seed7 - The extensible programming language: User defined statements and operators, abstract data types, templates without special syntax, OO with interfaces and multiple dispatch, statically typed, interpreted or compiled, portable, runs under linux/unix/windows.
[toc] | [next] | [standalone]
| From | Rainer Weikusat <rweikusat@mssgmbh.com> |
|---|---|
| Date | 2011-09-02 13:50 +0100 |
| Message-ID | <87obz3rtut.fsf@sapphire.mobileactivedefense.com> |
| In reply to | #1200 |
tm <thomas.mertes@gmx.at> writes: > The standard behaviour of stdin and stdout is (when a program is > started from a shell window): > > Whenever I read from stdin a fflush(stdout) is automatically done, > before data is read from stdin. This allows nice interactive > behaviour. > > But when I connect to the same program via two pipes no such > flushing occurs. > > My man page about stdio contains the following paragraph: > > Output streams that refer to terminal devices are always line > buffered by default; pending output to such streams is written > automatically whenever an input stream that refers to a terminal > device is read. [...] > The child process could find out that stdin and stdout are connected > with pipes (fstat() and check st_mode for S_IFIFO) and set stdout > to line buffering (with setvbuf()), but how can I get the > > read from stdin causes flush of stdout > > behaviour? > Can the child process do something like: > > interactive_io(stdin, stdout); > > To get the automatic flush behaviour? This isn't exactly the answer to your question but usually, when you want to remote-control an interactive program (for instance, in the way ssh enables using a shell interactively despite using TCP for I/O), you should be using a pseudo-terminal pair (pty) instead of a pipe because that is 'an interactive device'.
[toc] | [prev] | [next] | [standalone]
| From | tm <thomas.mertes@gmx.at> |
|---|---|
| Date | 2011-09-03 02:10 -0700 |
| Message-ID | <203bf7d1-cf75-4cd0-a75d-2c88d690a05c@fd21g2000vbb.googlegroups.com> |
| In reply to | #1201 |
On 2 Sep., 14:50, Rainer Weikusat <rweiku...@mssgmbh.com> wrote: > tm <thomas.mer...@gmx.at> writes: > > The standard behaviour of stdin and stdout is (when a program is > > started from a shell window): > > > Whenever I read from stdin a fflush(stdout) is automatically done, > > before data is read from stdin. This allows nice interactive > > behaviour. > > > But when I connect to the same program via two pipes no such > > flushing occurs. > > > My man page about stdio contains the following paragraph: > > > Output streams that refer to terminal devices are always line > > buffered by default; pending output to such streams is written > > automatically whenever an input stream that refers to a terminal > > device is read. > > [...] > > > The child process could find out that stdin and stdout are connected > > with pipes (fstat() and check st_mode for S_IFIFO) and set stdout > > to line buffering (with setvbuf()), but how can I get the > > > read from stdin causes flush of stdout > > > behaviour? > > Can the child process do something like: > > > interactive_io(stdin, stdout); > > > To get the automatic flush behaviour? > > This isn't exactly the answer to your question but usually, when you > want to remote-control an interactive program (for instance, in the > way ssh enables using a shell interactively despite using TCP for > I/O), you should be using a pseudo-terminal pair (pty) instead of a > pipe because that is 'an interactive device'. I was considering that. But pseudo-terminals have the disadvantage of being more OS dependent than pipes. Can ptys be used on all Unix-like operating systems the same way? If not I would be interested to know how ptys are used under the most common Unix-like operating systems. This way I can use #ifdefs in my library code. What should be used under Windows instead of ptys? Many thanks in advance. Greetings Thomas Mertes -- Seed7 Homepage: http://seed7.sourceforge.net Seed7 - The extensible programming language: User defined statements and operators, abstract data types, templates without special syntax, OO with interfaces and multiple dispatch, statically typed, interpreted or compiled, portable, runs under linux/unix/windows.
[toc] | [prev] | [next] | [standalone]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2011-09-03 13:05 +0100 |
| Message-ID | <pan.2011.09.03.12.05.24.68000@nowhere.com> |
| In reply to | #1205 |
On Sat, 03 Sep 2011 02:10:08 -0700, tm wrote: > Can ptys be used on all Unix-like operating systems > the same way? Creating them varies a bit (BSD vs Unix98 vs SysV/STREAMS), but they work the same way once they've been created. > What should be used under Windows instead of ptys? Pipes. Windows doesn't have anything similar to pseudo-terminals.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2011-09-02 20:43 -0400 |
| Message-ID | <j3rt6v$8rb$1@dont-email.me> |
| In reply to | #1200 |
On 9/2/2011 5:20 AM, tm wrote:
> The standard behaviour of stdin and stdout is (when a program is
> started from a shell window):
>
> Whenever I read from stdin a fflush(stdout) is automatically done,
> before data is read from stdin. This allows nice interactive
> behaviour.
>
> But when I connect to the same program via two pipes no such
> flushing occurs.
>
[...]
Have you considered using a pty instead of a pair of pipes?
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | gordonb.j3p91@burditt.org (Gordon Burditt) |
|---|---|
| Date | 2011-09-02 23:56 -0500 |
| Message-ID | <c_adndActqH6LvzTnZ2dnUVZ_o-dnZ2d@posted.internetamerica> |
| In reply to | #1200 |
> The standard behaviour of stdin and stdout is (when a program is > started from a shell window): You need more conditions here, like stdin and stdout not redirected to files. > > Whenever I read from stdin a fflush(stdout) is automatically done, > before data is read from stdin. This allows nice interactive > behaviour. What standard guarantees that? Linux? stdout is line buffered, which is still problematical when the prompt does not end in a newline. Actually, prompts that don't end in newlines are always problematical when sent to a device called a "line printer", which doesn't start printing a line until it has the whole line to print. If you do know of a standard that guarantees that, read the fine print. The claims for what Linux does do not mention *stdin* or *stdout*. > But when I connect to the same program via two pipes no such > flushing occurs. > > My man page about stdio contains the following paragraph: > > Output streams that refer to terminal devices are always line > buffered by default; pending output to such streams is written > automatically whenever an input stream that refers to a terminal > device is read. > > Okay, a pipe is not a terminal device. A pty is a terminal device, and this difference is pretty much the reason for the existence of ptys at all. Think about it. > I could change the child program to contain a fflush(stdout) before > every read from stdin, but I hope that a simpler solution is > possible. > Can a parent process tell a child process: > The stdin and stdout file descriptors should be handled > as terminal devices? Yes, sort of. "handled as terminal devices" -> "line-buffered". (1) Implement the tr(1) -u flag in the child, (have it call setvbuf(..., ..., _IOLBF, ...) ) (2) the parent should use it in invoking the child. This doesn't work too well when the child is an arbitrary program. > The child process could find out that stdin and stdout are connected > with pipes (fstat() and check st_mode for S_IFIFO) and set stdout > to line buffering (with setvbuf()), I certainly do *NOT* recommend that behavior for an arbitrary child all the time. It would likely kill the performance of various not-particularly-interactive tools like grep when they are used in a non-interactive manner with large files. > but how can I get the > > read from stdin causes flush of stdout > > behaviour? Read the specification of the feature, preferably in any standard if there is such a standard. I think it goes like this: A read from *any unbuffered or line-buffered stream* causes a flush of *all line-buffered streams*. That is what FreeBSD implements. > Can the child process do something like: > > interactive_io(stdin, stdout); > > To get the automatic flush behaviour? I believe that on systems with automatic flush behavior, setvbuf() will do it. On systems with or without automatic flush behavior, using ptys will do it. > With such an behaviour I could avoid changing all interactive I/O > in the child program.
[toc] | [prev] | [next] | [standalone]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2011-09-03 09:08 +0100 |
| Message-ID | <pan.2011.09.03.08.08.15.887000@nowhere.com> |
| In reply to | #1203 |
On Fri, 02 Sep 2011 23:56:07 -0500, Gordon Burditt wrote: >> but how can I get the >> >> read from stdin causes flush of stdout >> >> behaviour? > > Read the specification of the feature, preferably in any standard > if there is such a standard. I think it goes like this: > > A read from *any unbuffered or line-buffered stream* causes > a flush of *all line-buffered streams*. ISO C says (§7.19.3#3): When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block. When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled. When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment. Support for these characteristics is implementation-defined, and may be affected via the setbuf and setvbuf functions. POSIX (§2.5) says essentially the same thing: When a stream is "unbuffered", bytes are intended to appear from the source or at the destination as soon as possible; otherwise, bytes may be accumulated and transmitted as a block. When a stream is "fully buffered", bytes are intended to be transmitted as a block when a buffer is filled. When a stream is "line buffered", bytes are intended to be transmitted as a block when a <newline> byte is encountered. Furthermore, bytes are intended to be transmitted as a block when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line-buffered stream that requires the transmission of bytes. Support for these characteristics is implementation-defined, and may be affected via setbuf() and setvbuf(). http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html
[toc] | [prev] | [standalone]
Back to top | Article view | comp.unix.programmer
csiph-web