Make stdio deferred cancel-safe.

If used with fopen(3)/fdopen(3)-ed FILEs, stdio accurately uses
non-cancellable internal versions of the functions, i.e. it seems to
be fine with regard to cancellation.  But if the funopen(3) and
f{r,w}open(3) functions were used to open the FILE, and corresponding
user functions create cancellation points (they typically have no
other choice), then stdio code at least leaks FILE' lock.

The change installs cleanup handler which unlocks FILE.  Some minimal
restructuring of the code was required to make it use common return
place to satisfy hand-rolled pthread_cleanup_pop() requirements.

Noted by:	eugen
Reviewed by:	eugen, vangyzen
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
Differential revision:	https://reviews.freebsd.org/D11246
This commit is contained in:
Konstantin Belousov 2017-06-29 14:44:17 +00:00
parent d137278838
commit fda0a14f47
38 changed files with 185 additions and 138 deletions

View File

@ -97,7 +97,7 @@ fdclose(FILE *fp, int *fdp)
return (EOF);
}
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
r = 0;
if (fp->_close != __sclose) {
r = EOF;
@ -115,7 +115,7 @@ fdclose(FILE *fp, int *fdp)
*fdp = fp->_file;
r = cleanfile(fp, false);
}
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (r);
}
@ -130,9 +130,9 @@ fclose(FILE *fp)
return (EOF);
}
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
r = cleanfile(fp, true);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (r);
}

View File

@ -56,7 +56,7 @@ fflush(FILE *fp)
if (fp == NULL)
return (_fwalk(sflush_locked));
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
/*
* There is disagreement about the correct behaviour of fflush()
@ -76,7 +76,7 @@ fflush(FILE *fp)
retval = 0;
else
retval = __sflush(fp);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (retval);
}
@ -143,8 +143,8 @@ sflush_locked(FILE *fp)
{
int ret;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ret = __sflush(fp);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (ret);
}

View File

@ -46,10 +46,10 @@ int
fgetc(FILE *fp)
{
int retval;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
/* Orientation set by __sgetc() when buffer is empty. */
/* ORIENT(fp, -1); */
retval = __sgetc(fp);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (retval);
}

View File

@ -85,22 +85,21 @@ char *
fgetln(FILE *fp, size_t *lenp)
{
unsigned char *p;
char *ret;
size_t len;
size_t off;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, -1);
/* make sure there is input */
if (fp->_r <= 0 && __srefill(fp)) {
*lenp = 0;
FUNLOCKFILE(fp);
return (NULL);
ret = NULL;
goto end;
}
/* look for a newline in the input */
if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) != NULL) {
char *ret;
/*
* Found one. Flag buffer as modified to keep fseek from
* `optimising' a backward seek, in case the user stomps on
@ -112,8 +111,7 @@ fgetln(FILE *fp, size_t *lenp)
fp->_flags |= __SMOD;
fp->_r -= len;
fp->_p = p;
FUNLOCKFILE(fp);
return (ret);
goto end;
}
/*
@ -163,12 +161,14 @@ fgetln(FILE *fp, size_t *lenp)
#ifdef notdef
fp->_lb._base[len] = '\0';
#endif
FUNLOCKFILE(fp);
return ((char *)fp->_lb._base);
ret = (char *)fp->_lb._base;
end:
FUNLOCKFILE_CANCELSAFE();
return (ret);
error:
*lenp = 0; /* ??? */
fp->_flags |= __SERR;
FUNLOCKFILE(fp);
return (NULL); /* ??? */
ret = NULL;
goto end;
}

View File

