diff --git a/include/stdio.h b/include/stdio.h index a5de1de13530..a8aaf6da41cb 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -70,6 +70,12 @@ struct __sbuf { struct __file_lock; +/* hold a buncha junk that would grow the ABI */ +struct __sFILEX { + struct __file_lock *_mtlock; /* used for MT-safety */ + unsigned char *_up; /* saved _p when _p is doing ungetc data */ +}; + /* * stdio state variables. * @@ -114,7 +120,7 @@ typedef struct __sFILE { /* separate buffer for long sequences of ungetc() */ struct __sbuf _ub; /* ungetc buffer */ - unsigned char *_up; /* saved _p when _p is doing ungetc data */ + struct __sFILEX *_extra; /* additions to FILE to not break ABI */ int _ur; /* saved _r when _r is counting ungetc data */ /* tricks to meet minimum requirements even when malloc() fails */ @@ -127,13 +133,10 @@ typedef struct __sFILE { /* Unix stdio files get aligned to block boundaries on fseek() */ int _blksize; /* stat.st_blksize (may be != _bf._size) */ fpos_t _offset; /* current lseek offset (see WARNING) */ - struct __file_lock *_lock; /* used for MT-safety */ } FILE; __BEGIN_DECLS -extern FILE __stdin; -extern FILE __stdout; -extern FILE __stderr; +extern FILE __sF[]; __END_DECLS #define __SLBF 0x0001 /* line buffered */ @@ -196,9 +199,9 @@ __END_DECLS #define SEEK_END 2 /* set file offset to EOF plus offset */ #endif -#define stdin (&__stdin) -#define stdout (&__stdout) -#define stderr (&__stderr) +#define stdin (&__sF[0]) +#define stdout (&__sF[1]) +#define stderr (&__sF[2]) /* * Functions defined in ANSI C standard. diff --git a/lib/libc/Makefile b/lib/libc/Makefile index 3b6ea2ae02be..cdb5011c3571 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -7,7 +7,7 @@ # from CFLAGS below. To remove these strings from just the system call # stubs, remove just -DSYSLIBC_RCS from CFLAGS. LIB=c -SHLIB_MAJOR= 5.20010213 +SHLIB_MAJOR= 5 SHLIB_MINOR= 0 CFLAGS+=-DLIBC_RCS -DSYSLIBC_RCS -I${.CURDIR}/include AINC= -I${.CURDIR}/${MACHINE_ARCH} diff --git a/lib/libc/stdio/_flock_stub.c b/lib/libc/stdio/_flock_stub.c index 8bea66de5724..a77fad982242 100644 --- a/lib/libc/stdio/_flock_stub.c +++ b/lib/libc/stdio/_flock_stub.c @@ -67,6 +67,16 @@ struct __file_lock { int fl_count; /* recursive lock count */ }; +/* + * We need to retain binary compatibility for a while. So pretend + * that _lock is part of FILE * even though it is dereferenced off + * _extra now. When we stop encoding the size of FILE into binaries + * this can be changed in stdio.h. This will reduce the amount of + * code that has to change in the future (just remove this comment + * and #define). + */ +#define _lock _extra->_mtlock + /* * Allocate and initialize a file lock. */ diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c index 48eb5b525997..e0f0e296508e 100644 --- a/lib/libc/stdio/findfp.c +++ b/lib/libc/stdio/findfp.c @@ -59,21 +59,24 @@ int __sdidinit; #define NDYNAMIC 10 /* add ten more whenever necessary */ -#define std(handle, flags, file) \ -FILE handle = {0,0,0,flags,file,{0},0,&handle,__sclose,__sread,__sseek,__swrite} -/* p r w flags file _bf z cookie close read seek write */ - +#define std(flags, file) \ + {0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite, \ + {0}, __sFX + file} + /* p r w flags file _bf z cookie close read seek write */ + /* _ub _extra */ /* the usual - (stdin + stdout + stderr) */ static FILE usual[FOPEN_MAX - 3]; static struct glue uglue = { NULL, FOPEN_MAX - 3, usual }; -std(__stdin, __SRD, STDIN_FILENO); -std(__stdout, __SWR, STDOUT_FILENO); -std(__stderr, __SWR|__SNBF, STDERR_FILENO); +static struct __sFILEX __sFX[3]; -static struct glue sglue2 = { &uglue, 1, &__stderr }; -static struct glue sglue1 = { &sglue2, 1, &__stdout }; -struct glue __sglue = { &sglue1, 1, &__stdin }; +FILE __sF[3] = { + std(__SRD, STDIN_FILENO), + std(__SWR, STDOUT_FILENO), + std(__SWR|__SNBF, STDERR_FILENO) +}; + +struct glue __sglue = { &uglue, 3, __sF }; static struct glue *lastglue = &uglue; static struct glue * moreglue __P((int)); @@ -93,18 +96,26 @@ moreglue(n) int n; { struct glue *g; - FILE *p; static FILE empty; + static struct __sFILEX emptyx; + FILE *p; + struct __sFILEX *fx; - g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)); + g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE) + + n * sizeof(struct __sFILEX)); if (g == NULL) return (NULL); p = (FILE *)ALIGN(g + 1); + fx = (struct __sFILEX *)&p[n]; g->next = NULL; g->niobs = n; g->iobs = p; - while (--n >= 0) - *p++ = empty; + while (--n >= 0) { + *p = empty; + p->_extra = fx; + *p->_extra = emptyx; + p++, fx++; + } return (g); } diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c index f87397552a75..b4343501e6db 100644 --- a/lib/libc/stdio/fseek.c +++ b/lib/libc/stdio/fseek.c @@ -204,7 +204,7 @@ _fseeko(fp, offset, whence) */ if (HASUB(fp)) { curoff += fp->_r; /* kill off ungetc */ - n = fp->_up - fp->_bf._base; + n = fp->_extra->_up - fp->_bf._base; curoff -= n; n += fp->_ur; } else { diff --git a/lib/libc/stdio/refill.c b/lib/libc/stdio/refill.c index b597f97cd919..2adb3a73bf49 100644 --- a/lib/libc/stdio/refill.c +++ b/lib/libc/stdio/refill.c @@ -109,7 +109,7 @@ __srefill(FILE *fp) if (HASUB(fp)) { FREEUB(fp); if ((fp->_r = fp->_ur) != 0) { - fp->_p = fp->_up; + fp->_p = fp->_extra->_up; return (0); } } diff --git a/lib/libc/stdio/ungetc.c b/lib/libc/stdio/ungetc.c index 872abadc6817..f70fb425bb17 100644 --- a/lib/libc/stdio/ungetc.c +++ b/lib/libc/stdio/ungetc.c @@ -164,7 +164,7 @@ __ungetc(int c, FILE *fp) * Initially, we will use the `reserve' buffer. */ fp->_ur = fp->_r; - fp->_up = fp->_p; + fp->_extra->_up = fp->_p; fp->_ub._base = fp->_ubuf; fp->_ub._size = sizeof(fp->_ubuf); fp->_ubuf[sizeof(fp->_ubuf) - 1] = c;