Page MenuHomeFreeBSD

D54355.diff
No OneTemporary

D54355.diff

diff --git a/include/stdio.h b/include/stdio.h
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -126,7 +126,7 @@
int _r; /* (*) read space left for getc() */
int _w; /* (*) write space left for putc() */
short _flags; /* (*) flags, below; this FILE is free if 0 */
- short _fileno; /* (*) fileno, if Unix descriptor, else -1 */
+ short _fileno_short; /* (*) fileno, if Unix descriptor and <= SHRT_MAX, else -1 [legacy] */
struct __sbuf _bf; /* (*) the buffer (at least 1 byte, if !NULL) */
int _lbfsize; /* (*) 0 or -_bf._size, for inline putc */
@@ -159,6 +159,7 @@
int _orientation; /* orientation for fwide() */
__mbstate_t _mbstate; /* multibyte conversion state */
int _flags2; /* additional flags */
+ int _fileno; /* (*) fileno, if Unix descriptor, else -1 */
};
#ifndef _STDFILE_DECLARED
#define _STDFILE_DECLARED
diff --git a/lib/libc/stdio/fclose.c b/lib/libc/stdio/fclose.c
--- a/lib/libc/stdio/fclose.c
+++ b/lib/libc/stdio/fclose.c
@@ -61,6 +61,7 @@
if (HASLB(fp))
FREELB(fp);
fp->_fileno = -1;
+ fp->_fileno_short = -1;
fp->_r = fp->_w = 0; /* Mess up if reaccessed. */
/*
diff --git a/lib/libc/stdio/fdopen.c b/lib/libc/stdio/fdopen.c
--- a/lib/libc/stdio/fdopen.c
+++ b/lib/libc/stdio/fdopen.c
@@ -48,17 +48,10 @@
FILE *fp;
int flags, oflags, fdflags, rc, tmp;
- /*
- * File descriptors are a full int, but _fileno is only a short.
- * If we get a valid file descriptor that is greater than
- * SHRT_MAX, then the fd will get sign-extended into an
- * invalid file descriptor. Handle this case by failing the
- * open.
- */
- if (fd > SHRT_MAX) {
- errno = EMFILE;
- return (NULL);
- }
+ if (fd < 0) {
+ errno = EBADF;
+ return (NULL);
+ }
if ((flags = __sflags(mode, &oflags)) == 0)
return (NULL);
@@ -102,6 +95,7 @@
else if (oflags & O_APPEND)
fp->_flags |= __SAPP;
fp->_fileno = fd;
+ fp->_fileno_short = (unsigned)fd > SHRT_MAX ? -1 : fd;
fp->_cookie = fp;
fp->_read = __sread;
fp->_write = __swrite;
diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c
--- a/lib/libc/stdio/findfp.c
+++ b/lib/libc/stdio/findfp.c
@@ -53,6 +53,7 @@
#define std(flags, file) { \
._flags = (flags), \
._fileno = (file), \
+ ._fileno_short = (file), \
._cookie = __sF + (file), \
._close = __sclose, \
._read = __sread, \
@@ -146,6 +147,7 @@
fp->_bf._size = 0;
fp->_lbfsize = 0; /* not line buffered */
fp->_fileno = -1; /* no file */
+ fp->_fileno_short = -1; /* no file */
/* fp->_cookie = <any>; */ /* caller sets cookie, _read/_write etc */
fp->_ub._base = NULL; /* no ungetc buffer */
fp->_ub._size = 0;
diff --git a/lib/libc/stdio/fopen.c b/lib/libc/stdio/fopen.c
--- a/lib/libc/stdio/fopen.c
+++ b/lib/libc/stdio/fopen.c
@@ -59,20 +59,8 @@
fp->_flags = 0; /* release */
return (NULL);
}
- /*
- * File descriptors are a full int, but _fileno is only a short.
- * If we get a valid file descriptor that is greater than
- * SHRT_MAX, then the fd will get sign-extended into an
- * invalid file descriptor. Handle this case by failing the
- * open.
- */
- if (f > SHRT_MAX) {
- fp->_flags = 0; /* release */
- _close(f);
- errno = EMFILE;
- return (NULL);
- }
fp->_fileno = f;
+ fp->_fileno_short = (unsigned)f > SHRT_MAX ? -1 : f;
fp->_flags = flags;
fp->_cookie = fp;
fp->_read = __sread;
diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c
--- a/lib/libc/stdio/freopen.c
+++ b/lib/libc/stdio/freopen.c
@@ -212,22 +212,9 @@
(void)_close(fp->_fileno);
}
- /*
- * File descriptors are a full int, but _fileno is only a short.
- * If we get a valid file descriptor that is greater than
- * SHRT_MAX, then the fd will get sign-extended into an
- * invalid file descriptor. Handle this case by failing the
- * open.
- */
- if (f > SHRT_MAX) {
- fp->_flags = 0; /* set it free */
- errno = EMFILE;
- fp = NULL;
- goto end;
- }
-
fp->_flags = flags;
fp->_fileno = f;
+ fp->_fileno_short = (unsigned)f > SHRT_MAX ? -1 : f;
fp->_cookie = fp;
fp->_read = __sread;
fp->_write = __swrite;
diff --git a/lib/libc/stdio/funopen.c b/lib/libc/stdio/funopen.c
--- a/lib/libc/stdio/funopen.c
+++ b/lib/libc/stdio/funopen.c
@@ -63,6 +63,7 @@
return (NULL);
fp->_flags = flags;
fp->_fileno = -1;
+ fp->_fileno_short = -1;
fp->_cookie = (void *)cookie;
fp->_read = readfn;
fp->_write = writefn;
diff --git a/lib/libc/stdio/local.h b/lib/libc/stdio/local.h
--- a/lib/libc/stdio/local.h
+++ b/lib/libc/stdio/local.h
@@ -129,6 +129,7 @@
*/
#define FAKE_FILE { \
._fileno = -1, \
+ ._fileno_short = -1, \
._fl_mutex = PTHREAD_MUTEX_INITIALIZER, \
}
diff --git a/lib/libc/stdio/vdprintf.c b/lib/libc/stdio/vdprintf.c
--- a/lib/libc/stdio/vdprintf.c
+++ b/lib/libc/stdio/vdprintf.c
@@ -33,6 +33,7 @@
#include "namespace.h"
#include <errno.h>
+#include <fcntl.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
@@ -47,17 +48,27 @@
FILE f = FAKE_FILE;
unsigned char buf[BUFSIZ];
int serrno = errno;
- int ret;
+ int ret, fdflags;
- if (fd > SHRT_MAX) {
- errno = EMFILE;
- return (EOF);
+ if (fd < 0) {
+ errno = EBADF;
+ return (-1);
+ }
+
+ /* Ensure descriptor has been opened for writing */
+ if ((fdflags = _fcntl(fd, F_GETFL, 0)) == -1)
+ return (-1);
+ fdflags &= (O_ACCMODE | O_EXEC);
+ if (fdflags != O_RDWR && fdflags != O_WRONLY) {
+ errno = EINVAL;
+ return (-1);
}
f._p = buf;
f._w = sizeof(buf);
f._flags = __SWR;
f._fileno = fd;
+ f._fileno_short = (unsigned)fd > SHRT_MAX ? -1 : fd;
f._cookie = &f;
f._write = __swrite;
f._bf._base = buf;
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -183,6 +183,7 @@
/* copy the important variables */
fake._flags = fp->_flags & ~__SNBF;
fake._fileno = fp->_fileno;
+ fake._fileno_short = fp->_fileno_short;
fake._cookie = fp->_cookie;
fake._write = fp->_write;
fake._orientation = fp->_orientation;
diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c
--- a/lib/libc/stdio/vfwprintf.c
+++ b/lib/libc/stdio/vfwprintf.c
@@ -219,6 +219,7 @@
/* copy the important variables */
fake._flags = fp->_flags & ~__SNBF;
fake._fileno = fp->_fileno;
+ fake._fileno_short = fp->_fileno_short;
fake._cookie = fp->_cookie;
fake._write = fp->_write;
fake._orientation = fp->_orientation;
diff --git a/lib/libc/stdio/xprintf.c b/lib/libc/stdio/xprintf.c
--- a/lib/libc/stdio/xprintf.c
+++ b/lib/libc/stdio/xprintf.c
@@ -576,6 +576,7 @@
/* copy the important variables */
fake._flags = fp->_flags & ~__SNBF;
fake._fileno = fp->_fileno;
+ fake._fileno_short = fp->_fileno_short;
fake._cookie = fp->_cookie;
fake._write = fp->_write;
fake._orientation = fp->_orientation;

File Metadata

Mime Type
text/plain
Expires
Mon, Jul 20, 2:45 AM (1 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35261777
Default Alt Text
D54355.diff (6 KB)

Event Timeline