This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: The stdout always becomes line buffered mode.


Kazuhiro Fujieda wrote:
> 
> >>> On Thu, 26 Apr 2001 18:27:48 -0400
> >>> DJ Delorie <dj@delorie.com> said:
> 
> > >   ISO/IEC 9899:1999, Second Edition 1999-12-01, p.266
> > >     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 interective
> > >     device.
> >
> > The streams aren't fully buffered, they're line buffered.  I think
> > this complies with the spec.
> 
> I'm afraid you misunderstand. The first sentence of the spec
> mentions the *stderr*. The current newlib sets it no buffered so
> complies the spec.
> 
> I mentioned the *stdout*. Another sentence says the way of
> the current newlib doesn't comply the spec.
> 
> Anyway, I believe my patch is correct.

Your interpretation of the spec is correct; unfortunately, your patch ends up breaking a few
external and internal ports.  The problem has to do with "if the stream can be determined not to
refer to an interactive device".  Many embedded platforms don't have file systems so they hard-wire
isatty() and fstat().  Most of them in libgloss return true for isatty() and set S_IFCHR for
st.st_mode which allows everything to work as expected, however, there are a few out there that
return failure for fstat() (not unreasonable) and a few return 0 for isatty().  The __smakebuf()
routine doesn't handle these situations properly because it changes to line buffering only if the
device is found to be a terminal.  This is not the same as leaving it full-buffered only if it can
determine it is not an interactive terminal.  If fstat() returns failure, it does not change the
mode to line buffered.

One possibility is to change all the libgloss and sys directories to ensure that fstat() and
isatty() return the expected values for at least the std streams, however, IMO it is better to
default line buffering for platforms that don't have real file systems.  This allows them the
flexibility regarding how they want to handle fstat() and isatty().  Reusing the HAVE_FCNTL flag
would be ok since all the platforms that have file systems set the flag to true and the few that
don't are covered with appropriate fstat() and isatty() versions.  Thus, I propose the fix be:

Index: findfp.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/findfp.c,v
retrieving revision 1.3
diff -u -r1.3 findfp.c
--- findfp.c    2000/05/23 23:51:54     1.3
+++ findfp.c    2001/04/30 20:58:32
@@ -152,7 +152,16 @@
   s->__sdidinit = 1;

   std (s->__sf + 0, __SRD, 0, s);
+
+  /* on platforms that have true file system I/O, we can verify whether stdout
+     is an interactive terminal or not.  For all other platforms, we will
+     default to line buffered mode here.  */
+#ifdef HAVE_FCNTL
+  std (s->__sf + 1, __SWR, 1, s);
+#else
   std (s->__sf + 1, __SWR | __SLBF, 1, s);
+#endif
+
   std (s->__sf + 2, __SWR | __SNBF, 2, s);

   s->__sglue._next = NULL;

-- Jeff J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]