@ -53,17 +53,17 @@ char *
fgets(char * __restrict buf, int n, FILE * __restrict fp)
{
size_t len;
char *s;
char *s, *ret;
unsigned char *p, *t;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, -1);
if (n <= 0) { /* sanity check */
fp->_flags |= __SERR;
errno = EINVAL;
FUNLOCKFILE(fp);
return (NULL);
ret = NULL;
goto end;
}
s = buf;
@ -76,8 +76,8 @@ fgets(char * __restrict buf, int n, FILE * __restrict fp)
if (__srefill(fp)) {
/* EOF/error: stop with partial or no line */
if (!__sfeof(fp) || s == buf) {
FUNLOCKFILE(fp);
return (NULL);
ret = NULL;
goto end;
}
break;
}
@ -100,8 +100,8 @@ fgets(char * __restrict buf, int n, FILE * __restrict fp)
fp->_p = t;
(void)memcpy((void *)s, (void *)p, len);
s[len] = 0;
FUNLOCKFILE(fp);
return (buf);
ret = buf;
goto end;
}
fp->_r -= len;
fp->_p += len;
@ -110,6 +110,8 @@ fgets(char * __restrict buf, int n, FILE * __restrict fp)
n -= len;
}
*s = 0;
FUNLOCKFILE(fp);
return (buf);
ret = buf;
end:
FUNLOCKFILE_CANCELSAFE();
return (ret);
}

View File

@ -52,10 +52,10 @@ fgetwc_l(FILE *fp, locale_t locale)
wint_t r;
FIX_LOCALE(locale);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, 1);
r = __fgetwc(fp, locale);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (r);
}

View File

@ -45,13 +45,14 @@ wchar_t *fgetwln_l(FILE * __restrict, size_t *, locale_t);
wchar_t *
fgetwln_l(FILE * __restrict fp, size_t *lenp, locale_t locale)
{
wchar_t *ret;
wint_t wc;
size_t len;
int savserr;
FIX_LOCALE(locale);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, 1);
savserr = fp->_flags & __SERR;
@ -77,14 +78,16 @@ fgetwln_l(FILE * __restrict fp, size_t *lenp, locale_t locale)
if (len == 0)
goto error;
FUNLOCKFILE(fp);
*lenp = len;
return ((wchar_t *)fp->_lb._base);
ret = (wchar_t *)fp->_lb._base;
end:
FUNLOCKFILE_CANCELSAFE();
return (ret);
error:
FUNLOCKFILE(fp);
*lenp = 0;
return (NULL);
ret = NULL;
goto end;
}
wchar_t *

View File

@ -46,14 +46,14 @@ wchar_t *
fgetws_l(wchar_t * __restrict ws, int n, FILE * __restrict fp, locale_t locale)
{
int sret;
wchar_t *wsp;
wchar_t *wsp, *ret;
size_t nconv;
const char *src;
unsigned char *nl;
FIX_LOCALE(locale);
struct xlocale_ctype *l = XLOCALE_CTYPE(locale);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, 1);
if (n <= 0) {
@ -113,12 +113,14 @@ fgetws_l(wchar_t * __restrict ws, int n, FILE * __restrict fp, locale_t locale)
goto error;
ok:
*wsp = L'\0';
FUNLOCKFILE(fp);
ret = ws;
end:
FUNLOCKFILE_CANCELSAFE();
return (ws);
error:
FUNLOCKFILE(fp);
return (NULL);
ret = NULL;
goto end;
}
wchar_t *

View File

@ -46,10 +46,10 @@ int
fputc(int c, FILE *fp)
{
int retval;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
/* Orientation set by __sputc() when buffer is full. */
/* ORIENT(fp, -1); */
retval = __sputc(c, fp);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (retval);
}

View File

@ -59,10 +59,10 @@ fputs(const char * __restrict s, FILE * __restrict fp)
uio.uio_resid = iov.iov_len = strlen(s);
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, -1);
retval = __sfvwrite(fp, &uio);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
if (retval == 0)
return (iov.iov_len > INT_MAX ? INT_MAX : iov.iov_len);
return (retval);

View File

@ -74,10 +74,10 @@ fputwc_l(wchar_t wc, FILE *fp, locale_t locale)
wint_t r;
FIX_LOCALE(locale);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, 1);
r = __fputwc(wc, fp, locale);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (r);
}

View File

