mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-22 02:37:15 +00:00
Next stage of stdio cleanup: Retire __sFILEX and merge the fields back into
__sFILE. This was supposed to be done in 6.0. Some notes: - Where possible I restored the various lines to their pre-__sFILEX state. - Retire INITEXTRA() and just initialize the wchar bits (orientation and mbstate) explicitly instead. The various places that used INITEXTRA didn't need the locking fields or _up initialized. (Some places needed _up to exist and not be off the end of a NULL or garbage pointer, but they didn't require it to be initialized to a specific value.) - For now, stdio.h "knows" that pthread_t is a 'struct pthread *' to avoid namespace pollution of including all the pthread types in stdio.h. Once we remove all the inlines and make __sFILE private it can go back to using pthread_t, etc. - This does not remove any of the inlines currently and does not change any of the public ABI of 'FILE'. MFC after: 1 month Reviewed by: peter
This commit is contained in:
parent
aba7c5b84b
commit
1e98f88776
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=178287
|
@ -72,9 +72,6 @@ struct __sbuf {
|
||||||
int _size;
|
int _size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* hold a buncha junk that would grow the ABI */
|
|
||||||
struct __sFILEX;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* stdio state variables.
|
* stdio state variables.
|
||||||
*
|
*
|
||||||
|
@ -121,7 +118,7 @@ typedef struct __sFILE {
|
||||||
|
|
||||||
/* separate buffer for long sequences of ungetc() */
|
/* separate buffer for long sequences of ungetc() */
|
||||||
struct __sbuf _ub; /* ungetc buffer */
|
struct __sbuf _ub; /* ungetc buffer */
|
||||||
struct __sFILEX *_extra; /* additions to FILE to not break ABI */
|
unsigned char *_up; /* saved _p when _p is doing ungetc data */
|
||||||
int _ur; /* saved _r when _r is counting ungetc data */
|
int _ur; /* saved _r when _r is counting ungetc data */
|
||||||
|
|
||||||
/* tricks to meet minimum requirements even when malloc() fails */
|
/* tricks to meet minimum requirements even when malloc() fails */
|
||||||
|
@ -134,6 +131,12 @@ typedef struct __sFILE {
|
||||||
/* Unix stdio files get aligned to block boundaries on fseek() */
|
/* Unix stdio files get aligned to block boundaries on fseek() */
|
||||||
int _blksize; /* stat.st_blksize (may be != _bf._size) */
|
int _blksize; /* stat.st_blksize (may be != _bf._size) */
|
||||||
fpos_t _offset; /* current lseek offset */
|
fpos_t _offset; /* current lseek offset */
|
||||||
|
|
||||||
|
struct pthread_mutex *_fl_mutex; /* used for MT-safety */
|
||||||
|
struct pthread *_fl_owner; /* current owner */
|
||||||
|
int _fl_count; /* recursive lock count */
|
||||||
|
int _orientation; /* orientation for fwide() */
|
||||||
|
__mbstate_t _mbstate; /* multibyte conversion state */
|
||||||
} FILE;
|
} FILE;
|
||||||
|
|
||||||
#ifndef _STDSTREAM_DECLARED
|
#ifndef _STDSTREAM_DECLARED
|
||||||
|
|
|
@ -55,31 +55,21 @@ __weak_reference(_flockfile_debug_stub, _flockfile_debug);
|
||||||
__weak_reference(_ftrylockfile, ftrylockfile);
|
__weak_reference(_ftrylockfile, ftrylockfile);
|
||||||
__weak_reference(_funlockfile, funlockfile);
|
__weak_reference(_funlockfile, funlockfile);
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_flockfile(FILE *fp)
|
_flockfile(FILE *fp)
|
||||||
{
|
{
|
||||||
pthread_t curthread = _pthread_self();
|
pthread_t curthread = _pthread_self();
|
||||||
|
|
||||||
if (fp->_lock->fl_owner == curthread)
|
if (fp->_fl_owner == curthread)
|
||||||
fp->_lock->fl_count++;
|
fp->_fl_count++;
|
||||||
else {
|
else {
|
||||||
/*
|
/*
|
||||||
* Make sure this mutex is treated as a private
|
* Make sure this mutex is treated as a private
|
||||||
* internal mutex:
|
* internal mutex:
|
||||||
*/
|
*/
|
||||||
_pthread_mutex_lock(&fp->_lock->fl_mutex);
|
_pthread_mutex_lock(&fp->_fl_mutex);
|
||||||
fp->_lock->fl_owner = curthread;
|
fp->_fl_owner = curthread;
|
||||||
fp->_lock->fl_count = 1;
|
fp->_fl_count = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,15 +88,15 @@ _ftrylockfile(FILE *fp)
|
||||||
pthread_t curthread = _pthread_self();
|
pthread_t curthread = _pthread_self();
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (fp->_lock->fl_owner == curthread)
|
if (fp->_fl_owner == curthread)
|
||||||
fp->_lock->fl_count++;
|
fp->_fl_count++;
|
||||||
/*
|
/*
|
||||||
* Make sure this mutex is treated as a private
|
* Make sure this mutex is treated as a private
|
||||||
* internal mutex:
|
* internal mutex:
|
||||||
*/
|
*/
|
||||||
else if (_pthread_mutex_trylock(&fp->_lock->fl_mutex) == 0) {
|
else if (_pthread_mutex_trylock(&fp->_fl_mutex) == 0) {
|
||||||
fp->_lock->fl_owner = curthread;
|
fp->_fl_owner = curthread;
|
||||||
fp->_lock->fl_count = 1;
|
fp->_fl_count = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
@ -121,26 +111,26 @@ _funlockfile(FILE *fp)
|
||||||
/*
|
/*
|
||||||
* Check if this file is owned by the current thread:
|
* Check if this file is owned by the current thread:
|
||||||
*/
|
*/
|
||||||
if (fp->_lock->fl_owner == curthread) {
|
if (fp->_fl_owner == curthread) {
|
||||||
/*
|
/*
|
||||||
* Check if this thread has locked the FILE
|
* Check if this thread has locked the FILE
|
||||||
* more than once:
|
* more than once:
|
||||||
*/
|
*/
|
||||||
if (fp->_lock->fl_count > 1)
|
if (fp->_fl_count > 1)
|
||||||
/*
|
/*
|
||||||
* Decrement the count of the number of
|
* Decrement the count of the number of
|
||||||
* times the running thread has locked this
|
* times the running thread has locked this
|
||||||
* file:
|
* file:
|
||||||
*/
|
*/
|
||||||
fp->_lock->fl_count--;
|
fp->_fl_count--;
|
||||||
else {
|
else {
|
||||||
/*
|
/*
|
||||||
* The running thread will release the
|
* The running thread will release the
|
||||||
* lock now:
|
* lock now:
|
||||||
*/
|
*/
|
||||||
fp->_lock->fl_count = 0;
|
fp->_fl_count = 0;
|
||||||
fp->_lock->fl_owner = NULL;
|
fp->_fl_owner = NULL;
|
||||||
_pthread_mutex_unlock(&fp->_lock->fl_mutex);
|
_pthread_mutex_unlock(&fp->_fl_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ asprintf(char **str, char const *fmt, ...)
|
||||||
int ret;
|
int ret;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
FILE f;
|
FILE f;
|
||||||
struct __sFILEX ext;
|
|
||||||
|
|
||||||
f._file = -1;
|
f._file = -1;
|
||||||
f._flags = __SWR | __SSTR | __SALC;
|
f._flags = __SWR | __SSTR | __SALC;
|
||||||
|
@ -54,8 +53,8 @@ asprintf(char **str, char const *fmt, ...)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
f._bf._size = f._w = 127; /* Leave room for the NUL */
|
f._bf._size = f._w = 127; /* Leave room for the NUL */
|
||||||
f._extra = &ext;
|
f._orientation = 0;
|
||||||
INITEXTRA(&f);
|
memset(&f._mbstate, 0, sizeof(mbstate_t));
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
ret = __vfprintf(&f, fmt, ap); /* Use unlocked __vfprintf */
|
ret = __vfprintf(&f, fmt, ap); /* Use unlocked __vfprintf */
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
|
@ -71,7 +71,7 @@ __fgetwc(FILE *fp)
|
||||||
return (wc);
|
return (wc);
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_extra->mbstate);
|
nconv = __mbrtowc(&wc, fp->_p, fp->_r, &fp->_mbstate);
|
||||||
if (nconv == (size_t)-1)
|
if (nconv == (size_t)-1)
|
||||||
break;
|
break;
|
||||||
else if (nconv == (size_t)-2)
|
else if (nconv == (size_t)-2)
|
||||||
|
|
|
@ -62,7 +62,7 @@ fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp)
|
||||||
nl = memchr(fp->_p, '\n', fp->_r);
|
nl = memchr(fp->_p, '\n', fp->_r);
|
||||||
nconv = __mbsnrtowcs(wsp, &src,
|
nconv = __mbsnrtowcs(wsp, &src,
|
||||||
nl != NULL ? (nl - fp->_p + 1) : fp->_r,
|
nl != NULL ? (nl - fp->_p + 1) : fp->_r,
|
||||||
n - 1, &fp->_extra->mbstate);
|
n - 1, &fp->_mbstate);
|
||||||
if (nconv == (size_t)-1)
|
if (nconv == (size_t)-1)
|
||||||
/* Conversion error */
|
/* Conversion error */
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -86,7 +86,7 @@ fgetws(wchar_t * __restrict ws, int n, FILE * __restrict fp)
|
||||||
if (wsp == ws)
|
if (wsp == ws)
|
||||||
/* EOF */
|
/* EOF */
|
||||||
goto error;
|
goto error;
|
||||||
if (!__mbsinit(&fp->_extra->mbstate))
|
if (!__mbsinit(&fp->_mbstate))
|
||||||
/* Incomplete character */
|
/* Incomplete character */
|
||||||
goto error;
|
goto error;
|
||||||
*wsp++ = L'\0';
|
*wsp++ = L'\0';
|
||||||
|
|
|
@ -54,36 +54,19 @@ int __sdidinit;
|
||||||
#define NDYNAMIC 10 /* add ten more whenever necessary */
|
#define NDYNAMIC 10 /* add ten more whenever necessary */
|
||||||
|
|
||||||
#define std(flags, file) \
|
#define std(flags, file) \
|
||||||
{0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite, \
|
{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 */
|
/* p r w flags file _bf z cookie close read seek write */
|
||||||
/* _ub _extra */
|
|
||||||
/* the usual - (stdin + stdout + stderr) */
|
/* the usual - (stdin + stdout + stderr) */
|
||||||
static FILE usual[FOPEN_MAX - 3];
|
static FILE usual[FOPEN_MAX - 3];
|
||||||
static struct __sFILEX usual_extra[FOPEN_MAX - 3];
|
|
||||||
static struct glue uglue = { NULL, FOPEN_MAX - 3, usual };
|
static struct glue uglue = { NULL, FOPEN_MAX - 3, usual };
|
||||||
|
|
||||||
static struct __sFILEX __sFX[3];
|
static FILE __sF[3] = {
|
||||||
|
|
||||||
/*
|
|
||||||
* We can't make this 'static' until 6.0-current due to binary
|
|
||||||
* compatibility concerns. This also means we cannot change the
|
|
||||||
* sizeof(FILE) until that time either and must continue to use the
|
|
||||||
* __sFILEX stuff to add to FILE.
|
|
||||||
*/
|
|
||||||
FILE __sF[3] = {
|
|
||||||
std(__SRD, STDIN_FILENO),
|
std(__SRD, STDIN_FILENO),
|
||||||
std(__SWR, STDOUT_FILENO),
|
std(__SWR, STDOUT_FILENO),
|
||||||
std(__SWR|__SNBF, STDERR_FILENO)
|
std(__SWR|__SNBF, STDERR_FILENO)
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* The following kludge is done to ensure enough binary compatibility
|
|
||||||
* with future versions of libc. Or rather it allows us to work with
|
|
||||||
* libraries that have been built with a newer libc that defines these
|
|
||||||
* symbols and expects libc to provide them. We only have need to support
|
|
||||||
* i386 because it is the only "old" system we have deployed.
|
|
||||||
*/
|
|
||||||
FILE *__stdinp = &__sF[0];
|
FILE *__stdinp = &__sF[0];
|
||||||
FILE *__stdoutp = &__sF[1];
|
FILE *__stdoutp = &__sF[1];
|
||||||
FILE *__stderrp = &__sF[2];
|
FILE *__stderrp = &__sF[2];
|
||||||
|
@ -109,25 +92,17 @@ moreglue(n)
|
||||||
{
|
{
|
||||||
struct glue *g;
|
struct glue *g;
|
||||||
static FILE empty;
|
static FILE empty;
|
||||||
static struct __sFILEX emptyx;
|
|
||||||
FILE *p;
|
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)
|
if (g == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
p = (FILE *)ALIGN(g + 1);
|
p = (FILE *)ALIGN(g + 1);
|
||||||
fx = (struct __sFILEX *)&p[n];
|
|
||||||
g->next = NULL;
|
g->next = NULL;
|
||||||
g->niobs = n;
|
g->niobs = n;
|
||||||
g->iobs = p;
|
g->iobs = p;
|
||||||
while (--n >= 0) {
|
while (--n >= 0)
|
||||||
*p = empty;
|
*p++ = empty;
|
||||||
p->_extra = fx;
|
|
||||||
*p->_extra = emptyx;
|
|
||||||
p++, fx++;
|
|
||||||
}
|
|
||||||
return (g);
|
return (g);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,8 +150,8 @@ __sfp()
|
||||||
fp->_lb._base = NULL; /* no line buffer */
|
fp->_lb._base = NULL; /* no line buffer */
|
||||||
fp->_lb._size = 0;
|
fp->_lb._size = 0;
|
||||||
/* fp->_lock = NULL; */ /* once set always set (reused) */
|
/* fp->_lock = NULL; */ /* once set always set (reused) */
|
||||||
fp->_extra->orientation = 0;
|
fp->_orientation = 0;
|
||||||
memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t));
|
memset(&fp->_mbstate, 0, sizeof(mbstate_t));
|
||||||
return (fp);
|
return (fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,17 +204,8 @@ _cleanup()
|
||||||
void
|
void
|
||||||
__sinit()
|
__sinit()
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
|
|
||||||
THREAD_LOCK();
|
|
||||||
if (__sdidinit == 0) {
|
|
||||||
/* Set _extra for the usual suspects. */
|
|
||||||
for (i = 0; i < FOPEN_MAX - 3; i++)
|
|
||||||
usual[i]._extra = &usual_extra[i];
|
|
||||||
|
|
||||||
/* Make sure we clean up on exit. */
|
/* Make sure we clean up on exit. */
|
||||||
__cleanup = _cleanup; /* conservative */
|
__cleanup = _cleanup; /* conservative */
|
||||||
__sdidinit = 1;
|
__sdidinit = 1;
|
||||||
}
|
}
|
||||||
THREAD_UNLOCK();
|
|
||||||
}
|
|
||||||
|
|
|
@ -56,8 +56,7 @@ __fputwc(wchar_t wc, FILE *fp)
|
||||||
*buf = (unsigned char)wc;
|
*buf = (unsigned char)wc;
|
||||||
len = 1;
|
len = 1;
|
||||||
} else {
|
} else {
|
||||||
if ((len = __wcrtomb(buf, wc, &fp->_extra->mbstate)) ==
|
if ((len = __wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) {
|
||||||
(size_t)-1) {
|
|
||||||
fp->_flags |= __SERR;
|
fp->_flags |= __SERR;
|
||||||
return (WEOF);
|
return (WEOF);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ fputws(const wchar_t * __restrict ws, FILE * __restrict fp)
|
||||||
iov.iov_base = buf;
|
iov.iov_base = buf;
|
||||||
do {
|
do {
|
||||||
nbytes = __wcsnrtombs(buf, &ws, SIZE_T_MAX, sizeof(buf),
|
nbytes = __wcsnrtombs(buf, &ws, SIZE_T_MAX, sizeof(buf),
|
||||||
&fp->_extra->mbstate);
|
&fp->_mbstate);
|
||||||
if (nbytes == (size_t)-1)
|
if (nbytes == (size_t)-1)
|
||||||
goto error;
|
goto error;
|
||||||
iov.iov_len = uio.uio_resid = nbytes;
|
iov.iov_len = uio.uio_resid = nbytes;
|
||||||
|
|
|
@ -182,8 +182,8 @@ freopen(file, mode, fp)
|
||||||
if (HASLB(fp))
|
if (HASLB(fp))
|
||||||
FREELB(fp);
|
FREELB(fp);
|
||||||
fp->_lb._size = 0;
|
fp->_lb._size = 0;
|
||||||
fp->_extra->orientation = 0;
|
fp->_orientation = 0;
|
||||||
memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t));
|
memset(&fp->_mbstate, 0, sizeof(mbstate_t));
|
||||||
|
|
||||||
if (f < 0) { /* did not get it after all */
|
if (f < 0) { /* did not get it after all */
|
||||||
fp->_flags = 0; /* set it free */
|
fp->_flags = 0; /* set it free */
|
||||||
|
|
|
@ -233,7 +233,7 @@ _fseeko(fp, offset, whence, ltest)
|
||||||
*/
|
*/
|
||||||
if (HASUB(fp)) {
|
if (HASUB(fp)) {
|
||||||
curoff += fp->_r; /* kill off ungetc */
|
curoff += fp->_r; /* kill off ungetc */
|
||||||
n = fp->_extra->_up - fp->_bf._base;
|
n = fp->_up - fp->_bf._base;
|
||||||
curoff -= n;
|
curoff -= n;
|
||||||
n += fp->_ur;
|
n += fp->_ur;
|
||||||
} else {
|
} else {
|
||||||
|
@ -255,7 +255,7 @@ _fseeko(fp, offset, whence, ltest)
|
||||||
if (HASUB(fp))
|
if (HASUB(fp))
|
||||||
FREEUB(fp);
|
FREEUB(fp);
|
||||||
fp->_flags &= ~__SEOF;
|
fp->_flags &= ~__SEOF;
|
||||||
memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t));
|
memset(&fp->_mbstate, 0, sizeof(mbstate_t));
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,7 +283,7 @@ _fseeko(fp, offset, whence, ltest)
|
||||||
fp->_r -= n;
|
fp->_r -= n;
|
||||||
}
|
}
|
||||||
fp->_flags &= ~__SEOF;
|
fp->_flags &= ~__SEOF;
|
||||||
memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t));
|
memset(&fp->_mbstate, 0, sizeof(mbstate_t));
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -306,6 +306,6 @@ _fseeko(fp, offset, whence, ltest)
|
||||||
fp->_r = 0;
|
fp->_r = 0;
|
||||||
/* fp->_w = 0; */ /* unnecessary (I think...) */
|
/* fp->_w = 0; */ /* unnecessary (I think...) */
|
||||||
fp->_flags &= ~__SEOF;
|
fp->_flags &= ~__SEOF;
|
||||||
memset(&fp->_extra->mbstate, 0, sizeof(mbstate_t));
|
memset(&fp->_mbstate, 0, sizeof(mbstate_t));
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,9 +42,9 @@ fwide(FILE *fp, int mode)
|
||||||
|
|
||||||
FLOCKFILE(fp);
|
FLOCKFILE(fp);
|
||||||
/* Only change the orientation if the stream is not oriented yet. */
|
/* Only change the orientation if the stream is not oriented yet. */
|
||||||
if (mode != 0 && fp->_extra->orientation == 0)
|
if (mode != 0 && fp->_orientation == 0)
|
||||||
fp->_extra->orientation = mode > 0 ? 1 : -1;
|
fp->_orientation = mode > 0 ? 1 : -1;
|
||||||
m = fp->_extra->orientation;
|
m = fp->_orientation;
|
||||||
FUNLOCKFILE(fp);
|
FUNLOCKFILE(fp);
|
||||||
|
|
||||||
return (m);
|
return (m);
|
||||||
|
|
|
@ -80,16 +80,6 @@ extern size_t __fread(void * __restrict buf, size_t size, size_t count,
|
||||||
extern int __sdidinit;
|
extern int __sdidinit;
|
||||||
|
|
||||||
|
|
||||||
/* hold a buncha junk that would grow the ABI */
|
|
||||||
struct __sFILEX {
|
|
||||||
unsigned char *_up; /* saved _p when _p is doing ungetc data */
|
|
||||||
pthread_mutex_t fl_mutex; /* used for MT-safety */
|
|
||||||
pthread_t fl_owner; /* current owner */
|
|
||||||
int fl_count; /* recursive lock count */
|
|
||||||
int orientation; /* orientation for fwide() */
|
|
||||||
mbstate_t mbstate; /* multibyte conversion state */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare the given FILE for writing, and return 0 iff it
|
* Prepare the given FILE for writing, and return 0 iff it
|
||||||
* can be written now. Otherwise, return EOF and set errno.
|
* can be written now. Otherwise, return EOF and set errno.
|
||||||
|
@ -119,20 +109,11 @@ struct __sFILEX {
|
||||||
(fp)->_lb._base = NULL; \
|
(fp)->_lb._base = NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INITEXTRA(fp) { \
|
|
||||||
(fp)->_extra->_up = NULL; \
|
|
||||||
(fp)->_extra->fl_mutex = PTHREAD_MUTEX_INITIALIZER; \
|
|
||||||
(fp)->_extra->fl_owner = NULL; \
|
|
||||||
(fp)->_extra->fl_count = 0; \
|
|
||||||
(fp)->_extra->orientation = 0; \
|
|
||||||
memset(&(fp)->_extra->mbstate, 0, sizeof(mbstate_t)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the orientation for a stream. If o > 0, the stream has wide-
|
* Set the orientation for a stream. If o > 0, the stream has wide-
|
||||||
* orientation. If o < 0, the stream has byte-orientation.
|
* orientation. If o < 0, the stream has byte-orientation.
|
||||||
*/
|
*/
|
||||||
#define ORIENT(fp, o) do { \
|
#define ORIENT(fp, o) do { \
|
||||||
if ((fp)->_extra->orientation == 0) \
|
if ((fp)->_orientation == 0) \
|
||||||
(fp)->_extra->orientation = (o); \
|
(fp)->_orientation = (o); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
|
@ -106,7 +106,7 @@ __srefill(FILE *fp)
|
||||||
if (HASUB(fp)) {
|
if (HASUB(fp)) {
|
||||||
FREEUB(fp);
|
FREEUB(fp);
|
||||||
if ((fp->_r = fp->_ur) != 0) {
|
if ((fp->_r = fp->_ur) != 0) {
|
||||||
fp->_p = fp->_extra->_up;
|
fp->_p = fp->_up;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...)
|
||||||
int ret;
|
int ret;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
FILE f;
|
FILE f;
|
||||||
struct __sFILEX ext;
|
|
||||||
|
|
||||||
on = n;
|
on = n;
|
||||||
if (n != 0)
|
if (n != 0)
|
||||||
|
@ -61,8 +60,8 @@ snprintf(char * __restrict str, size_t n, char const * __restrict fmt, ...)
|
||||||
f._flags = __SWR | __SSTR;
|
f._flags = __SWR | __SSTR;
|
||||||
f._bf._base = f._p = (unsigned char *)str;
|
f._bf._base = f._p = (unsigned char *)str;
|
||||||
f._bf._size = f._w = n;
|
f._bf._size = f._w = n;
|
||||||
f._extra = &ext;
|
f._orientation = 0;
|
||||||
INITEXTRA(&f);
|
memset(&f._mbstate, 0, sizeof(mbstate_t));
|
||||||
ret = __vfprintf(&f, fmt, ap);
|
ret = __vfprintf(&f, fmt, ap);
|
||||||
if (on > 0)
|
if (on > 0)
|
||||||
*f._p = '\0';
|
*f._p = '\0';
|
||||||
|
|
|
@ -47,14 +47,13 @@ sprintf(char * __restrict str, char const * __restrict fmt, ...)
|
||||||
int ret;
|
int ret;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
FILE f;
|
FILE f;
|
||||||
struct __sFILEX ext;
|
|
||||||
|
|
||||||
f._file = -1;
|
f._file = -1;
|
||||||
f._flags = __SWR | __SSTR;
|
f._flags = __SWR | __SSTR;
|
||||||
f._bf._base = f._p = (unsigned char *)str;
|
f._bf._base = f._p = (unsigned char *)str;
|
||||||
f._bf._size = f._w = INT_MAX;
|
f._bf._size = f._w = INT_MAX;
|
||||||
f._extra = &ext;
|
f._orientation = 0;
|
||||||
INITEXTRA(&f);
|
memset(&f._mbstate, 0, sizeof(mbstate_t));
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
ret = __vfprintf(&f, fmt, ap);
|
ret = __vfprintf(&f, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
|
@ -59,7 +59,6 @@ sscanf(const char * __restrict str, char const * __restrict fmt, ...)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
struct __sFILEX extra;
|
|
||||||
FILE f;
|
FILE f;
|
||||||
|
|
||||||
f._file = -1;
|
f._file = -1;
|
||||||
|
@ -69,8 +68,8 @@ sscanf(const char * __restrict str, char const * __restrict fmt, ...)
|
||||||
f._read = eofread;
|
f._read = eofread;
|
||||||
f._ub._base = NULL;
|
f._ub._base = NULL;
|
||||||
f._lb._base = NULL;
|
f._lb._base = NULL;
|
||||||
f._extra = &extra;
|
f._orientation = 0;
|
||||||
INITEXTRA(&f);
|
memset(&f._mbstate, 0, sizeof(mbstate_t));
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
ret = __svfscanf(&f, fmt, ap);
|
ret = __svfscanf(&f, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
|
@ -158,7 +158,7 @@ __ungetc(int c, FILE *fp)
|
||||||
* Initially, we will use the `reserve' buffer.
|
* Initially, we will use the `reserve' buffer.
|
||||||
*/
|
*/
|
||||||
fp->_ur = fp->_r;
|
fp->_ur = fp->_r;
|
||||||
fp->_extra->_up = fp->_p;
|
fp->_up = fp->_p;
|
||||||
fp->_ub._base = fp->_ubuf;
|
fp->_ub._base = fp->_ubuf;
|
||||||
fp->_ub._size = sizeof(fp->_ubuf);
|
fp->_ub._size = sizeof(fp->_ubuf);
|
||||||
fp->_ubuf[sizeof(fp->_ubuf) - 1] = c;
|
fp->_ubuf[sizeof(fp->_ubuf) - 1] = c;
|
||||||
|
|
|
@ -49,7 +49,7 @@ __ungetwc(wint_t wc, FILE *fp)
|
||||||
|
|
||||||
if (wc == WEOF)
|
if (wc == WEOF)
|
||||||
return (WEOF);
|
return (WEOF);
|
||||||
if ((len = __wcrtomb(buf, wc, &fp->_extra->mbstate)) == (size_t)-1) {
|
if ((len = __wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) {
|
||||||
fp->_flags |= __SERR;
|
fp->_flags |= __SERR;
|
||||||
return (WEOF);
|
return (WEOF);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ vasprintf(str, fmt, ap)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
FILE f;
|
FILE f;
|
||||||
struct __sFILEX ext;
|
|
||||||
|
|
||||||
f._file = -1;
|
f._file = -1;
|
||||||
f._flags = __SWR | __SSTR | __SALC;
|
f._flags = __SWR | __SSTR | __SALC;
|
||||||
|
@ -54,8 +53,8 @@ vasprintf(str, fmt, ap)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
f._bf._size = f._w = 127; /* Leave room for the NUL */
|
f._bf._size = f._w = 127; /* Leave room for the NUL */
|
||||||
f._extra = &ext;
|
f._orientation = 0;
|
||||||
INITEXTRA(&f);
|
memset(&f._mbstate, 0, sizeof(mbstate_t));
|
||||||
ret = __vfprintf(&f, fmt, ap);
|
ret = __vfprintf(&f, fmt, ap);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(f._bf._base);
|
free(f._bf._base);
|
||||||
|
|
|
@ -149,7 +149,8 @@ __sbprintf(FILE *fp, const char *fmt, va_list ap)
|
||||||
fake._file = fp->_file;
|
fake._file = fp->_file;
|
||||||
fake._cookie = fp->_cookie;
|
fake._cookie = fp->_cookie;
|
||||||
fake._write = fp->_write;
|
fake._write = fp->_write;
|
||||||
fake._extra = fp->_extra;
|
fake._orientation = fp->_orientation;
|
||||||
|
fake._mbstate = fp->_mbstate;
|
||||||
|
|
||||||
/* set up the buffer */
|
/* set up the buffer */
|
||||||
fake._bf._base = fake._p = buf;
|
fake._bf._base = fake._p = buf;
|
||||||
|
|
|
@ -132,7 +132,8 @@ __sbprintf(FILE *fp, const wchar_t *fmt, va_list ap)
|
||||||
fake._file = fp->_file;
|
fake._file = fp->_file;
|
||||||
fake._cookie = fp->_cookie;
|
fake._cookie = fp->_cookie;
|
||||||
fake._write = fp->_write;
|
fake._write = fp->_write;
|
||||||
fake._extra = fp->_extra;
|
fake._orientation = fp->_orientation;
|
||||||
|
fake._mbstate = fp->_mbstate;
|
||||||
|
|
||||||
/* set up the buffer */
|
/* set up the buffer */
|
||||||
fake._bf._base = fake._p = buf;
|
fake._bf._base = fake._p = buf;
|
||||||
|
|
|
@ -48,7 +48,6 @@ vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt,
|
||||||
int ret;
|
int ret;
|
||||||
char dummy[2];
|
char dummy[2];
|
||||||
FILE f;
|
FILE f;
|
||||||
struct __sFILEX ext;
|
|
||||||
|
|
||||||
on = n;
|
on = n;
|
||||||
if (n != 0)
|
if (n != 0)
|
||||||
|
@ -66,8 +65,8 @@ vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt,
|
||||||
f._flags = __SWR | __SSTR;
|
f._flags = __SWR | __SSTR;
|
||||||
f._bf._base = f._p = (unsigned char *)str;
|
f._bf._base = f._p = (unsigned char *)str;
|
||||||
f._bf._size = f._w = n;
|
f._bf._size = f._w = n;
|
||||||
f._extra = &ext;
|
f._orientation = 0;
|
||||||
INITEXTRA(&f);
|
memset(&f._mbstate, 0, sizeof(mbstate_t));
|
||||||
ret = __vfprintf(&f, fmt, ap);
|
ret = __vfprintf(&f, fmt, ap);
|
||||||
if (on > 0)
|
if (on > 0)
|
||||||
*f._p = '\0';
|
*f._p = '\0';
|
||||||
|
|
|
@ -45,14 +45,13 @@ vsprintf(char * __restrict str, const char * __restrict fmt, __va_list ap)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
FILE f;
|
FILE f;
|
||||||
struct __sFILEX ext;
|
|
||||||
|
|
||||||
f._file = -1;
|
f._file = -1;
|
||||||
f._flags = __SWR | __SSTR;
|
f._flags = __SWR | __SSTR;
|
||||||
f._bf._base = f._p = (unsigned char *)str;
|
f._bf._base = f._p = (unsigned char *)str;
|
||||||
f._bf._size = f._w = INT_MAX;
|
f._bf._size = f._w = INT_MAX;
|
||||||
f._extra = &ext;
|
f._orientation = 0;
|
||||||
INITEXTRA(&f);
|
memset(&f._mbstate, 0, sizeof(mbstate_t));
|
||||||
ret = __vfprintf(&f, fmt, ap);
|
ret = __vfprintf(&f, fmt, ap);
|
||||||
*f._p = 0;
|
*f._p = 0;
|
||||||
return (ret);
|
return (ret);
|
||||||
|
|
|
@ -61,7 +61,6 @@ vsscanf(str, fmt, ap)
|
||||||
__va_list ap;
|
__va_list ap;
|
||||||
{
|
{
|
||||||
FILE f;
|
FILE f;
|
||||||
struct __sFILEX ext;
|
|
||||||
|
|
||||||
f._file = -1;
|
f._file = -1;
|
||||||
f._flags = __SRD;
|
f._flags = __SRD;
|
||||||
|
@ -70,7 +69,7 @@ vsscanf(str, fmt, ap)
|
||||||
f._read = eofread;
|
f._read = eofread;
|
||||||
f._ub._base = NULL;
|
f._ub._base = NULL;
|
||||||
f._lb._base = NULL;
|
f._lb._base = NULL;
|
||||||
f._extra = &ext;
|
f._orientation = 0;
|
||||||
INITEXTRA(&f);
|
memset(&f._mbstate, 0, sizeof(mbstate_t));
|
||||||
return (__svfscanf(&f, fmt, ap));
|
return (__svfscanf(&f, fmt, ap));
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
|
||||||
static const mbstate_t initial;
|
static const mbstate_t initial;
|
||||||
mbstate_t mbs;
|
mbstate_t mbs;
|
||||||
FILE f;
|
FILE f;
|
||||||
struct __sFILEX ext;
|
|
||||||
char *mbp;
|
char *mbp;
|
||||||
int ret, sverrno;
|
int ret, sverrno;
|
||||||
size_t nwc;
|
size_t nwc;
|
||||||
|
@ -64,8 +63,8 @@ vswprintf(wchar_t * __restrict s, size_t n, const wchar_t * __restrict fmt,
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
f._bf._size = f._w = 127; /* Leave room for the NUL */
|
f._bf._size = f._w = 127; /* Leave room for the NUL */
|
||||||
f._extra = &ext;
|
f._orientation = 0;
|
||||||
INITEXTRA(&f);
|
memset(&f._mbstate, 0, sizeof(mbstate_t));
|
||||||
ret = __vfwprintf(&f, fmt, ap);
|
ret = __vfwprintf(&f, fmt, ap);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
sverrno = errno;
|
sverrno = errno;
|
||||||
|
|
|
@ -63,7 +63,6 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
|
||||||
static const mbstate_t initial;
|
static const mbstate_t initial;
|
||||||
mbstate_t mbs;
|
mbstate_t mbs;
|
||||||
FILE f;
|
FILE f;
|
||||||
struct __sFILEX ext;
|
|
||||||
char *mbstr;
|
char *mbstr;
|
||||||
size_t mlen;
|
size_t mlen;
|
||||||
int r;
|
int r;
|
||||||
|
@ -86,8 +85,8 @@ vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict fmt,
|
||||||
f._read = eofread;
|
f._read = eofread;
|
||||||
f._ub._base = NULL;
|
f._ub._base = NULL;
|
||||||
f._lb._base = NULL;
|
f._lb._base = NULL;
|
||||||
f._extra = &ext;
|
f._orientation = 0;
|
||||||
INITEXTRA(&f);
|
memset(&f._mbstate, 0, sizeof(mbstate_t));
|
||||||
r = __vfwscanf(&f, fmt, ap);
|
r = __vfwscanf(&f, fmt, ap);
|
||||||
free(mbstr);
|
free(mbstr);
|
||||||
|
|
||||||
|
|
|
@ -583,7 +583,8 @@ __v3printf(FILE *fp, const char *fmt, int pct, va_list ap)
|
||||||
fake._file = fp->_file;
|
fake._file = fp->_file;
|
||||||
fake._cookie = fp->_cookie;
|
fake._cookie = fp->_cookie;
|
||||||
fake._write = fp->_write;
|
fake._write = fp->_write;
|
||||||
fake._extra = fp->_extra;
|
fake._orientation = fp->_orientation;
|
||||||
|
fake._mbstate = fp->_mbstate;
|
||||||
|
|
||||||
/* set up the buffer */
|
/* set up the buffer */
|
||||||
fake._bf._base = fake._p = buf;
|
fake._bf._base = fake._p = buf;
|
||||||
|
|
Loading…
Reference in a new issue