Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.unix.programmer > #1200 > unrolled thread

How to automatically flush stdout when a read from stdin occurs.

Started bytm <thomas.mertes@gmx.at>
First post2011-09-02 02:20 -0700
Last post2011-09-03 09:08 +0100
Articles 7 — 5 participants

Back to article view | Back to comp.unix.programmer


Contents

  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

#1200 — How to automatically flush stdout when a read from stdin occurs.

Fromtm <thomas.mertes@gmx.at>
Date2011-09-02 02:20 -0700
SubjectHow 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]


#1201

FromRainer Weikusat <rweikusat@mssgmbh.com>
Date2011-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]


#1205

Fromtm <thomas.mertes@gmx.at>
Date2011-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]


#1207

FromNobody <nobody@nowhere.com>
Date2011-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]


#1202

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-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]


#1203

Fromgordonb.j3p91@burditt.org (Gordon Burditt)
Date2011-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]


#1204

FromNobody <nobody@nowhere.com>
Date2011-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