@ -53,11 +53,13 @@ fputws_l(const wchar_t * __restrict ws, FILE * __restrict fp, locale_t locale)
const wchar_t *wsp;
FIX_LOCALE(locale);
struct xlocale_ctype *l = XLOCALE_CTYPE(locale);
int ret;
FLOCKFILE(fp);
ret = -1;
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, 1);
if (prepwrite(fp) != 0)
goto error;
goto end;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
iov.iov_base = buf;
@ -66,17 +68,15 @@ fputws_l(const wchar_t * __restrict ws, FILE * __restrict fp, locale_t locale)
nbytes = l->__wcsnrtombs(buf, &wsp, SIZE_T_MAX, sizeof(buf),
&fp->_mbstate);
if (nbytes == (size_t)-1)
goto error;
goto end;
uio.uio_resid = iov.iov_len = nbytes;
if (__sfvwrite(fp, &uio) != 0)
goto error;
goto end;
} while (wsp != NULL);
FUNLOCKFILE(fp);
return (0);
error:
FUNLOCKFILE(fp);
return (-1);
ret = 0;
end:
FUNLOCKFILE_CANCELSAFE();
return (ret);
}
int

View File

@ -54,9 +54,9 @@ fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp)
{
size_t ret;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ret = __fread(buf, size, count, fp);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (ret);
}

View File

@ -68,7 +68,7 @@ freopen(const char * __restrict file, const char * __restrict mode,
return (NULL);
}
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
if (!__sdidinit)
__sinit();
@ -81,24 +81,24 @@ freopen(const char * __restrict file, const char * __restrict mode,
if (file == NULL) {
/* See comment below regarding freopen() of closed files. */
if (fp->_flags == 0) {
FUNLOCKFILE(fp);
errno = EINVAL;
return (NULL);
fp = NULL;
goto end;
}
if ((dflags = _fcntl(fp->_file, F_GETFL)) < 0) {
sverrno = errno;
fclose(fp);
FUNLOCKFILE(fp);
errno = sverrno;
return (NULL);
fp = NULL;
goto end;
}
/* Work around incorrect O_ACCMODE. */
if ((dflags & O_ACCMODE) != O_RDWR &&
(dflags & (O_ACCMODE | O_EXEC)) != (oflags & O_ACCMODE)) {
fclose(fp);
FUNLOCKFILE(fp);
errno = EBADF;
return (NULL);
fp = NULL;
goto end;
}
if (fp->_flags & __SWR)
(void) __sflush(fp);
@ -108,9 +108,9 @@ freopen(const char * __restrict file, const char * __restrict mode,
if (_fcntl(fp->_file, F_SETFL, dflags) < 0) {
sverrno = errno;
fclose(fp);
FUNLOCKFILE(fp);
errno = sverrno;
return (NULL);
fp = NULL;
goto end;
}
}
if (oflags & O_TRUNC)
@ -193,9 +193,9 @@ freopen(const char * __restrict file, const char * __restrict mode,
if (isopen)
(void) (*fp->_close)(fp->_cookie);
fp->_flags = 0; /* set it free */
FUNLOCKFILE(fp);
errno = sverrno; /* restore in case _close clobbered */
return (NULL);
fp = NULL;
goto end;
}
/*
@ -221,9 +221,9 @@ freopen(const char * __restrict file, const char * __restrict mode,
*/
if (f > SHRT_MAX) {
fp->_flags = 0; /* set it free */
FUNLOCKFILE(fp);
errno = EMFILE;
return (NULL);
fp = NULL;
goto end;
}
fp->_flags = flags;
@ -245,6 +245,7 @@ freopen(const char * __restrict file, const char * __restrict mode,
fp->_flags2 |= __S2OAP;
(void) _sseek(fp, (fpos_t)0, SEEK_END);
}
FUNLOCKFILE(fp);
end:
FUNLOCKFILE_CANCELSAFE();
return (fp);
}

View File

@ -56,10 +56,10 @@ fscanf(FILE * __restrict fp, char const * __restrict fmt, ...)
va_list ap;
va_start(ap, fmt);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ret = __svfscanf(fp, __get_locale(), fmt, ap);
va_end(ap);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (ret);
}
int
@ -70,9 +70,9 @@ fscanf_l(FILE * __restrict fp, locale_t locale, char const * __restrict fmt, ...
FIX_LOCALE(locale);
va_start(ap, fmt);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ret = __svfscanf(fp, locale, fmt, ap);
va_end(ap);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (ret);
}

