diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 042c17d64..6f506cc8c 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,11 @@ +2007-07-31 Eric Blake + + 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. + 2007-07-18 Eric Blake Fix 'make info'. diff --git a/newlib/libc/stdio/fdopen.c b/newlib/libc/stdio/fdopen.c index f4fc551c4..aa764c372 100644 --- a/newlib/libc/stdio/fdopen.c +++ b/newlib/libc/stdio/fdopen.c @@ -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 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; diff --git a/newlib/libc/stdio/findfp.c b/newlib/libc/stdio/findfp.c index 43f02ba5f..4f613e537 100644 --- a/newlib/libc/stdio/findfp.c +++ b/newlib/libc/stdio/findfp.c @@ -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 (); } diff --git a/newlib/libc/stdio64/fdopen64.c b/newlib/libc/stdio64/fdopen64.c index 4f159e813..49d1f03aa 100644 --- a/newlib/libc/stdio64/fdopen64.c +++ b/newlib/libc/stdio64/fdopen64.c @@ -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;