svn commit: r320472 - head/lib/libc/stdio
Konstantin Belousov
kib at FreeBSD.org
Thu Jun 29 14:44:22 UTC 2017
Author: kib
Date: Thu Jun 29 14:44:17 2017
New Revision: 320472
URL: https://svnweb.freebsd.org/changeset/base/320472
Log:
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
Modified:
head/lib/libc/stdio/fclose.c
head/lib/libc/stdio/fflush.c
head/lib/libc/stdio/fgetc.c
head/lib/libc/stdio/fgetln.c
head/lib/libc/stdio/fgets.c
head/lib/libc/stdio/fgetwc.c
head/lib/libc/stdio/fgetwln.c
head/lib/libc/stdio/fgetws.c
head/lib/libc/stdio/fputc.c
head/lib/libc/stdio/fputs.c
head/lib/libc/stdio/fputwc.c
head/lib/libc/stdio/fputws.c
head/lib/libc/stdio/fread.c
head/lib/libc/stdio/freopen.c
head/lib/libc/stdio/fscanf.c
head/lib/libc/stdio/fseek.c
head/lib/libc/stdio/fwrite.c
head/lib/libc/stdio/getc.c
head/lib/libc/stdio/getchar.c
head/lib/libc/stdio/getdelim.c
head/lib/libc/stdio/gets.c
head/lib/libc/stdio/local.h
head/lib/libc/stdio/perror.c
head/lib/libc/stdio/putc.c
head/lib/libc/stdio/putchar.c
head/lib/libc/stdio/puts.c
head/lib/libc/stdio/putw.c
head/lib/libc/stdio/refill.c
head/lib/libc/stdio/scanf.c
head/lib/libc/stdio/setvbuf.c
head/lib/libc/stdio/stdio.c
head/lib/libc/stdio/ungetc.c
head/lib/libc/stdio/ungetwc.c
head/lib/libc/stdio/vfprintf.c
head/lib/libc/stdio/vfscanf.c
head/lib/libc/stdio/vfwprintf.c
head/lib/libc/stdio/vfwscanf.c
head/lib/libc/stdio/vscanf.c
Modified: head/lib/libc/stdio/fclose.c
==============================================================================
--- head/lib/libc/stdio/fclose.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fclose.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/fflush.c
==============================================================================
--- head/lib/libc/stdio/fflush.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fflush.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/fgetc.c
==============================================================================
--- head/lib/libc/stdio/fgetc.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fgetc.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/fgetln.c
==============================================================================
--- head/lib/libc/stdio/fgetln.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fgetln.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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;
}
Modified: head/lib/libc/stdio/fgets.c
==============================================================================
--- head/lib/libc/stdio/fgets.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fgets.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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
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->_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
n -= len;
}
*s = 0;
- FUNLOCKFILE(fp);
- return (buf);
+ ret = buf;
+end:
+ FUNLOCKFILE_CANCELSAFE();
+ return (ret);
}
Modified: head/lib/libc/stdio/fgetwc.c
==============================================================================
--- head/lib/libc/stdio/fgetwc.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fgetwc.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/fgetwln.c
==============================================================================
--- head/lib/libc/stdio/fgetwln.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fgetwln.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -45,13 +45,14 @@ wchar_t *fgetwln_l(FILE * __restrict, size_t *, locale
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
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 *
Modified: head/lib/libc/stdio/fgetws.c
==============================================================================
--- head/lib/libc/stdio/fgetws.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fgetws.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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 * __rest
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 *
Modified: head/lib/libc/stdio/fputc.c
==============================================================================
--- head/lib/libc/stdio/fputc.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fputc.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/fputs.c
==============================================================================
--- head/lib/libc/stdio/fputs.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fputs.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
Modified: head/lib/libc/stdio/fputwc.c
==============================================================================
--- head/lib/libc/stdio/fputwc.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fputwc.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/fputws.c
==============================================================================
--- head/lib/libc/stdio/fputws.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fputws.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -53,11 +53,13 @@ fputws_l(const wchar_t * __restrict ws, FILE * __restr
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 * __restr
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
Modified: head/lib/libc/stdio/fread.c
==============================================================================
--- head/lib/libc/stdio/fread.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fread.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -54,9 +54,9 @@ fread(void * __restrict buf, size_t size, size_t count
{
size_t ret;
- FLOCKFILE(fp);
+ FLOCKFILE_CANCELSAFE(fp);
ret = __fread(buf, size, count, fp);
- FUNLOCKFILE(fp);
+ FUNLOCKFILE_CANCELSAFE();
return (ret);
}
Modified: head/lib/libc/stdio/freopen.c
==============================================================================
--- head/lib/libc/stdio/freopen.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/freopen.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -68,7 +68,7 @@ freopen(const char * __restrict file, const char * __r
return (NULL);
}
- FLOCKFILE(fp);
+ FLOCKFILE_CANCELSAFE(fp);
if (!__sdidinit)
__sinit();
@@ -81,24 +81,24 @@ freopen(const char * __restrict file, const char * __r
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 * __r
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 @@ finish:
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 @@ finish:
*/
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 @@ finish:
fp->_flags2 |= __S2OAP;
(void) _sseek(fp, (fpos_t)0, SEEK_END);
}
- FUNLOCKFILE(fp);
+end:
+ FUNLOCKFILE_CANCELSAFE();
return (fp);
}
Modified: head/lib/libc/stdio/fscanf.c
==============================================================================
--- head/lib/libc/stdio/fscanf.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fscanf.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -56,10 +56,10 @@ fscanf(FILE * __restrict fp, char const * __restrict f
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 c
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);
}
Modified: head/lib/libc/stdio/fseek.c
==============================================================================
--- head/lib/libc/stdio/fseek.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fseek.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
Modified: head/lib/libc/stdio/fwrite.c
==============================================================================
--- head/lib/libc/stdio/fwrite.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/fwrite.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -82,7 +82,7 @@ fwrite(const void * __restrict buf, size_t size, size_
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_
*/
if (__sfvwrite(fp, &uio) != 0)
count = (n - uio.uio_resid) / size;
- FUNLOCKFILE(fp);
+ FUNLOCKFILE_CANCELSAFE();
return (count);
}
Modified: head/lib/libc/stdio/getc.c
==============================================================================
--- head/lib/libc/stdio/getc.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/getc.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/getchar.c
==============================================================================
--- head/lib/libc/stdio/getchar.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/getchar.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/getdelim.c
==============================================================================
--- head/lib/libc/stdio/getdelim.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/getdelim.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -112,7 +112,7 @@ getdelim(char ** __restrict linep, size_t * __restrict
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
/* 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
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;
}
Modified: head/lib/libc/stdio/gets.c
==============================================================================
--- head/lib/libc/stdio/gets.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/gets.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/local.h
==============================================================================
--- head/lib/libc/stdio/local.h Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/local.h Thu Jun 29 14:44:17 2017 (r320472)
@@ -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 */
Modified: head/lib/libc/stdio/perror.c
==============================================================================
--- head/lib/libc/stdio/perror.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/perror.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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();
}
Modified: head/lib/libc/stdio/putc.c
==============================================================================
--- head/lib/libc/stdio/putc.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/putc.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/putchar.c
==============================================================================
--- head/lib/libc/stdio/putchar.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/putchar.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/puts.c
==============================================================================
--- head/lib/libc/stdio/puts.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/puts.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/putw.c
==============================================================================
--- head/lib/libc/stdio/putw.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/putw.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/refill.c
==============================================================================
--- head/lib/libc/stdio/refill.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/refill.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/scanf.c
==============================================================================
--- head/lib/libc/stdio/scanf.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/scanf.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/setvbuf.c
==============================================================================
--- head/lib/libc/stdio/setvbuf.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/setvbuf.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -63,7 +63,7 @@ setvbuf(FILE * __restrict fp, char * __restrict buf, i
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 @@ nbf:
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 @@ nbf:
}
__cleanup = _cleanup;
- FUNLOCKFILE(fp);
+end:
+ FUNLOCKFILE_CANCELSAFE();
return (ret);
}
Modified: head/lib/libc/stdio/stdio.c
==============================================================================
--- head/lib/libc/stdio/stdio.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/stdio.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
+}
Modified: head/lib/libc/stdio/ungetc.c
==============================================================================
--- head/lib/libc/stdio/ungetc.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/ungetc.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/ungetwc.c
==============================================================================
--- head/lib/libc/stdio/ungetwc.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/ungetwc.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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);
}
Modified: head/lib/libc/stdio/vfprintf.c
==============================================================================
--- head/lib/libc/stdio/vfprintf.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/vfprintf.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -274,14 +274,14 @@ vfprintf_l(FILE * __restrict fp, locale_t locale, cons
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
Modified: head/lib/libc/stdio/vfscanf.c
==============================================================================
--- head/lib/libc/stdio/vfscanf.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/vfscanf.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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,
int ret;
FIX_LOCALE(locale);
- FLOCKFILE(fp);
+ FLOCKFILE_CANCELSAFE(fp);
ret = __svfscanf(fp, locale, fmt0, ap);
- FUNLOCKFILE(fp);
+ FUNLOCKFILE_CANCELSAFE();
return (ret);
}
Modified: head/lib/libc/stdio/vfwprintf.c
==============================================================================
--- head/lib/libc/stdio/vfwprintf.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/vfwprintf.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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
Modified: head/lib/libc/stdio/vfwscanf.c
==============================================================================
--- head/lib/libc/stdio/vfwscanf.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/vfwscanf.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -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
Modified: head/lib/libc/stdio/vscanf.c
==============================================================================
--- head/lib/libc/stdio/vscanf.c Thu Jun 29 14:40:33 2017 (r320471)
+++ head/lib/libc/stdio/vscanf.c Thu Jun 29 14:44:17 2017 (r320472)
@@ -54,9 +54,9 @@ vscanf_l(locale_t locale, const char * __restrict fmt,
int retval;
FIX_LOCALE(locale);
- FLOCKFILE(stdin);
+ FLOCKFILE_CANCELSAFE(stdin);
retval = __svfscanf(stdin, locale, fmt, ap);
- FUNLOCKFILE(stdin);
+ FUNLOCKFILE_CANCELSAFE();
return (retval);
}
int
More information about the svn-src-head
mailing list