View File

@ -60,9 +60,9 @@ fseek(FILE *fp, long offset, int whence)
if (!__sdidinit)
__sinit();
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ret = _fseeko(fp, (off_t)offset, whence, 1);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
if (ret == 0)
errno = serrno;
return (ret);
@ -78,9 +78,9 @@ fseeko(FILE *fp, off_t offset, int whence)
if (!__sdidinit)
__sinit();
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ret = _fseeko(fp, offset, whence, 0);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
if (ret == 0)
errno = serrno;
return (ret);

View File

@ -82,7 +82,7 @@ fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, -1);
/*
* The usual case is success (__sfvwrite returns 0);
@ -91,6 +91,6 @@ fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict
*/
if (__sfvwrite(fp, &uio) != 0)
count = (n - uio.uio_resid) / size;
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (count);
}

View File

@ -49,11 +49,11 @@ int
getc(FILE *fp)
{
int retval;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
/* Orientation set by __sgetc() when buffer is empty. */
/* ORIENT(fp, -1); */
retval = __sgetc(fp);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (retval);
}

View File

@ -52,11 +52,11 @@ int
getchar(void)
{
int retval;
FLOCKFILE(stdin);
FLOCKFILE_CANCELSAFE(stdin);
/* Orientation set by __sgetc() when buffer is empty. */
/* ORIENT(stdin, -1); */
retval = __sgetc(stdin);
FUNLOCKFILE(stdin);
FUNLOCKFILE_CANCELSAFE();
return (retval);
}

View File

@ -112,7 +112,7 @@ getdelim(char ** __restrict linep, size_t * __restrict linecapp, int delim,
u_char *endp;
size_t linelen;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, -1);
if (linep == NULL || linecapp == NULL) {
@ -127,9 +127,9 @@ getdelim(char ** __restrict linep, size_t * __restrict linecapp, int delim,
/* If fp is at EOF already, we just need space for the NUL. */
if (!__sfeof(fp) || expandtofit(linep, 1, linecapp))
goto error;
FUNLOCKFILE(fp);
(*linep)[0] = '\0';
return (-1);
linelen = -1;
goto end;
}
linelen = 0;
@ -150,11 +150,12 @@ getdelim(char ** __restrict linep, size_t * __restrict linecapp, int delim,
done:
/* Invariant: *linep has space for at least linelen+1 bytes. */
(*linep)[linelen] = '\0';
FUNLOCKFILE(fp);
end:
FUNLOCKFILE_CANCELSAFE();
return (linelen);
error:
fp->_flags |= __SERR;
FUNLOCKFILE(fp);
return (-1);
linelen = -1;
goto end;
}

View File

@ -50,27 +50,30 @@ char *
gets(char *buf)
{
int c;
char *s;
char *s, *ret;
static int warned;
static const char w[] =
"warning: this program uses gets(), which is unsafe.\n";
FLOCKFILE(stdin);
FLOCKFILE_CANCELSAFE(stdin);
ORIENT(stdin, -1);
if (!warned) {
(void) _write(STDERR_FILENO, w, sizeof(w) - 1);
warned = 1;
}
for (s = buf; (c = __sgetc(stdin)) != '\n';)
for (s = buf; (c = __sgetc(stdin)) != '\n'; ) {
if (c == EOF)
if (s == buf) {
FUNLOCKFILE(stdin);
return (NULL);
ret = NULL;
goto end;
} else
break;
else
*s++ = c;
}
*s = 0;
FUNLOCKFILE(stdin);
return (buf);
ret = buf;
end:
FUNLOCKFILE_CANCELSAFE();
return (ret);
}

View File

@ -38,6 +38,9 @@
* $FreeBSD$
*/
#ifndef _STDIO_LOCAL_H
#define _STDIO_LOCAL_H
#include <sys/types.h> /* for off_t */
#include <pthread.h>
#include <string.h>
@ -138,3 +141,26 @@ __fgetwc(FILE *fp, locale_t locale)
if ((fp)->_orientation == 0) \
(fp)->_orientation = (o); \
} while (0)
void __stdio_cancel_cleanup(void *);
#define FLOCKFILE_CANCELSAFE(fp) \
{ \
struct _pthread_cleanup_info __cleanup_info__; \
if (__isthreaded) { \
_FLOCKFILE(fp); \
__pthread_cleanup_push_imp( \
__stdio_cancel_cleanup, (fp), \
&__cleanup_info__); \
} else { \
__pthread_cleanup_push_imp( \
__stdio_cancel_cleanup, NULL, \
&__cleanup_info__); \
} \
{
#define FUNLOCKFILE_CANCELSAFE() \
(void)0; \
} \
__pthread_cleanup_pop_imp(1); \
}
#endif /* _STDIO_LOCAL_H */

