Page MenuHomeFreeBSD

D442.id763.diff
No OneTemporary

D442.id763.diff

Index: lib/libc/stdio/fflush.c
===================================================================
--- lib/libc/stdio/fflush.c
+++ lib/libc/stdio/fflush.c
@@ -60,7 +60,7 @@
/*
* There is disagreement about the correct behaviour of fflush()
- * when passed a file which is not open for reading. According to
+ * when passed a file which is not open for writing. According to
* the ISO C standard, the behaviour is undefined.
* Under linux, such an fflush returns success and has no effect;
* under Windows, such an fflush is documented as behaving instead
@@ -68,11 +68,14 @@
* Given that applications may be written with the expectation of
* either of these two behaviours, the only safe (non-astonishing)
* option is to return EBADF and ask that applications be fixed.
+ * SUSv3 now requires that fflush() returns success on a read-only
+ * stream. In addition, the conformance tests will warn if a fflush
+ * on a read-only stream does not set the file descriptor's file offset
+ * to the real position.
*/
- if ((fp->_flags & (__SWR | __SRW)) == 0) {
- errno = EBADF;
- retval = EOF;
- } else
+ if ((fp->_flags & (__SWR | __SRW)) == 0)
+ retval = 0;
+ else
retval = __sflush(fp);
FUNLOCKFILE(fp);
return (retval);
@@ -89,10 +92,9 @@
if (fp == NULL)
return (_fwalk(sflush_locked));
- if ((fp->_flags & (__SWR | __SRW)) == 0) {
- errno = EBADF;
- retval = EOF;
- } else
+ if ((fp->_flags & (__SWR | __SRW)) == 0)
+ retval = 0;
+ else
retval = __sflush(fp);
return (retval);
}
@@ -122,6 +124,12 @@
for (; n > 0; n -= t, p += t) {
t = _swrite(fp, (char *)p, n);
if (t <= 0) {
+ /* Reset _p and _w. */
+ if (p > fp->_p) /* Some was written. */
+ memmove(fp->_p, p, n);
+ fp->_p += n;
+ if ((fp->_flags & (__SLBF | __SNBF)) == 0)
+ fp->_w -= n;
fp->_flags |= __SERR;
return (EOF);
}
Index: lib/libc/stdio/fgetln.3
===================================================================
--- lib/libc/stdio/fgetln.3
+++ lib/libc/stdio/fgetln.3
@@ -97,6 +97,9 @@
The argument
.Fa stream
is not a stream open for reading.
+.It Bq Er ENOMEM
+The internal line buffer could not be expanded due to lack of available memory,
+or because it would need to expand beyond INT_MAX in size.
.El
.Pp
The
Index: lib/libc/stdio/fgetln.c
===================================================================
--- lib/libc/stdio/fgetln.c
+++ lib/libc/stdio/fgetln.c
@@ -37,6 +37,8 @@
__FBSDID("$FreeBSD$");
#include "namespace.h"
+#include <errno.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -61,6 +63,10 @@
#endif
if (fp->_lb._size >= newsize)
return (0);
+ if (newsize > INT_MAX) {
+ errno = ENOMEM;
+ return (-1);
+ }
if ((p = realloc(fp->_lb._base, newsize)) == NULL)
return (-1);
fp->_lb._base = p;
@@ -159,6 +165,7 @@
error:
*lenp = 0; /* ??? */
+ fp->_flags |= __SERR;
FUNLOCKFILE(fp);
return (NULL); /* ??? */
}
Index: lib/libc/stdio/fputs.c
===================================================================
--- lib/libc/stdio/fputs.c
+++ lib/libc/stdio/fputs.c
@@ -62,5 +62,7 @@
ORIENT(fp, -1);
retval = __sfvwrite(fp, &uio);
FUNLOCKFILE(fp);
+ if (retval == 0)
+ return iov.iov_len;
return (retval);
}
Index: lib/libc/stdio/freopen.c
===================================================================
--- lib/libc/stdio/freopen.c
+++ lib/libc/stdio/freopen.c
@@ -97,7 +97,7 @@
(dflags & (O_ACCMODE | O_EXEC)) != (oflags & O_ACCMODE)) {
fclose(fp);
FUNLOCKFILE(fp);
- errno = EINVAL;
+ errno = EBADF;
return (NULL);
}
if (fp->_flags & __SWR)
@@ -132,6 +132,7 @@
* descriptor (if any) was associated with it. If it was attached to
* a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin)
* should work. This is unnecessary if it was not a Unix file.
+ * For UNIX03, we always close if it was open.
*/
if (fp->_flags == 0) {
fp->_flags = __SEOF; /* hold on to it */
@@ -142,15 +143,22 @@
if (fp->_flags & __SWR)
(void) __sflush(fp);
/* if close is NULL, closing is a no-op, hence pointless */
- isopen = fp->_close != NULL;
- if ((wantfd = fp->_file) < 0 && isopen) {
+ if (fp->_close)
(void) (*fp->_close)(fp->_cookie);
- isopen = 0;
- }
+ isopen = 0;
+ wantfd = -1;
}
/* Get a new descriptor to refer to the new file. */
f = _open(file, oflags, DEFFILEMODE);
+ if (f < 0 && isopen) {
+ /* If out of fd's close the old one and try again. */
+ if (errno == ENFILE || errno == EMFILE) {
+ (void) (*fp->_close)(fp->_cookie);
+ isopen = 0;
+ f = _open(file, oflags, DEFFILEMODE);
+ }
+ }
sverrno = errno;
finish:
@@ -158,11 +166,9 @@
* Finish closing fp. Even if the open succeeded above, we cannot
* keep fp->_base: it may be the wrong size. This loses the effect
* of any setbuffer calls, but stdio has always done this before.
- *
- * Leave the existing file descriptor open until dup2() is called
- * below to avoid races where a concurrent open() in another thread
- * could claim the existing descriptor.
*/
+ if (isopen)
+ (void) (*fp->_close)(fp->_cookie);
if (fp->_flags & __SMBF)
free((char *)fp->_bf._base);
fp->_w = 0;
@@ -181,8 +187,6 @@
memset(&fp->_mbstate, 0, sizeof(mbstate_t));
if (f < 0) { /* did not get it after all */
- if (isopen)
- (void) (*fp->_close)(fp->_cookie);
fp->_flags = 0; /* set it free */
FUNLOCKFILE(fp);
errno = sverrno; /* restore in case _close clobbered */
@@ -194,13 +198,12 @@
* to maintain the descriptor. Various C library routines (perror)
* assume stderr is always fd STDERR_FILENO, even if being freopen'd.
*/
- if (wantfd >= 0) {
+ if (wantfd >= 0 && f != wantfd) {
if ((oflags & O_CLOEXEC ? _fcntl(f, F_DUP2FD_CLOEXEC, wantfd) :
_dup2(f, wantfd)) >= 0) {
(void)_close(f);
f = wantfd;
- } else
- (void)_close(fp->_file);
+ }
}
/*
Index: lib/libc/stdio/ftell.c
===================================================================
--- lib/libc/stdio/ftell.c
+++ lib/libc/stdio/ftell.c
@@ -97,6 +97,8 @@
* Find offset of underlying I/O object, then
* adjust for buffered bytes.
*/
+ if (__sflush(fp)) /* may adjust seek offset on append stream */
+ return (1);
if (fp->_flags & __SOFF)
pos = fp->_offset;
else {
Index: lib/libc/stdio/gets.c
===================================================================
--- lib/libc/stdio/gets.c
+++ lib/libc/stdio/gets.c
@@ -52,7 +52,7 @@
int c;
char *s;
static int warned;
- static char w[] =
+ static const char w[] =
"warning: this program uses gets(), which is unsafe.\n";
FLOCKFILE(stdin);
Index: lib/libc/stdio/rewind.c
===================================================================
--- lib/libc/stdio/rewind.c
+++ lib/libc/stdio/rewind.c
@@ -53,9 +53,8 @@
__sinit();
FLOCKFILE(fp);
- if (_fseeko(fp, (off_t)0, SEEK_SET, 1) == 0) {
- clearerr_unlocked(fp);
+ if (_fseeko(fp, (off_t)0, SEEK_SET, 1) == 0)
errno = serrno;
- }
+ clearerr_unlocked(fp); /* POSIX: clear stdio error regardless */
FUNLOCKFILE(fp);
}
Index: lib/libc/stdio/wbuf.c
===================================================================
--- lib/libc/stdio/wbuf.c
+++ lib/libc/stdio/wbuf.c
@@ -36,6 +36,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <errno.h>
#include <stdio.h>
#include "local.h"
@@ -59,8 +60,10 @@
* calls might wrap _w from negative to positive.
*/
fp->_w = fp->_lbfsize;
- if (prepwrite(fp) != 0)
+ if (prepwrite(fp) != 0) {
+ errno = EBADF;
return (EOF);
+ }
c = (unsigned char)c;
ORIENT(fp, -1);

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 11, 4:37 PM (15 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23584428
Default Alt Text
D442.id763.diff (7 KB)

Event Timeline