SUMMARY: Strange behaviour of "setbuf()"

SUMMARY: Strange behaviour of "setbuf()"

Post by Heinz Herbe » Sat, 30 Apr 1994 17:01:53



I had asked why setbuf(stdout,NULL); is ineffective when executed in a child
process just before exec'ing another program, but works fine when executed at
the start of the exec'd program.

I have received quite many responses, all of them boiling down to

         "the data structures that are allocated and used by setbuf()
          are blown away and allocated anew by exec()"

the reason for this being the fact that streams (like stdout) are user data
structures, which are not retained across exec(). Open files however, which
are kernel data structures, are kept open across fork() and exec().

Thanks to all who replied.

MfG
HH

--

- Technical University of Vienna, Austria // Institute for Computer Graphics -
- Life would be so much easier if we could just look at the source code.     -

 
 
 

SUMMARY: Strange behaviour of "setbuf()"

Post by James Vlc » Sun, 08 May 1994 07:57:22



>I had asked why setbuf(stdout,NULL); is ineffective when executed in a child
>process just before exec'ing another program, but works fine when executed at
>the start of the exec'd program.

>I have received quite many responses, all of them boiling down to

>         "the data structures that are allocated and used by setbuf()
>          are blown away and allocated anew by exec()"

>the reason for this being the fact that streams (like stdout) are user data
>structures, which are not retained across exec(). Open files however, which
>are kernel data structures, are kept open across fork() and exec().

At first glance, one tends to think of this as a minor flaw in the
construction of Unix.  "Hmmm... if the parent program opens a
pipe/socket/&c for the child, but I still want the child program to
work interactively, I have to explicitly setbuf() within the code of
the child program."  At first, this appears to run contrary to the
purpose of the tiny stub of child process code between the fork() and
the exec(), since the setbuf() code must be placed within the source
of the child program.

But then, one realizes that - if a program is to be able to run
interactively - it SHOULD explicitly set stdout to be unbuffered or
line buffered (as appropriate, and assuming that stdout is the
preferred channel of interactive output).

Jim Vlcek


 
 
 

SUMMARY: Strange behaviour of "setbuf()"

Post by Leslie Mikese » Sun, 08 May 1994 13:13:28




>>the reason for this being the fact that streams (like stdout) are user data
>>structures, which are not retained across exec(). Open files however, which
>>are kernel data structures, are kept open across fork() and exec().
>At first glance, one tends to think of this as a minor flaw in the
>construction of Unix. "Hmmm... if the parent program opens a
>pipe/socket/&c for the child, but I still want the child program to
>work interactively, I have to explicitly setbuf() within the code of
>the child program."  At first, this appears to run contrary to the
>purpose of the tiny stub of child process code between the fork() and
>the exec(), since the setbuf() code must be placed within the source
>of the child program.
>But then, one realizes that - if a program is to be able to run
>interactively - it SHOULD explicitly set stdout to be unbuffered or
>line buffered (as appropriate, and assuming that stdout is the
>preferred channel of interactive output).

Actually the flaw is that pipes present a different interface than
ptys and real ttys, yet the unix programming paradigm is to treat
everything the same.  Season that with a stdio library that tries
to guess whether or not it can get away with more efficient block
buffering based on which interface it detects and you get connections
that sometimes do what you want and sometimes not.  But, note that
stdio is the real culprit.  If a program does it's own buffering
with write()'s whenever needed, you don't have a problem.  The simple
solution is to just call fflush() at any point in every program where
it might be useful to be sure something is printed.  You need this
anyway if you ever issue prompts that don't include a newline.  Or,
if you want to allow the more efficient block buffering in non-interactive
mode, be sure to include a command line option so you can override
stdio's guess.

Les Mikesell

 
 
 

1. Strange behaviour of "setbuf" on HP

(Sorry  for the  crossposting,  I  didn't  know  what  newsgroup  was most
appropriate  for this  question.  Followup  has been set to "poster",  and
please reply per email.  Also sorry if this appears more than one time, my
newsreader rejected my posting the first time.  Thank you very much.)

I have encountered some rather strange behaviour of setbuf(3) on a HP 705,
HP-UX 8.07,  standard HP  C-compiler.  I'm writing a plain vanilla  filter
application, in which a process creates two pipes, then forks off a child,
and the child execs another program after connecting its stdin, stdout and
stderr  to  the  pipes   created  just   before.  Parent  and  child  then
communicate via the pipes.

Now the exec'd program is an interactive  application,  which writes a few
bytes to stdout,  then waits for user  input,  then again  writes a little
bit, and reads  again, etc.  And, since stdout is buffered,  the few bytes
usually  remain in the pipe, and the parent process  doesn't get any input
from the pipe.  This behaviour is inacceptable  for my application, and so
I  put  a  "setbuf(stdout,NULL)"  into  the  child  process,  right  after
reconnecting  stdout to the pipe and  immediately  before the exec().  For
some unknown  reason, this does *not* work.  (I have also tried to execute
setbuf() directly on the pipe, with the same (negative) result.)

What does work, however, is placing a  "setbuf(stdout,NULL)"  at the start
of the exec'd program.  In this case, everything works as expected, output
is  available  to the  parent  as  soon  as it is  written  by the  child.
Unfortunately,   the   C-source  for  the  exec'd   program  is  generated
automatically  from a Turbo Pascal  program with a Pascal-To-C  converter,
and is written and  maintained  by another  person (my boss :-), which  is
also  the  reason  for  the  program  not to  contain  a  single  call  to
fflush(stdout).  So I can't rely on a specific behaviour of the program, I
have to use it as is.  (Even if I could safely change the program, I would
consider this a quite unsatisfying kludge.)

Can anyone tell me why setbuf()  works "after" the exec(), but not before?
Does exec() change the file's buffers? Bug? Feature? RTFM?  (which FM? :-)

Thanks a lot in advance for any help and hints (email please),
MfG
HH

--

- Technical University of Vienna, Austria // Institute for Computer Graphics -
- Life would be so much easier if we could just look at the source code.     -

2. UNIX for PC

3. strange behavior from "gdb" and "ObjectCenter"

4. Tape Drive OnStream ECHO30 Internal IDE. Good Choice?

5. : Weird ">" redirect behavior vs. ">>" redirect behavior

6. HELP: Reinstalling Sun OS after running Redhat SPARC Linux

7. GETSERVBYNAME()????????????????????"""""""""""""

8. mkfontdir crashes

9. """"""""My SoundBlast 16 pnp isn't up yet""""""""""""

10. Strange "w", "who" and "uptime" output

11. SUMMARY: To "nice" or not to "nice" [LONG]

12. Type "(", ")" and "{", "}" in X...

13. terminal behavior after "man", "less", etc.