View File

@ -67,9 +67,9 @@ perror(const char *s)
v++;
v->iov_base = "\n";
v->iov_len = 1;
FLOCKFILE(stderr);
FLOCKFILE_CANCELSAFE(stderr);
__sflush(stderr);
(void)_writev(stderr->_file, iov, (v - iov) + 1);
stderr->_flags &= ~__SOFF;
FUNLOCKFILE(stderr);
FUNLOCKFILE_CANCELSAFE();
}

View File

@ -49,11 +49,11 @@ int
putc(int c, FILE *fp)
{
int retval;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
/* Orientation set by __sputc() when buffer is full. */
/* ORIENT(fp, -1); */
retval = __sputc(c, fp);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (retval);
}

View File

@ -54,11 +54,11 @@ putchar(int c)
int retval;
FILE *so = stdout;
FLOCKFILE(so);
FLOCKFILE_CANCELSAFE(so);
/* Orientation set by __sputc() when buffer is full. */
/* ORIENT(so, -1); */
retval = __sputc(c, so);
FUNLOCKFILE(so);
FUNLOCKFILE_CANCELSAFE();
return (retval);
}

View File

@ -62,9 +62,9 @@ puts(char const *s)
uio.uio_resid = c + 1;
uio.uio_iov = &iov[0];
uio.uio_iovcnt = 2;
FLOCKFILE(stdout);
FLOCKFILE_CANCELSAFE(stdout);
ORIENT(stdout, -1);
retval = __sfvwrite(stdout, &uio) ? EOF : '\n';
FUNLOCKFILE(stdout);
FUNLOCKFILE_CANCELSAFE();
return (retval);
}

View File

@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
#include "fvwrite.h"
#include "libc_private.h"
#include "local.h"
int
putw(int w, FILE *fp)
@ -53,8 +54,8 @@ putw(int w, FILE *fp)
uio.uio_resid = iov.iov_len = sizeof(w);
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
retval = __sfvwrite(fp, &uio);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (retval);
}

View File

@ -53,9 +53,9 @@ lflush(FILE *fp)
int ret = 0;
if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) {
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ret = __sflush(fp);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
}
return (ret);
}

View File

@ -56,9 +56,9 @@ scanf(char const * __restrict fmt, ...)
va_list ap;
va_start(ap, fmt);
FLOCKFILE(stdin);
FLOCKFILE_CANCELSAFE(stdin);
ret = __svfscanf(stdin, __get_locale(), fmt, ap);
FUNLOCKFILE(stdin);
FUNLOCKFILE_CANCELSAFE();
va_end(ap);
return (ret);
}
@ -70,9 +70,9 @@ scanf_l(locale_t locale, char const * __restrict fmt, ...)
FIX_LOCALE(locale);
va_start(ap, fmt);
FLOCKFILE(stdin);
FLOCKFILE_CANCELSAFE(stdin);
ret = __svfscanf(stdin, locale, fmt, ap);
FUNLOCKFILE(stdin);
FUNLOCKFILE_CANCELSAFE();
va_end(ap);
return (ret);
}

