Index: include/stdio.h =================================================================== --- include/stdio.h (revision 241096) +++ include/stdio.h (working copy) @@ -112,7 +112,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 _file; /* (*) fileno, if Unix descriptor, else -1 */ + short _ofile; /* (*) compat fileno for old binaries */ struct __sbuf _bf; /* (*) the buffer (at least 1 byte, if !NULL) */ int _lbfsize; /* (*) 0 or -_bf._size, for inline putc */ @@ -144,6 +144,9 @@ int _fl_count; /* recursive lock count */ int _orientation; /* orientation for fwide() */ __mbstate_t _mbstate; /* multibyte conversion state */ +#ifdef STDIO_INTERNALS + int _file; /* fileno, if Unix descriptor, else -1 */ +#endif }; #ifndef _STDFILE_DECLARED #define _STDFILE_DECLARED @@ -481,17 +484,12 @@ #define __sfeof(p) (((p)->_flags & __SEOF) != 0) #define __sferror(p) (((p)->_flags & __SERR) != 0) #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) -#define __sfileno(p) ((p)->_file) #define feof(p) (!__isthreaded ? __sfeof(p) : (feof)(p)) #define ferror(p) (!__isthreaded ? __sferror(p) : (ferror)(p)) #define clearerr(p) (!__isthreaded ? __sclearerr(p) : (clearerr)(p)) -#if __POSIX_VISIBLE -#define fileno(p) (!__isthreaded ? __sfileno(p) : (fileno)(p)) -#endif - #define getc(fp) (!__isthreaded ? __sgetc(fp) : (getc)(fp)) #define putc(x, fp) (!__isthreaded ? __sputc(x, fp) : (putc)(x, fp)) @@ -506,7 +504,6 @@ #define feof_unlocked(p) __sfeof(p) #define ferror_unlocked(p) __sferror(p) #define clearerr_unlocked(p) __sclearerr(p) -#define fileno_unlocked(p) __sfileno(p) #endif #if __POSIX_VISIBLE >= 199506 #define getc_unlocked(fp) __sgetc(fp) Index: lib/libc/stdio/Symbol.map =================================================================== --- lib/libc/stdio/Symbol.map (revision 241096) +++ lib/libc/stdio/Symbol.map (working copy) @@ -10,7 +10,6 @@ clearerr; fclose; fcloseall; - fdopen; feof; ferror; fflush; @@ -27,7 +26,6 @@ __stdoutp; __stderrp; f_prealloc; /* deprecated??? */ - fopen; fprintf; fpurge; fputc; @@ -35,7 +33,6 @@ fputwc; fputws; fread; - freopen; fscanf; fseek; fseeko; @@ -118,6 +115,9 @@ }; FBSD_1.3 { + fdopen; + fopen; + freopen; asprintf_l; fprintf_l; fwprintf_l; Index: lib/libc/stdio/Makefile.inc =================================================================== --- lib/libc/stdio/Makefile.inc (revision 241096) +++ lib/libc/stdio/Makefile.inc (working copy) @@ -4,6 +4,8 @@ # stdio sources .PATH: ${.CURDIR}/stdio +CFLAGS+= -DSTDIO_INTERNALS + SRCS+= _flock_stub.c asprintf.c clrerr.c dprintf.c \ fclose.c fcloseall.c fdopen.c \ feof.c ferror.c fflush.c fgetc.c fgetln.c fgetpos.c fgets.c fgetwc.c \ Index: lib/libc/stdio/freopen.c =================================================================== --- lib/libc/stdio/freopen.c (revision 241096) +++ lib/libc/stdio/freopen.c (working copy) @@ -54,11 +54,12 @@ * ANSI is written such that the original file gets closed if at * all possible, no matter what. */ -FILE * -freopen(file, mode, fp) +static FILE * +freopen_internal(file, mode, fp, ofile) const char * __restrict file; const char * __restrict mode; FILE *fp; + int ofile; { int f; int dflags, flags, isopen, oflags, sverrno, wantfd; @@ -202,13 +203,13 @@ } /* - * File descriptors are a full int, but _file is only a short. + * File descriptors are a full int, but _ofile 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) { + if (f > SHRT_MAX && ofile) { fp->_flags = 0; /* set it free */ FUNLOCKFILE(fp); errno = EMFILE; @@ -217,6 +218,10 @@ fp->_flags = flags; fp->_file = f; + if (f > SHRT_MAX) + fp->_ofile = -1; + else + fp->_ofile = f; fp->_cookie = fp; fp->_read = __sread; fp->_write = __swrite; @@ -235,3 +240,25 @@ FUNLOCKFILE(fp); return (fp); } + +FILE * +freopen(file, mode, fp) + const char * __restrict file; + const char * __restrict mode; + FILE *fp; +{ + + return (freopen_internal(file, mode, fp, 0)); +} + +FILE * +freopen_ofile(file, mode, fp) + const char * __restrict file; + const char * __restrict mode; + FILE *fp; +{ + + return (freopen_internal(file, mode, fp, 1)); +} + +__sym_compat(freopen, freopen_ofile, FBSD_1.0); Index: lib/libc/stdio/vfwprintf.c =================================================================== --- lib/libc/stdio/vfwprintf.c (revision 241096) +++ lib/libc/stdio/vfwprintf.c (working copy) @@ -215,7 +215,7 @@ __sbprintf(FILE *fp, locale_t locale, const wchar_t *fmt, va_list ap) { int ret; - FILE fake; + FILE fake = FAKE_FILE; unsigned char buf[BUFSIZ]; /* XXX This is probably not needed. */ Index: lib/libc/stdio/vdprintf.c =================================================================== --- lib/libc/stdio/vdprintf.c (revision 241096) +++ lib/libc/stdio/vdprintf.c (working copy) @@ -49,11 +49,6 @@ unsigned char buf[BUFSIZ]; int ret; - if (fd > SHRT_MAX) { - errno = EMFILE; - return (EOF); - } - f._p = buf; f._w = sizeof(buf); f._flags = __SWR; Index: lib/libc/stdio/local.h =================================================================== --- lib/libc/stdio/local.h (revision 241096) +++ lib/libc/stdio/local.h (working copy) @@ -128,6 +128,7 @@ #define FAKE_FILE { \ ._file = -1, \ ._fl_mutex = PTHREAD_MUTEX_INITIALIZER, \ + ._ofile = -1, \ } /* Index: lib/libc/stdio/fopen.c =================================================================== --- lib/libc/stdio/fopen.c (revision 241096) +++ lib/libc/stdio/fopen.c (working copy) @@ -48,10 +48,11 @@ #include "local.h" -FILE * -fopen(file, mode) +static FILE * +fopen_internal(file, mode, ofile) const char * __restrict file; const char * __restrict mode; + int ofile; { FILE *fp; int f; @@ -66,19 +67,23 @@ return (NULL); } /* - * File descriptors are a full int, but _file is only a short. + * File descriptors are a full int, but _ofile 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) { + if (f > SHRT_MAX && ofile) { fp->_flags = 0; /* release */ _close(f); errno = EMFILE; return (NULL); } fp->_file = f; + if (f > SHRT_MAX) + fp->_ofile = -1; + else + fp->_ofile = f; fp->_flags = flags; fp->_cookie = fp; fp->_read = __sread; @@ -97,3 +102,23 @@ (void)_sseek(fp, (fpos_t)0, SEEK_END); return (fp); } + +FILE * +fopen(file, mode) + const char * __restrict file; + const char * __restrict mode; +{ + + return (fopen_internal(file, mode, 0)); +} + +FILE * +fopen_ofile(file, mode) + const char * __restrict file; + const char * __restrict mode; +{ + + return (fopen_internal(file, mode, 1)); +} + +__sym_compat(fopen, fopen_ofile, FBSD_1.0); Index: lib/libc/stdio/fclose.c =================================================================== --- lib/libc/stdio/fclose.c (revision 241096) +++ lib/libc/stdio/fclose.c (working copy) @@ -65,6 +65,7 @@ if (HASLB(fp)) FREELB(fp); fp->_file = -1; + fp->_ofile = -1; fp->_r = fp->_w = 0; /* Mess up if reaccessed. */ /* Index: lib/libc/stdio/findfp.c =================================================================== --- lib/libc/stdio/findfp.c (revision 241096) +++ lib/libc/stdio/findfp.c (working copy) @@ -56,6 +56,7 @@ #define std(flags, file) { \ ._flags = (flags), \ ._file = (file), \ + ._ofile = (file), \ ._cookie = __sF + (file), \ ._close = __sclose, \ ._read = __sread, \ @@ -148,6 +149,7 @@ fp->_bf._size = 0; fp->_lbfsize = 0; /* not line buffered */ fp->_file = -1; /* no file */ + fp->_ofile = -1; /* fp->_cookie = ; */ /* caller sets cookie, _read/_write etc */ fp->_ub._base = NULL; /* no ungetc buffer */ fp->_ub._size = 0; Index: lib/libc/stdio/fdopen.c =================================================================== --- lib/libc/stdio/fdopen.c (revision 241096) +++ lib/libc/stdio/fdopen.c (working copy) @@ -54,18 +54,6 @@ FILE *fp; int flags, oflags, fdflags, tmp; - /* - * File descriptors are a full int, but _file 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 ((flags = __sflags(mode, &oflags)) == 0) return (NULL); @@ -89,6 +77,10 @@ if ((oflags & O_APPEND) && !(fdflags & O_APPEND)) fp->_flags |= __SAPP; fp->_file = fd; + if (fd > SHRT_MAX) + fp->_ofile = -1; + else + fp->_ofile = fd; fp->_cookie = fp; fp->_read = __sread; fp->_write = __swrite; @@ -96,3 +88,25 @@ fp->_close = __sclose; return (fp); } + +FILE * +fdopen_ofile(fd, mode) + int fd; + const char *mode; +{ + + /* + * File descriptors are a full int, but _ofile 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); + } + return (fdopen(fd, mode)); +} + +__sym_compat(fdopen, fdopen_ofile, FBSD_1.0); Index: lib/libc/stdio/fileno.c =================================================================== --- lib/libc/stdio/fileno.c (revision 241096) +++ lib/libc/stdio/fileno.c (working copy) @@ -50,7 +50,7 @@ int fd; FLOCKFILE(fp); - fd = __sfileno(fp); + fd = fp->_file; FUNLOCKFILE(fp); return (fd); @@ -60,5 +60,5 @@ fileno_unlocked(FILE *fp) { - return (__sfileno(fp)); + return (fp->_file); } Index: lib/libc/stdio/funopen.c =================================================================== --- lib/libc/stdio/funopen.c (revision 241096) +++ lib/libc/stdio/funopen.c (working copy) @@ -67,6 +67,7 @@ return (NULL); fp->_flags = flags; fp->_file = -1; + fp->_ofile = -1; fp->_cookie = (void *)cookie; fp->_read = readfn; fp->_write = writefn;