summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2017-07-13 09:27:11 +0000
committerkib <kib@FreeBSD.org>2017-07-13 09:27:11 +0000
commit668d59a23068fc4a8aa806b914d95c71e903e92f (patch)
tree2479fb648c9c841acba46263712cd58a9c7dc384
parent55a89eef51d5a91be65f136631688b2c5b3371ab (diff)
downloadFreeBSD-src-668d59a23068fc4a8aa806b914d95c71e903e92f.zip
FreeBSD-src-668d59a23068fc4a8aa806b914d95c71e903e92f.tar.gz
MFC r320472,r320508,r320509:
Make stdio deferred cancel-safe.
-rw-r--r--lib/libc/include/libc_private.h5
-rw-r--r--lib/libc/stdio/fclose.c8
-rw-r--r--lib/libc/stdio/fflush.c8
-rw-r--r--lib/libc/stdio/fgetc.c4
-rw-r--r--lib/libc/stdio/fgetln.c22
-rw-r--r--lib/libc/stdio/fgets.c22
-rw-r--r--lib/libc/stdio/fgetwc.c4
-rw-r--r--lib/libc/stdio/fgetwln.c13
-rw-r--r--lib/libc/stdio/fgetws.c14
-rw-r--r--lib/libc/stdio/fputc.c4
-rw-r--r--lib/libc/stdio/fputs.c4
-rw-r--r--lib/libc/stdio/fputwc.c4
-rw-r--r--lib/libc/stdio/fputws.c20
-rw-r--r--lib/libc/stdio/fread.c4
-rw-r--r--lib/libc/stdio/freopen.c29
-rw-r--r--lib/libc/stdio/fscanf.c8
-rw-r--r--lib/libc/stdio/fseek.c8
-rw-r--r--lib/libc/stdio/fwrite.c4
-rw-r--r--lib/libc/stdio/getc.c4
-rw-r--r--lib/libc/stdio/getchar.c4
-rw-r--r--lib/libc/stdio/getdelim.c13
-rw-r--r--lib/libc/stdio/gets.c17
-rw-r--r--lib/libc/stdio/local.h26
-rw-r--r--lib/libc/stdio/perror.c4
-rw-r--r--lib/libc/stdio/putc.c4
-rw-r--r--lib/libc/stdio/putchar.c4
-rw-r--r--lib/libc/stdio/puts.c4
-rw-r--r--lib/libc/stdio/putw.c5
-rw-r--r--lib/libc/stdio/refill.c4
-rw-r--r--lib/libc/stdio/scanf.c8
-rw-r--r--lib/libc/stdio/setvbuf.c8
-rw-r--r--lib/libc/stdio/stdio.c8
-rw-r--r--lib/libc/stdio/ungetc.c4
-rw-r--r--lib/libc/stdio/ungetwc.c4
-rw-r--r--lib/libc/stdio/vfprintf.c4
-rw-r--r--lib/libc/stdio/vfscanf.c8
-rw-r--r--lib/libc/stdio/vfwprintf.c4
-rw-r--r--lib/libc/stdio/vfwscanf.c4
-rw-r--r--lib/libc/stdio/vscanf.c4
39 files changed, 191 insertions, 139 deletions
diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h
index 2134f34..1535dd7 100644
--- a/lib/libc/include/libc_private.h
+++ b/lib/libc/include/libc_private.h
@@ -407,6 +407,11 @@ void __libc_map_stacks_exec(void);
void _pthread_cancel_enter(int);
void _pthread_cancel_leave(int);
+struct _pthread_cleanup_info;
+void ___pthread_cleanup_push_imp(void (*)(void *), void *,
+ struct _pthread_cleanup_info *);
+void ___pthread_cleanup_pop_imp(int);
+
void __throw_constraint_handler_s(const char * restrict msg, int error);
#endif /* _LIBC_PRIVATE_H_ */
diff --git a/lib/libc/stdio/fclose.c b/lib/libc/stdio/fclose.c
index 24b9b90..063ef841 100644
--- a/lib/libc/stdio/fclose.c
+++ b/lib/libc/stdio/fclose.c
@@ -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);
}
diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c
index 123167a..5ecfc44 100644
--- a/lib/libc/stdio/fflush.c
+++ b/lib/libc/stdio/fflush.c
@@ -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);
}
diff --git a/lib/libc/stdio/fgetc.c b/lib/libc/stdio/fgetc.c
index 2ee4d7a..025a0c2 100644
--- a/lib/libc/stdio/fgetc.c
+++ b/lib/libc/stdio/fgetc.c
@@ -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);
}
diff --git a/lib/libc/stdio/fgetln.c b/lib/libc/stdio/fgetln.c
index c8e30ee..1e6b984 100644
--- a/lib/libc/stdio/fgetln.c
+++ b/lib/libc/stdio/fgetln.c
@@ -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;
}
diff --git a/lib/libc/stdio/fgets.c b/lib/libc/stdio/fgets.c
index a2e39ed..95d0ad9 100644
--- a/lib/libc/stdio/fgets.c
+++ b/lib/libc/stdio/fgets.c
@@ -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);
}
diff --git a/lib/libc/stdio/fgetwc.c b/lib/libc/stdio/fgetwc.c
index 3074d44..5f13e2d 100644
--- a/lib/libc/stdio/fgetwc.c
+++ b/lib/libc/stdio/fgetwc.c
@@ -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);
}
diff --git a/lib/libc/stdio/fgetwln.c b/lib/libc/stdio/fgetwln.c
index 037657c..a29f1f6 100644
--- a/lib/libc/stdio/fgetwln.c
+++ b/lib/libc/stdio/fgetwln.c
@@ -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 *
diff --git a/lib/libc/stdio/fgetws.c b/lib/libc/stdio/fgetws.c
index 8513a37..f47fea7 100644
--- a/lib/libc/stdio/fgetws.c
+++ b/lib/libc/stdio/fgetws.c
@@ -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);
- return (ws);
+ ret = ws;
+end:
+ FUNLOCKFILE_CANCELSAFE();
+ return (ret);
error:
- FUNLOCKFILE(fp);
- return (NULL);
+ ret = NULL;
+ goto end;
}
wchar_t *
diff --git a/lib/libc/stdio/fputc.c b/lib/libc/stdio/fputc.c
index 3b6101f..32c261a 100644
--- a/lib/libc/stdio/fputc.c
+++ b/lib/libc/stdio/fputc.c
@@ -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);
}
diff --git a/lib/libc/stdio/fputs.c b/lib/libc/stdio/fputs.c
index 1f9795a..b10ac52 100644
--- a/lib/libc/stdio/fputs.c
+++ b/lib/libc/stdio/fputs.c
@@ -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);
diff --git a/lib/libc/stdio/fputwc.c b/lib/libc/stdio/fputwc.c
index 7f0c910..d168867 100644
--- a/lib/libc/stdio/fputwc.c
+++ b/lib/libc/stdio/fputwc.c
@@ -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);
}
diff --git a/lib/libc/stdio/fputws.c b/lib/libc/stdio/fputws.c
index 4153067..19da946 100644
--- a/lib/libc/stdio/fputws.c
+++ b/lib/libc/stdio/fputws.c
@@ -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
diff --git a/lib/libc/stdio/fread.c b/lib/libc/stdio/fread.c
index c24df99..ff1c65b 100644
--- a/lib/libc/stdio/fread.c
+++ b/lib/libc/stdio/fread.c
@@ -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);
}
diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c
index e0104c8..3d6cc89 100644
--- a/lib/libc/stdio/freopen.c
+++ b/lib/libc/stdio/freopen.c
@@ -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 @@ 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);
}
diff --git a/lib/libc/stdio/fscanf.c b/lib/libc/stdio/fscanf.c
index 014f094..d3e0933 100644
--- a/lib/libc/stdio/fscanf.c
+++ b/lib/libc/stdio/fscanf.c
@@ -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);
}
diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c
index 2897eeb..e933bda 100644
--- a/lib/libc/stdio/fseek.c
+++ b/lib/libc/stdio/fseek.c
@@ -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);
diff --git a/lib/libc/stdio/fwrite.c b/lib/libc/stdio/fwrite.c
index 5b57fab0..41bb4f6 100644
--- a/lib/libc/stdio/fwrite.c
+++ b/lib/libc/stdio/fwrite.c
@@ -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);
}
diff --git a/lib/libc/stdio/getc.c b/lib/libc/stdio/getc.c
index 4963c8c..ad2df8a 100644
--- a/lib/libc/stdio/getc.c
+++ b/lib/libc/stdio/getc.c
@@ -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);
}
diff --git a/lib/libc/stdio/getchar.c b/lib/libc/stdio/getchar.c
index 2815072..320f967 100644
--- a/lib/libc/stdio/getchar.c
+++ b/lib/libc/stdio/getchar.c
@@ -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);
}
diff --git a/lib/libc/stdio/getdelim.c b/lib/libc/stdio/getdelim.c
index 7e0b2e2..26c608f 100644
--- a/lib/libc/stdio/getdelim.c
+++ b/lib/libc/stdio/getdelim.c
@@ -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;
}
diff --git a/lib/libc/stdio/gets.c b/lib/libc/stdio/gets.c
index c943851..f31221a 100644
--- a/lib/libc/stdio/gets.c
+++ b/lib/libc/stdio/gets.c
@@ -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);
}
diff --git a/lib/libc/stdio/local.h b/lib/libc/stdio/local.h
index 7168f62..e4b1687 100644
--- a/lib/libc/stdio/local.h
+++ b/lib/libc/stdio/local.h
@@ -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 */
diff --git a/lib/libc/stdio/perror.c b/lib/libc/stdio/perror.c
index 89c0798..1500788 100644
--- a/lib/libc/stdio/perror.c
+++ b/lib/libc/stdio/perror.c
@@ -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();
}
diff --git a/lib/libc/stdio/putc.c b/lib/libc/stdio/putc.c
index aaffece..c62d13f 100644
--- a/lib/libc/stdio/putc.c
+++ b/lib/libc/stdio/putc.c
@@ -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);
}
diff --git a/lib/libc/stdio/putchar.c b/lib/libc/stdio/putchar.c
index 7561559..1721a98 100644
--- a/lib/libc/stdio/putchar.c
+++ b/lib/libc/stdio/putchar.c
@@ -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);
}
diff --git a/lib/libc/stdio/puts.c b/lib/libc/stdio/puts.c
index 124afc7..b5fa01a 100644
--- a/lib/libc/stdio/puts.c
+++ b/lib/libc/stdio/puts.c
@@ -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);
}
diff --git a/lib/libc/stdio/putw.c b/lib/libc/stdio/putw.c
index ecd5d095..fc1d81c 100644
--- a/lib/libc/stdio/putw.c
+++ b/lib/libc/stdio/putw.c
@@ -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);
}
diff --git a/lib/libc/stdio/refill.c b/lib/libc/stdio/refill.c
index 71eb2e5..b4b4e01 100644
--- a/lib/libc/stdio/refill.c
+++ b/lib/libc/stdio/refill.c
@@ -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);
}
diff --git a/lib/libc/stdio/scanf.c b/lib/libc/stdio/scanf.c
index e377724..55aa420 100644
--- a/lib/libc/stdio/scanf.c
+++ b/lib/libc/stdio/scanf.c
@@ -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);
}
diff --git a/lib/libc/stdio/setvbuf.c b/lib/libc/stdio/setvbuf.c
index d396960..01db02e 100644
--- a/lib/libc/stdio/setvbuf.c
+++ b/lib/libc/stdio/setvbuf.c
@@ -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 @@ 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);
}
diff --git a/lib/libc/stdio/stdio.c b/lib/libc/stdio/stdio.c
index 5d6fb9a..c92fb4f 100644
--- a/lib/libc/stdio/stdio.c
+++ b/lib/libc/stdio/stdio.c
@@ -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);
+}
diff --git a/lib/libc/stdio/ungetc.c b/lib/libc/stdio/ungetc.c
index 88c9da5..a24a5a2 100644
--- a/lib/libc/stdio/ungetc.c
+++ b/lib/libc/stdio/ungetc.c
@@ -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);
}
diff --git a/lib/libc/stdio/ungetwc.c b/lib/libc/stdio/ungetwc.c
index 78bc38d..b47caf4 100644
--- a/lib/libc/stdio/ungetwc.c
+++ b/lib/libc/stdio/ungetwc.c
@@ -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);
}
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index bf45bfb..4779ad7 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -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
diff --git a/lib/libc/stdio/vfscanf.c b/lib/libc/stdio/vfscanf.c
index e49a9e1..8f7c1e8 100644
--- a/lib/libc/stdio/vfscanf.c
+++ b/lib/libc/stdio/vfscanf.c
@@ -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);
}
diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c
index 9a5381d..f130c14 100644
--- a/lib/libc/stdio/vfwprintf.c
+++ b/lib/libc/stdio/vfwprintf.c
@@ -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
diff --git a/lib/libc/stdio/vfwscanf.c b/lib/libc/stdio/vfwscanf.c
index 63b5dd1..aedc249 100644
--- a/lib/libc/stdio/vfwscanf.c
+++ b/lib/libc/stdio/vfwscanf.c
@@ -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
diff --git a/lib/libc/stdio/vscanf.c b/lib/libc/stdio/vscanf.c
index 8729c9c..309d00c 100644
--- a/lib/libc/stdio/vscanf.c
+++ b/lib/libc/stdio/vscanf.c
@@ -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
OpenPOWER on IntegriCloud