View File

@ -63,7 +63,7 @@ setvbuf(FILE * __restrict fp, char * __restrict buf, int mode, size_t size)
if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0)
return (EOF);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
/*
* Write current buffer, if any. Discard unread input (including
* ungetc data), cancel line buffering, and free old buffer if
@ -115,8 +115,7 @@ setvbuf(FILE * __restrict fp, char * __restrict buf, int mode, size_t size)
fp->_w = 0;
fp->_bf._base = fp->_p = fp->_nbuf;
fp->_bf._size = 1;
FUNLOCKFILE(fp);
return (ret);
goto end;
}
flags |= __SMBF;
}
@ -156,6 +155,7 @@ setvbuf(FILE * __restrict fp, char * __restrict buf, int mode, size_t size)
}
__cleanup = _cleanup;
FUNLOCKFILE(fp);
end:
FUNLOCKFILE_CANCELSAFE();
return (ret);
}

View File

@ -166,3 +166,11 @@ _sseek(FILE *fp, fpos_t offset, int whence)
}
return (ret);
}
void
__stdio_cancel_cleanup(void * arg)
{
if (arg != NULL)
_funlockfile((FILE *)arg);
}

View File

@ -94,10 +94,10 @@ ungetc(int c, FILE *fp)
if (!__sdidinit)
__sinit();
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, -1);
ret = __ungetc(c, fp);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (ret);
}

View File

@ -76,10 +76,10 @@ ungetwc_l(wint_t wc, FILE *fp, locale_t locale)
wint_t r;
FIX_LOCALE(locale);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, 1);
r = __ungetwc(wc, fp, locale);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (r);
}

View File

@ -274,14 +274,14 @@ vfprintf_l(FILE * __restrict fp, locale_t locale, const char * __restrict fmt0,
int ret;
FIX_LOCALE(locale);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
fp->_file >= 0)
ret = __sbprintf(fp, locale, fmt0, ap);
else
ret = __vfprintf(fp, locale, fmt0, ap);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (ret);
}
int

View File

@ -443,9 +443,9 @@ __vfscanf(FILE *fp, char const *fmt0, va_list ap)
{
int ret;
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ret = __svfscanf(fp, __get_locale(), fmt0, ap);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (ret);
}
int
@ -454,9 +454,9 @@ vfscanf_l(FILE *fp, locale_t locale, char const *fmt0, va_list ap)
int ret;
FIX_LOCALE(locale);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ret = __svfscanf(fp, locale, fmt0, ap);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (ret);
}

View File

@ -356,14 +356,14 @@ vfwprintf_l(FILE * __restrict fp, locale_t locale,
{
int ret;
FIX_LOCALE(locale);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
fp->_file >= 0)
ret = __sbprintf(fp, locale, fmt0, ap);
else
ret = __vfwprintf(fp, locale, fmt0, ap);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (ret);
}
int

View File

@ -428,10 +428,10 @@ vfwscanf_l(FILE * __restrict fp, locale_t locale,
int ret;
FIX_LOCALE(locale);
FLOCKFILE(fp);
FLOCKFILE_CANCELSAFE(fp);
ORIENT(fp, 1);
ret = __vfwscanf(fp, locale, fmt, ap);
FUNLOCKFILE(fp);
FUNLOCKFILE_CANCELSAFE();
return (ret);
}
int

View File

@ -54,9 +54,9 @@ vscanf_l(locale_t locale, const char * __restrict fmt, __va_list ap)
int retval;
FIX_LOCALE(locale);
FLOCKFILE(stdin);
FLOCKFILE_CANCELSAFE(stdin);
retval = __svfscanf(stdin, locale, fmt, ap);
FUNLOCKFILE(stdin);
FUNLOCKFILE_CANCELSAFE();
return (retval);
}
int