This is the mail archive of the newlib@sourceware.org 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]
Other format: [Raw text]

fix stderr, fdopen


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

POSIX requires "The stderr stream is expected to be open for reading and
writing".  This implements that (and if fd 2 is a write-only pipe instead
of a read-write tty, fgetc(stderr) will correctly fail later on); ok to
apply?

Also, for fdopen, POSIX states "Although not explicitly required by this
volume of IEEE Std 1003.1-2001, a good implementation of append (a) mode
would cause the O_APPEND flag to be set."  OK to apply?

I'm not quite sure whether POSIX requires the following example to remain
in append mode, or if it can go to seekable writes; but I'm assuming that
a stream must remain in append mode even if the underlying fd is altered.

remove("foo");
FILE *f = fopen("foo", "a");
fputs("hi", f);
fflush(f);
fcntl(fileno(f), F_SETFL, fcntl(fileno(f), F_GETFL) & ~O_APPEND);
fseek(f, 0, SEEK_SET);
fputs("bye", f);
fclose(f);
/* Does "foo" now contain "hibye", or just "bye"?  */

2007-07-13  Eric Blake  <ebb9@byu.net>

	More POSIX stream corner cases.
	* libc/stdio/findfp.c (__sinit): Open stderr read/write.
	* libc/stdio/fdopen.c (_fdopen_r): Set O_APPEND on fd when
	requested.
	* libc/stdio64/fdopen64.c (_fdopen64_r): Likewise.

- --
Don't work too hard, make some time for fun as well!

Eric Blake             ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGmDzU84KuGfSFAYARAqOUAKCERj8sP32yTUX6htEBR0WN2eu7qwCg1mLL
Nr7bxe59nWhiYNvwLBFdZGA=
=ryfS
-----END PGP SIGNATURE-----
Index: libc/stdio/fdopen.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/fdopen.c,v
retrieving revision 1.8
diff -u -p -r1.8 fdopen.c
--- libc/stdio/fdopen.c	23 Apr 2004 20:01:54 -0000	1.8
+++ libc/stdio/fdopen.c	14 Jul 2007 02:58:51 -0000
@@ -29,7 +29,7 @@ ANSI_SYNOPSIS
 	FILE *fdopen(int <[fd]>, const char *<[mode]>);
 	FILE *_fdopen_r(struct _reent *<[reent]>,
                         int <[fd]>, const char *<[mode]>);
-  
+
 TRAD_SYNOPSIS
 	#include <stdio.h>
 	FILE *fdopen(<[fd]>, <[mode]>)
@@ -96,17 +96,14 @@ _DEFUN(_fdopen_r, (ptr, fd, mode),
   _flockfile (fp);
 
   fp->_flags = flags;
-  /*
-   * If opened for appending, but underlying descriptor
-   * does not have O_APPEND bit set, assert __SAPP so that
-   * __swrite() will lseek to end before each write.
-   */
-  if ((oflags & O_APPEND)
+  /* POSIX recommends setting the O_APPEND bit on fd to match append
+     streams.  Someone may later clear O_APPEND on fileno(fp), but the
+     stream must still remain in append mode.  Rely on __sflags
+     setting __SAPP properly.  */
 #ifdef HAVE_FCNTL
-       && !(fdflags & O_APPEND)
+  if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
+    _fcntl_r (ptr, fd, F_SETFL, fdflags | O_APPEND);
 #endif
-      )
-    fp->_flags |= __SAPP;
   fp->_file = fd;
   fp->_cookie = (_PTR) fp;
 
Index: libc/stdio/findfp.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/findfp.c,v
retrieving revision 1.18
diff -u -p -r1.18 findfp.c
--- libc/stdio/findfp.c	1 May 2007 23:03:36 -0000	1.18
+++ libc/stdio/findfp.c	14 Jul 2007 02:58:51 -0000
@@ -204,16 +204,21 @@ _DEFUN(__sinit, (s),
 
   std (s->_stdin,  __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.  */
+  /* On platforms that have true file system I/O, we can verify
+     whether stdout is an interactive terminal or not, as part of
+     __smakebuf on first use of the stream.  For all other platforms,
+     we will default to line buffered mode here.  Technically, POSIX
+     requires both stdin and stdout to be line-buffered, but tradition
+     leaves stdin alone on systems without fcntl.  */
 #ifdef HAVE_FCNTL
   std (s->_stdout, __SWR, 1, s);
 #else
   std (s->_stdout, __SWR | __SLBF, 1, s);
 #endif
 
-  std (s->_stderr, __SWR | __SNBF, 2, s);
+  /* POSIX requires stderr to be opened for reading and writing, even
+     when the underlying fd 2 is write-only.  */
+  std (s->_stderr, __SRW | __SNBF, 2, s);
 
   __sinit_lock_release ();
 }
Index: libc/stdio64/fdopen64.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio64/fdopen64.c,v
retrieving revision 1.4
diff -u -p -r1.4 fdopen64.c
--- libc/stdio64/fdopen64.c	1 May 2007 23:03:36 -0000	1.4
+++ libc/stdio64/fdopen64.c	14 Jul 2007 02:58:51 -0000
@@ -67,17 +67,14 @@ _DEFUN (_fdopen64_r, (ptr, fd, mode),
   _flockfile(fp);
 
   fp->_flags = flags;
-  /*
-   * If opened for appending, but underlying descriptor
-   * does not have O_APPEND bit set, assert __SAPP so that
-   * __swrite() will lseek to end before each write.
-   */
-  if ((oflags & O_APPEND)
+  /* POSIX recommends setting the O_APPEND bit on fd to match append
+     streams.  Someone may later clear O_APPEND on fileno(fp), but the
+     stream must still remain in append mode.  Rely on __sflags
+     setting __SAPP properly.  */
 #ifdef HAVE_FCNTL
-       && !(fdflags & O_APPEND)
+  if ((oflags & O_APPEND) && !(fdflags & O_APPEND))
+    _fcntl_r (ptr, fd, F_SETFL, fdflags | O_APPEND);
 #endif
-      )
-    fp->_flags |= __SAPP;
   fp->_file = fd;
   fp->_cookie = (_PTR) fp;
 

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