aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--newlib/ChangeLog16
-rw-r--r--newlib/libc/stdio/clearerr.c4
-rw-r--r--newlib/libc/stdio/fclose.c12
-rw-r--r--newlib/libc/stdio/fdopen.c4
-rw-r--r--newlib/libc/stdio/feof.c4
-rw-r--r--newlib/libc/stdio/ferror.c4
-rw-r--r--newlib/libc/stdio/fflush.c4
-rw-r--r--newlib/libc/stdio/fgetc.c8
-rw-r--r--newlib/libc/stdio/fgets.c12
-rw-r--r--newlib/libc/stdio/fgetwc.c4
-rw-r--r--newlib/libc/stdio/fgetws.c6
-rw-r--r--newlib/libc/stdio/fileno.c4
-rw-r--r--newlib/libc/stdio/findfp.c6
-rw-r--r--newlib/libc/stdio/fmemopen.c8
-rw-r--r--newlib/libc/stdio/fopen.c8
-rw-r--r--newlib/libc/stdio/fopencookie.c8
-rw-r--r--newlib/libc/stdio/fpurge.c6
-rw-r--r--newlib/libc/stdio/fputc.c8
-rw-r--r--newlib/libc/stdio/fputs.c4
-rw-r--r--newlib/libc/stdio/fputwc.c4
-rw-r--r--newlib/libc/stdio/fputws.c6
-rw-r--r--newlib/libc/stdio/fread.c14
-rw-r--r--newlib/libc/stdio/freopen.c15
-rw-r--r--newlib/libc/stdio/fseek.c18
-rw-r--r--newlib/libc/stdio/ftell.c8
-rw-r--r--newlib/libc/stdio/funopen.c8
-rw-r--r--newlib/libc/stdio/fwide.c4
-rw-r--r--newlib/libc/stdio/fwrite.c6
-rw-r--r--newlib/libc/stdio/getc.c8
-rw-r--r--newlib/libc/stdio/getdelim.c4
-rw-r--r--newlib/libc/stdio/gets.c7
-rw-r--r--newlib/libc/stdio/local.h77
-rw-r--r--newlib/libc/stdio/open_memstream.c12
-rw-r--r--newlib/libc/stdio/putc.c8
-rw-r--r--newlib/libc/stdio/setvbuf.c8
-rw-r--r--newlib/libc/stdio/ungetc.c14
-rw-r--r--newlib/libc/stdio/ungetwc.c4
-rw-r--r--newlib/libc/stdio/vfprintf.c8
-rw-r--r--newlib/libc/stdio/vfscanf.c18
-rw-r--r--newlib/libc/stdio/vfwprintf.c8
-rw-r--r--newlib/libc/stdio/vfwscanf.c18
-rw-r--r--newlib/libc/stdio64/fdopen64.c4
-rw-r--r--newlib/libc/stdio64/fopen64.c8
-rw-r--r--newlib/libc/stdio64/freopen64.c23
-rw-r--r--newlib/libc/stdio64/fseeko64.c12
-rw-r--r--newlib/libc/stdio64/ftello64.c8
46 files changed, 301 insertions, 161 deletions
diff --git a/newlib/ChangeLog b/newlib/ChangeLog
index d51b87f..b40d62a 100644
--- a/newlib/ChangeLog
+++ b/newlib/ChangeLog
@@ -1,3 +1,19 @@
+2012-05-30 Corinna Vinschen <vinschen@redhat.com>
+
+ * libc/stdio/local.h (_newlib_flockfile_start): New macro to
+ secure stream related critical section against thread cancellation.
+ (_newlib_flockfile_exit): Ditto.
+ (_newlib_sfp_lock_end): Ditto.
+ (_newlib_sfp_lock_start): Ditto for the list of streams.
+ (_newlib_sfp_lock_exit): Ditto.
+ (_newlib_sfp_lock_end): Ditto.
+ Use aforementioned macros in place of _flockfile/_funlockfile
+ and __sfp_lock_acquire/__sfp_lock_release throughout the code.
+ * libc/stdio/fclose.c: Explicitely disable and re-enable thread
+ cancellation. Explain why.
+ * libc/stdio/freopen.c: Ditto.
+ * libc/stdio64/freopen64.c: Ditto.
+
2012-05-21 Sandeep Kumar Singh <Sandeep.Singh2@kpitcummins.com>
* libc/machine/cr16/asm.h: Added some missing instructions
diff --git a/newlib/libc/stdio/clearerr.c b/newlib/libc/stdio/clearerr.c
index d3b620b..ed4603b 100644
--- a/newlib/libc/stdio/clearerr.c
+++ b/newlib/libc/stdio/clearerr.c
@@ -65,7 +65,7 @@ _DEFUN(clearerr, (fp),
FILE * fp)
{
CHECK_INIT(_REENT, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
__sclearerr (fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
}
diff --git a/newlib/libc/stdio/fclose.c b/newlib/libc/stdio/fclose.c
index 3c8868a..7904964 100644
--- a/newlib/libc/stdio/fclose.c
+++ b/newlib/libc/stdio/fclose.c
@@ -76,11 +76,20 @@ _DEFUN(_fclose_r, (rptr, fp),
CHECK_INIT (rptr, fp);
+ /* We can't use the _newlib_flockfile_XXX macros here due to the
+ interlocked locking with the sfp_lock. */
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+ int __oldcancel;
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldcancel);
+#endif
_flockfile (fp);
if (fp->_flags == 0) /* not open! */
{
_funlockfile (fp);
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+ pthread_setcancelstate (__oldcancel, &__oldcancel);
+#endif
return (0);
}
/* Unconditionally flush to allow special handling for seekable read
@@ -103,6 +112,9 @@ _DEFUN(_fclose_r, (rptr, fp),
#endif
__sfp_lock_release ();
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+ pthread_setcancelstate (__oldcancel, &__oldcancel);
+#endif
return (r);
}
diff --git a/newlib/libc/stdio/fdopen.c b/newlib/libc/stdio/fdopen.c
index aa764c3..77f599b 100644
--- a/newlib/libc/stdio/fdopen.c
+++ b/newlib/libc/stdio/fdopen.c
@@ -93,7 +93,7 @@ _DEFUN(_fdopen_r, (ptr, fd, mode),
if ((fp = __sfp (ptr)) == 0)
return 0;
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
fp->_flags = flags;
/* POSIX recommends setting the O_APPEND bit on fd to match append
@@ -127,7 +127,7 @@ _DEFUN(_fdopen_r, (ptr, fd, mode),
fp->_flags |= __SCLE;
#endif
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return fp;
}
diff --git a/newlib/libc/stdio/feof.c b/newlib/libc/stdio/feof.c
index e8db65b..c0216ff 100644
--- a/newlib/libc/stdio/feof.c
+++ b/newlib/libc/stdio/feof.c
@@ -58,8 +58,8 @@ _DEFUN(feof, (fp),
{
int result;
CHECK_INIT(_REENT, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
result = __sfeof (fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return result;
}
diff --git a/newlib/libc/stdio/ferror.c b/newlib/libc/stdio/ferror.c
index 72b7ce2..0cd3c30 100644
--- a/newlib/libc/stdio/ferror.c
+++ b/newlib/libc/stdio/ferror.c
@@ -67,8 +67,8 @@ _DEFUN(ferror, (fp),
{
int result;
CHECK_INIT(_REENT, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
result = __sferror (fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return result;
}
diff --git a/newlib/libc/stdio/fflush.c b/newlib/libc/stdio/fflush.c
index 130c148..b2bde7a 100644
--- a/newlib/libc/stdio/fflush.c
+++ b/newlib/libc/stdio/fflush.c
@@ -226,9 +226,9 @@ _DEFUN(_fflush_r, (ptr, fp),
if (!fp->_flags)
return 0;
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ret = __sflush_r (ptr, fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return ret;
}
diff --git a/newlib/libc/stdio/fgetc.c b/newlib/libc/stdio/fgetc.c
index e275cfe..99d8330 100644
--- a/newlib/libc/stdio/fgetc.c
+++ b/newlib/libc/stdio/fgetc.c
@@ -78,9 +78,9 @@ _DEFUN(_fgetc_r, (ptr, fp),
{
int result;
CHECK_INIT(ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
result = __sgetc_r (ptr, fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return result;
}
@@ -93,9 +93,9 @@ _DEFUN(fgetc, (fp),
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
int result;
CHECK_INIT(_REENT, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
result = __sgetc_r (_REENT, fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return result;
#else
return _fgetc_r (_REENT, fp);
diff --git a/newlib/libc/stdio/fgets.c b/newlib/libc/stdio/fgets.c
index 7f02e3f..1644fba 100644
--- a/newlib/libc/stdio/fgets.c
+++ b/newlib/libc/stdio/fgets.c
@@ -98,7 +98,7 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
CHECK_INIT(ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
@@ -112,11 +112,11 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
}
if (c == EOF && s == buf)
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return NULL;
}
*s = 0;
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return buf;
}
#endif
@@ -134,7 +134,7 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
/* EOF: stop with partial or no line */
if (s == buf)
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return 0;
}
break;
@@ -159,7 +159,7 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
fp->_p = t;
_CAST_VOID memcpy ((_PTR) s, (_PTR) p, len);
s[len] = 0;
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return (buf);
}
fp->_r -= len;
@@ -169,7 +169,7 @@ _DEFUN(_fgets_r, (ptr, buf, n, fp),
}
while ((n -= len) != 0);
*s = 0;
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return buf;
}
diff --git a/newlib/libc/stdio/fgetwc.c b/newlib/libc/stdio/fgetwc.c
index 38a79bc..0eaaecb 100644
--- a/newlib/libc/stdio/fgetwc.c
+++ b/newlib/libc/stdio/fgetwc.c
@@ -164,10 +164,10 @@ _DEFUN(_fgetwc_r, (ptr, fp),
{
wint_t r;
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT(fp, 1);
r = __fgetwc (ptr, fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return r;
}
diff --git a/newlib/libc/stdio/fgetws.c b/newlib/libc/stdio/fgetws.c
index 2784f15..cbfd84e 100644
--- a/newlib/libc/stdio/fgetws.c
+++ b/newlib/libc/stdio/fgetws.c
@@ -93,7 +93,7 @@ _DEFUN(_fgetws_r, (ptr, ws, n, fp),
const char *src;
unsigned char *nl;
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT (fp, 1);
if (n <= 0)
@@ -142,11 +142,11 @@ _DEFUN(_fgetws_r, (ptr, ws, n, fp),
/* Incomplete character */
goto error;
*wsp++ = L'\0';
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return ws;
error:
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return NULL;
}
diff --git a/newlib/libc/stdio/fileno.c b/newlib/libc/stdio/fileno.c
index db399eb..818f1a1 100644
--- a/newlib/libc/stdio/fileno.c
+++ b/newlib/libc/stdio/fileno.c
@@ -55,8 +55,8 @@ _DEFUN(fileno, (f),
{
int result;
CHECK_INIT (_REENT, f);
- _flockfile (f);
+ _newlib_flockfile_start (f);
result = __sfileno (f);
- _funlockfile (f);
+ _newlib_flockfile_end (f);
return result;
}
diff --git a/newlib/libc/stdio/findfp.c b/newlib/libc/stdio/findfp.c
index d812414..e39660c 100644
--- a/newlib/libc/stdio/findfp.c
+++ b/newlib/libc/stdio/findfp.c
@@ -108,7 +108,7 @@ _DEFUN(__sfp, (d),
int n;
struct _glue *g;
- __sfp_lock_acquire ();
+ _newlib_sfp_lock_start ();
if (!_GLOBAL_REENT->__sdidinit)
__sinit (_GLOBAL_REENT);
@@ -121,7 +121,7 @@ _DEFUN(__sfp, (d),
(g->_next = __sfmoreglue (d, NDYNAMIC)) == NULL)
break;
}
- __sfp_lock_release ();
+ _newlib_sfp_lock_exit ();
d->_errno = ENOMEM;
return NULL;
@@ -132,7 +132,7 @@ found:
#ifndef __SINGLE_THREAD__
__lock_init_recursive (fp->_lock);
#endif
- __sfp_lock_release ();
+ _newlib_sfp_lock_end ();
fp->_p = NULL; /* no current pointer */
fp->_w = 0; /* nothing to read or write */
diff --git a/newlib/libc/stdio/fmemopen.c b/newlib/libc/stdio/fmemopen.c
index 5218e8a..acfb23c 100644
--- a/newlib/libc/stdio/fmemopen.c
+++ b/newlib/libc/stdio/fmemopen.c
@@ -291,12 +291,12 @@ _DEFUN(_fmemopen_r, (ptr, buf, size, mode),
if ((c = (fmemcookie *) _malloc_r (ptr, sizeof *c + (buf ? 0 : size)))
== NULL)
{
- __sfp_lock_acquire ();
+ _newlib_sfp_lock_start ();
fp->_flags = 0; /* release */
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
- __sfp_lock_release ();
+ _newlib_sfp_lock_end ();
return NULL;
}
@@ -343,7 +343,7 @@ _DEFUN(_fmemopen_r, (ptr, buf, size, mode),
}
}
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
fp->_file = -1;
fp->_flags = flags;
fp->_cookie = c;
@@ -355,7 +355,7 @@ _DEFUN(_fmemopen_r, (ptr, buf, size, mode),
fp->_flags |= __SL64;
#endif
fp->_close = fmemcloser;
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return fp;
}
diff --git a/newlib/libc/stdio/fopen.c b/newlib/libc/stdio/fopen.c
index 64c24e7..27d4bc8 100644
--- a/newlib/libc/stdio/fopen.c
+++ b/newlib/libc/stdio/fopen.c
@@ -140,16 +140,16 @@ _DEFUN(_fopen_r, (ptr, file, mode),
if ((f = _open_r (ptr, file, oflags, 0666)) < 0)
{
- __sfp_lock_acquire ();
+ _newlib_sfp_lock_start ();
fp->_flags = 0; /* release */
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
- __sfp_lock_release ();
+ _newlib_sfp_lock_end ();
return NULL;
}
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
fp->_file = f;
fp->_flags = flags;
@@ -167,7 +167,7 @@ _DEFUN(_fopen_r, (ptr, file, mode),
fp->_flags |= __SCLE;
#endif
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return fp;
}
diff --git a/newlib/libc/stdio/fopencookie.c b/newlib/libc/stdio/fopencookie.c
index 5148c8a..f08d132 100644
--- a/newlib/libc/stdio/fopencookie.c
+++ b/newlib/libc/stdio/fopencookie.c
@@ -219,16 +219,16 @@ _DEFUN(_fopencookie_r, (ptr, cookie, mode, functions),
return NULL;
if ((c = (fccookie *) _malloc_r (ptr, sizeof *c)) == NULL)
{
- __sfp_lock_acquire ();
+ _newlib_sfp_lock_start ();
fp->_flags = 0; /* release */
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
- __sfp_lock_release ();
+ _newlib_sfp_lock_end ();
return NULL;
}
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
fp->_file = -1;
fp->_flags = flags;
c->cookie = cookie;
@@ -246,7 +246,7 @@ _DEFUN(_fopencookie_r, (ptr, cookie, mode, functions),
#endif
c->closefn = functions.close;
fp->_close = fccloser;
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return fp;
}
diff --git a/newlib/libc/stdio/fpurge.c b/newlib/libc/stdio/fpurge.c
index 7e23bb7..dc052e8 100644
--- a/newlib/libc/stdio/fpurge.c
+++ b/newlib/libc/stdio/fpurge.c
@@ -68,13 +68,13 @@ _DEFUN(_fpurge_r, (ptr, fp),
CHECK_INIT (ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
t = fp->_flags;
if (!t)
{
ptr->_errno = EBADF;
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return EOF;
}
fp->_p = fp->_bf._base;
@@ -86,7 +86,7 @@ _DEFUN(_fpurge_r, (ptr, fp),
}
else
fp->_w = t & (__SLBF | __SNBF) ? 0 : fp->_bf._size;
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return 0;
}
diff --git a/newlib/libc/stdio/fputc.c b/newlib/libc/stdio/fputc.c
index 777a342..6af79d4 100644
--- a/newlib/libc/stdio/fputc.c
+++ b/newlib/libc/stdio/fputc.c
@@ -83,9 +83,9 @@ _DEFUN(_fputc_r, (ptr, ch, file),
{
int result;
CHECK_INIT(ptr, file);
- _flockfile (file);
+ _newlib_flockfile_start (file);
result = _putc_r (ptr, ch, file);
- _funlockfile (file);
+ _newlib_flockfile_end (file);
return result;
}
@@ -98,9 +98,9 @@ _DEFUN(fputc, (ch, file),
#if !defined(__OPTIMIZE_SIZE__) && !defined(PREFER_SIZE_OVER_SPEED)
int result;
CHECK_INIT(_REENT, file);
- _flockfile (file);
+ _newlib_flockfile_start (file);
result = _putc_r (_REENT, ch, file);
- _funlockfile (file);
+ _newlib_flockfile_end (file);
return result;
#else
return _fputc_r (_REENT, ch, file);
diff --git a/newlib/libc/stdio/fputs.c b/newlib/libc/stdio/fputs.c
index a32dea4..6e623a5 100644
--- a/newlib/libc/stdio/fputs.c
+++ b/newlib/libc/stdio/fputs.c
@@ -88,10 +88,10 @@ _DEFUN(_fputs_r, (ptr, s, fp),
CHECK_INIT(ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT (fp, -1);
result = __sfvwrite_r (ptr, fp, &uio);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return result;
}
diff --git a/newlib/libc/stdio/fputwc.c b/newlib/libc/stdio/fputwc.c
index f32d566..74e7a45 100644
--- a/newlib/libc/stdio/fputwc.c
+++ b/newlib/libc/stdio/fputwc.c
@@ -160,10 +160,10 @@ _DEFUN(_fputwc_r, (ptr, wc, fp),
{
wint_t r;
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT(fp, 1);
r = __fputwc(ptr, wc, fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return r;
}
diff --git a/newlib/libc/stdio/fputws.c b/newlib/libc/stdio/fputws.c
index b8e5d1e..c88111c 100644
--- a/newlib/libc/stdio/fputws.c
+++ b/newlib/libc/stdio/fputws.c
@@ -87,7 +87,7 @@ _DEFUN(_fputws_r, (ptr, ws, fp),
struct __suio uio;
struct __siov iov;
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT (fp, 1);
if (cantwrite (ptr, fp) != 0)
goto error;
@@ -104,11 +104,11 @@ _DEFUN(_fputws_r, (ptr, ws, fp),
goto error;
}
while (ws != NULL);
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return (0);
error:
- _funlockfile(fp);
+ _newlib_flockfile_end(fp);
return (-1);
}
diff --git a/newlib/libc/stdio/fread.c b/newlib/libc/stdio/fread.c
index a39e9d8..07fe0af 100644
--- a/newlib/libc/stdio/fread.c
+++ b/newlib/libc/stdio/fread.c
@@ -146,7 +146,7 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
CHECK_INIT(ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT (fp, -1);
if (fp->_r < 0)
fp->_r = 0;
@@ -195,11 +195,11 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return crlf_r (ptr, fp, buf, total-resid, 1) / size;
}
#endif
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return (total - resid) / size;
}
}
@@ -220,11 +220,11 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return crlf_r (ptr, fp, buf, total-resid, 1) / size;
}
#endif
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return (total - resid) / size;
}
}
@@ -237,11 +237,11 @@ _DEFUN(_fread_r, (ptr, buf, size, count, fp),
#ifdef __SCLE
if (fp->_flags & __SCLE)
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return crlf_r(ptr, fp, buf, total, 0) / size;
}
#endif
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return count;
}
diff --git a/newlib/libc/stdio/freopen.c b/newlib/libc/stdio/freopen.c
index 1720062..6483655 100644
--- a/newlib/libc/stdio/freopen.c
+++ b/newlib/libc/stdio/freopen.c
@@ -100,11 +100,20 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
CHECK_INIT (ptr, fp);
+ /* We can't use the _newlib_flockfile_XXX macros here due to the
+ interlocked locking with the sfp_lock. */
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+ int __oldcancel;
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldcancel);
+#endif
_flockfile (fp);
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
{
_funlockfile (fp);
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+ pthread_setcancelstate (__oldcancel, &__oldcancel);
+#endif
_fclose_r (ptr, fp);
return NULL;
}
@@ -213,6 +222,9 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
__lock_close_recursive (fp->_lock);
#endif
__sfp_lock_release ();
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+ pthread_setcancelstate (__oldcancel, &__oldcancel);
+#endif
return NULL;
}
@@ -230,6 +242,9 @@ _DEFUN(_freopen_r, (ptr, file, mode, fp),
#endif
_funlockfile (fp);
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+ pthread_setcancelstate (__oldcancel, &__oldcancel);
+#endif
return fp;
}
diff --git a/newlib/libc/stdio/fseek.c b/newlib/libc/stdio/fseek.c
index c78d2b2..099a958 100644
--- a/newlib/libc/stdio/fseek.c
+++ b/newlib/libc/stdio/fseek.c
@@ -138,7 +138,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
CHECK_INIT (ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
/* If we've been doing some writing, and we're in append mode
then we don't really know where the filepos is. */
@@ -154,7 +154,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
if ((seekfn = fp->_seek) == NULL)
{
ptr->_errno = ESPIPE; /* ??? */
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return EOF;
}
@@ -179,7 +179,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
curoff = seekfn (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
if (curoff == -1L)
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return EOF;
}
}
@@ -204,7 +204,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
default:
ptr->_errno = EINVAL;
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return (EOF);
}
@@ -263,7 +263,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
if ((long)target != target)
{
ptr->_errno = EOVERFLOW;
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return EOF;
}
@@ -319,7 +319,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
FREEUB (ptr, fp);
fp->_flags &= ~__SEOF;
memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return 0;
}
@@ -349,7 +349,7 @@ _DEFUN(_fseek_r, (ptr, fp, offset, whence),
fp->_r -= n;
}
memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return 0;
/*
@@ -361,7 +361,7 @@ dumb:
if (_fflush_r (ptr, fp)
|| seekfn (ptr, fp->_cookie, offset, whence) == POS_ERR)
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return EOF;
}
/* success: clear EOF indicator and discard ungetc() data */
@@ -379,7 +379,7 @@ dumb:
is performed. */
fp->_flags &= ~__SNPT;
memset (&fp->_mbstate, 0, sizeof (_mbstate_t));
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return 0;
}
diff --git a/newlib/libc/stdio/ftell.c b/newlib/libc/stdio/ftell.c
index 816cafa..54a656c 100644
--- a/newlib/libc/stdio/ftell.c
+++ b/newlib/libc/stdio/ftell.c
@@ -109,12 +109,12 @@ _DEFUN(_ftell_r, (ptr, fp),
CHECK_INIT (ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
if (fp->_seek == NULL)
{
ptr->_errno = ESPIPE;
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return -1L;
}
@@ -131,7 +131,7 @@ _DEFUN(_ftell_r, (ptr, fp),
pos = fp->_seek (ptr, fp->_cookie, (_fpos_t) 0, SEEK_CUR);
if (pos == -1L)
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return pos;
}
}
@@ -156,7 +156,7 @@ _DEFUN(_ftell_r, (ptr, fp),
pos += fp->_p - fp->_bf._base;
}
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
if ((long)pos != pos)
{
pos = -1;
diff --git a/newlib/libc/stdio/funopen.c b/newlib/libc/stdio/funopen.c
index 35a274f..065ed93 100644
--- a/newlib/libc/stdio/funopen.c
+++ b/newlib/libc/stdio/funopen.c
@@ -214,16 +214,16 @@ _DEFUN(_funopen_r, (ptr, cookie, readfn, writefn, seekfn, closefn),
return NULL;
if ((c = (funcookie *) _malloc_r (ptr, sizeof *c)) == NULL)
{
- __sfp_lock_acquire ();
+ _newlib_sfp_lock_start ();
fp->_flags = 0; /* release */
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
- __sfp_lock_release ();
+ _newlib_sfp_lock_end ();
return NULL;
}
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
fp->_file = -1;
c->cookie = (void *) cookie; /* cast away const */
fp->_cookie = c;
@@ -260,7 +260,7 @@ _DEFUN(_funopen_r, (ptr, cookie, readfn, writefn, seekfn, closefn),
#endif
c->closefn = closefn;
fp->_close = funcloser;
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return fp;
}
diff --git a/newlib/libc/stdio/fwide.c b/newlib/libc/stdio/fwide.c
index e298f91..a060d8f 100644
--- a/newlib/libc/stdio/fwide.c
+++ b/newlib/libc/stdio/fwide.c
@@ -68,7 +68,7 @@ _DEFUN(_fwide_r, (ptr, fp, mode),
CHECK_INIT(ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
if (mode != 0) {
ORIENT (fp, mode);
}
@@ -76,7 +76,7 @@ _DEFUN(_fwide_r, (ptr, fp, mode),
ret = 0;
else
ret = (fp->_flags2 & __SWID) ? 1 : -1;
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return ret;
}
diff --git a/newlib/libc/stdio/fwrite.c b/newlib/libc/stdio/fwrite.c
index ce77c8d..dc21805 100644
--- a/newlib/libc/stdio/fwrite.c
+++ b/newlib/libc/stdio/fwrite.c
@@ -119,14 +119,14 @@ _DEFUN(_fwrite_r, (ptr, buf, size, count, fp),
CHECK_INIT(ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT (fp, -1);
if (__sfvwrite_r (ptr, fp, &uio) == 0)
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return count;
}
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return (n - uio.uio_resid) / size;
}
diff --git a/newlib/libc/stdio/getc.c b/newlib/libc/stdio/getc.c
index 5b1fa88..355b191 100644
--- a/newlib/libc/stdio/getc.c
+++ b/newlib/libc/stdio/getc.c
@@ -92,9 +92,9 @@ _DEFUN(_getc_r, (ptr, fp),
{
int result;
CHECK_INIT (ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
result = __sgetc_r (ptr, fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return result;
}
@@ -106,9 +106,9 @@ _DEFUN(getc, (fp),
{
int result;
CHECK_INIT (_REENT, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
result = __sgetc_r (_REENT, fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return result;
}
diff --git a/newlib/libc/stdio/getdelim.c b/newlib/libc/stdio/getdelim.c
index 23fc502..63a579a 100644
--- a/newlib/libc/stdio/getdelim.c
+++ b/newlib/libc/stdio/getdelim.c
@@ -81,7 +81,7 @@ _DEFUN(__getdelim, (bufptr, n, delim, fp),
CHECK_INIT (_REENT, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
numbytes = *n;
ptr = buf;
@@ -129,7 +129,7 @@ _DEFUN(__getdelim, (bufptr, n, delim, fp),
}
}
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
/* if no input data, return failure */
if (ptr == buf)
diff --git a/newlib/libc/stdio/gets.c b/newlib/libc/stdio/gets.c
index 17d1443..f51d461 100644
--- a/newlib/libc/stdio/gets.c
+++ b/newlib/libc/stdio/gets.c
@@ -70,6 +70,7 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
#include <_ansi.h>
#include <reent.h>
#include <stdio.h>
+#include "local.h"
char *
_DEFUN(_gets_r, (ptr, buf),
@@ -79,12 +80,12 @@ _DEFUN(_gets_r, (ptr, buf),
register int c;
register char *s = buf;
- _flockfile (stdin);
+ _newlib_flockfile_start (stdin);
while ((c = __sgetc_r (ptr, stdin)) != '\n')
if (c == EOF)
if (s == buf)
{
- _funlockfile (stdin);
+ _newlib_flockfile_exit (stdin);
return NULL;
}
else
@@ -92,7 +93,7 @@ _DEFUN(_gets_r, (ptr, buf),
else
*s++ = c;
*s = 0;
- _funlockfile (stdin);
+ _newlib_flockfile_end (stdin);
return buf;
}
diff --git a/newlib/libc/stdio/local.h b/newlib/libc/stdio/local.h
index 187f7d8..aeeb0e8 100644
--- a/newlib/libc/stdio/local.h
+++ b/newlib/libc/stdio/local.h
@@ -32,6 +32,83 @@
# include <io.h>
#endif
+/* The following macros are supposed to replace calls to _flockfile/_funlockfile
+ and __sfp_lock_acquire/__sfp_lock_release. In case of multi-threaded
+ environments using pthreads, it's not sufficient to lock the stdio functions
+ against concurrent threads accessing the same data, the locking must also be
+ secured against thread cancellation.
+
+ The below macros have to be used in pairs. The _newlib_XXX_start macro
+ starts with a opening curly brace, the _newlib_XXX_end macro ends with a
+ closing curly brace, so the start macro and the end macro mark the code
+ start and end of a critical section. In case the code leaves the critical
+ section before reaching the end of the critical section's code end, use
+ the appropriate _newlib_XXX_exit macro. */
+
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+#include <pthread.h>
+
+/* Start a stream oriented critical section: */
+# define _newlib_flockfile_start(_fp) \
+ { \
+ int __oldfpcancel; \
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldfpcancel); \
+ _flockfile (_fp)
+
+/* Exit from a stream oriented critical section prematurely: */
+# define _newlib_flockfile_exit(_fp) \
+ _funlockfile (_fp); \
+ pthread_setcancelstate (__oldfpcancel, &__oldfpcancel);
+
+/* End a stream oriented critical section: */
+# define _newlib_flockfile_end(_fp) \
+ _funlockfile (_fp); \
+ pthread_setcancelstate (__oldfpcancel, &__oldfpcancel); \
+ }
+
+/* Start a stream list oriented critical section: */
+# define _newlib_sfp_lock_start() \
+ { \
+ int __oldsfpcancel; \
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldsfpcancel); \
+ __sfp_lock_acquire ()
+
+/* Exit from a stream list oriented critical section prematurely: */
+# define _newlib_sfp_lock_exit() \
+ __sfp_lock_release (); \
+ pthread_setcancelstate (__oldsfpcancel, &__oldsfpcancel);
+
+/* End a stream list oriented critical section: */
+# define _newlib_sfp_lock_end() \
+ __sfp_lock_release (); \
+ pthread_setcancelstate (__oldsfpcancel, &__oldsfpcancel); \
+ }
+
+#else /* __SINGLE_THREAD__ || !_POSIX_THREADS */
+
+# define _newlib_flockfile_start(_fp) \
+ { \
+ _flockfile(_fp)
+
+# define _newlib_flockfile_exit(_fp) \
+ _funlockfile(_fp); \
+
+# define _newlib_flockfile_end(_fp) \
+ _funlockfile(_fp); \
+ }
+
+# define _newlib_sfp_lock_start() \
+ { \
+ __sfp_lock_acquire ()
+
+# define _newlib_sfp_lock_end() \
+ __sfp_lock_release ();
+
+# define _newlib_sfp_lock_end() \
+ __sfp_lock_release (); \
+ }
+
+#endif /* !__SINGLE_THREAD__ && _POSIX_THREADS */
extern u_char *_EXFUN(__sccl, (char *, u_char *fmt));
extern int _EXFUN(__svfscanf_r,(struct _reent *,FILE *, _CONST char *,va_list));
diff --git a/newlib/libc/stdio/open_memstream.c b/newlib/libc/stdio/open_memstream.c
index a53bdef..0b58720 100644
--- a/newlib/libc/stdio/open_memstream.c
+++ b/newlib/libc/stdio/open_memstream.c
@@ -313,12 +313,12 @@ _DEFUN(internal_open_memstream_r, (ptr, buf, size, wide),
return NULL;
if ((c = (memstream *) _malloc_r (ptr, sizeof *c)) == NULL)
{
- __sfp_lock_acquire ();
+ _newlib_sfp_lock_start ();
fp->_flags = 0; /* release */
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
- __sfp_lock_release ();
+ _newlib_sfp_lock_end ();
return NULL;
}
/* Use *size as a hint for initial sizing, but bound the initial
@@ -338,12 +338,12 @@ _DEFUN(internal_open_memstream_r, (ptr, buf, size, wide),
*buf = _malloc_r (ptr, c->max);
if (!*buf)
{
- __sfp_lock_acquire ();
+ _newlib_sfp_lock_start ();
fp->_flags = 0; /* release */
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
- __sfp_lock_release ();
+ _newlib_sfp_lock_end ();
_free_r (ptr, c);
return NULL;
}
@@ -359,7 +359,7 @@ _DEFUN(internal_open_memstream_r, (ptr, buf, size, wide),
c->saved.w = L'\0';
c->wide = (int8_t) wide;
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
fp->_file = -1;
fp->_flags = __SWR;
fp->_cookie = c;
@@ -372,7 +372,7 @@ _DEFUN(internal_open_memstream_r, (ptr, buf, size, wide),
#endif
fp->_close = memcloser;
ORIENT (fp, wide);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return fp;
}
diff --git a/newlib/libc/stdio/putc.c b/newlib/libc/stdio/putc.c
index 667324d..1115bf4 100644
--- a/newlib/libc/stdio/putc.c
+++ b/newlib/libc/stdio/putc.c
@@ -97,9 +97,9 @@ _DEFUN(_putc_r, (ptr, c, fp),
{
int result;
CHECK_INIT (ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
result = __sputc_r (ptr, c, fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return result;
}
@@ -112,9 +112,9 @@ _DEFUN(putc, (c, fp),
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
int result;
CHECK_INIT (_REENT, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
result = __sputc_r (_REENT, c, fp);
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return result;
#else
return _putc_r (_REENT, c, fp);
diff --git a/newlib/libc/stdio/setvbuf.c b/newlib/libc/stdio/setvbuf.c
index 583a081..63f1f80 100644
--- a/newlib/libc/stdio/setvbuf.c
+++ b/newlib/libc/stdio/setvbuf.c
@@ -106,7 +106,7 @@ _DEFUN(setvbuf, (fp, buf, mode, size),
CHECK_INIT (_REENT, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
/*
* Verify arguments. The `int' limit on `size' is due to this
@@ -115,7 +115,7 @@ _DEFUN(setvbuf, (fp, buf, mode, size),
if ((mode != _IOFBF && mode != _IOLBF && mode != _IONBF) || (int)(_POINTER_INT) size < 0)
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return (EOF);
}
@@ -158,7 +158,7 @@ nbf:
fp->_w = 0;
fp->_bf._base = fp->_p = fp->_nbuf;
fp->_bf._size = 1;
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return (ret);
}
fp->_flags |= __SMBF;
@@ -193,6 +193,6 @@ nbf:
if (fp->_flags & __SWR)
fp->_w = fp->_flags & (__SLBF | __SNBF) ? 0 : size;
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return 0;
}
diff --git a/newlib/libc/stdio/ungetc.c b/newlib/libc/stdio/ungetc.c
index 0339a3d..e385ce8 100644
--- a/newlib/libc/stdio/ungetc.c
+++ b/newlib/libc/stdio/ungetc.c
@@ -125,7 +125,7 @@ _DEFUN(_ungetc_r, (rptr, c, fp),
CHECK_INIT (rptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT (fp, -1);
@@ -140,14 +140,14 @@ _DEFUN(_ungetc_r, (rptr, c, fp),
*/
if ((fp->_flags & __SRW) == 0)
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return EOF;
}
if (fp->_flags & __SWR)
{
if (_fflush_r (rptr, fp))
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return EOF;
}
fp->_flags &= ~__SWR;
@@ -167,12 +167,12 @@ _DEFUN(_ungetc_r, (rptr, c, fp),
{
if (fp->_r >= fp->_ub._size && __submore (rptr, fp))
{
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return EOF;
}
*--fp->_p = c;
fp->_r++;
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return c;
}
@@ -186,7 +186,7 @@ _DEFUN(_ungetc_r, (rptr, c, fp),
{
fp->_p--;
fp->_r++;
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return c;
}
@@ -202,7 +202,7 @@ _DEFUN(_ungetc_r, (rptr, c, fp),
fp->_ubuf[sizeof (fp->_ubuf) - 1] = c;
fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - 1];
fp->_r = 1;
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return c;
}
diff --git a/newlib/libc/stdio/ungetwc.c b/newlib/libc/stdio/ungetwc.c
index 234d2f7..ee0d7fc 100644
--- a/newlib/libc/stdio/ungetwc.c
+++ b/newlib/libc/stdio/ungetwc.c
@@ -82,7 +82,7 @@ _DEFUN(_ungetwc_r, (ptr, wc, fp),
char buf[MB_LEN_MAX];
size_t len;
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT (fp, 1);
if (wc == WEOF)
wc = WEOF;
@@ -98,7 +98,7 @@ _DEFUN(_ungetwc_r, (ptr, wc, fp),
wc = WEOF;
break;
}
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return wc;
}
diff --git a/newlib/libc/stdio/vfprintf.c b/newlib/libc/stdio/vfprintf.c
index e3fc099..5598991 100644
--- a/newlib/libc/stdio/vfprintf.c
+++ b/newlib/libc/stdio/vfprintf.c
@@ -708,20 +708,20 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
#ifndef STRING_ONLY
/* Initialize std streams if not dealing with sprintf family. */
CHECK_INIT (data, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT(fp, -1);
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
if (cantwrite (data, fp)) {
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return (EOF);
}
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
fp->_file >= 0) {
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return (__sbprintf (data, fp, fmt0, ap));
}
#else /* STRING_ONLY */
@@ -1633,7 +1633,7 @@ error:
if (malloc_buf != NULL)
_free_r (data, malloc_buf);
#ifndef STRING_ONLY
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
#endif
return (__sferror (fp) ? EOF : ret);
/* NOTREACHED */
diff --git a/newlib/libc/stdio/vfscanf.c b/newlib/libc/stdio/vfscanf.c
index 32a132a..e05082d 100644
--- a/newlib/libc/stdio/vfscanf.c
+++ b/newlib/libc/stdio/vfscanf.c
@@ -148,10 +148,12 @@ Supporting OS subroutines required:
#endif
#ifdef STRING_ONLY
-#undef _flockfile
-#undef _funlockfile
-#define _flockfile(x) {}
-#define _funlockfile(x) {}
+#undef _newlib_flockfile_start
+#undef _newlib_flockfile_exit
+#undef _newlib_flockfile_end
+#define _newlib_flockfile_start(x) {}
+#define _newlib_flockfile_exit(x) {}
+#define _newlib_flockfile_end(x) {}
#define _ungetc_r _sungetc_r
#define __srefill_r __ssrefill_r
#define _fread_r _sfread_r
@@ -496,7 +498,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
# define GET_ARG(n, ap, type) (va_arg (ap, type))
#endif
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT (fp, -1);
@@ -795,7 +797,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
* Disgusting backwards compatibility hacks. XXX
*/
case '\0': /* compat */
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return EOF;
default: /* compat */
@@ -1595,12 +1597,12 @@ input_failure:
should have been set prior to here. On EOF failure (including
invalid format string), return EOF if no matches yet, else number
of matches made prior to failure. */
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return nassigned && !(fp->_flags & __SERR) ? nassigned : EOF;
match_failure:
all_done:
/* Return number of matches, which can be 0 on match failure. */
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return nassigned;
}
diff --git a/newlib/libc/stdio/vfwprintf.c b/newlib/libc/stdio/vfwprintf.c
index d76fff0..029f1d0 100644
--- a/newlib/libc/stdio/vfwprintf.c
+++ b/newlib/libc/stdio/vfwprintf.c
@@ -553,20 +553,20 @@ _DEFUN(_VFWPRINTF_R, (data, fp, fmt0, ap),
#ifndef STRING_ONLY
/* Initialize std streams if not dealing with sprintf family. */
CHECK_INIT (data, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT(fp, 1);
/* sorry, fwprintf(read_only_file, "") returns EOF, not 0 */
if (cantwrite (data, fp)) {
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return (EOF);
}
/* optimise fwprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
fp->_file >= 0) {
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return (__sbwprintf (data, fp, fmt0, ap));
}
#else /* STRING_ONLY */
@@ -1465,7 +1465,7 @@ error:
if (malloc_buf != NULL)
_free_r (data, malloc_buf);
#ifndef STRING_ONLY
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
#endif
return (__sferror (fp) ? EOF : ret);
/* NOTREACHED */
diff --git a/newlib/libc/stdio/vfwscanf.c b/newlib/libc/stdio/vfwscanf.c
index 49ccf2f..5d2388d 100644
--- a/newlib/libc/stdio/vfwscanf.c
+++ b/newlib/libc/stdio/vfwscanf.c
@@ -145,10 +145,12 @@ C99, POSIX-1.2008
#endif
#ifdef STRING_ONLY
-#undef _flockfile
-#undef _funlockfile
-#define _flockfile(x) {}
-#define _funlockfile(x) {}
+#undef _newlib_flockfile_start
+#undef _newlib_flockfile_exit
+#undef _newlib_flockfile_end
+#define _newlib_flockfile_start(x) {}
+#define _newlib_flockfile_exit(x) {}
+#define _newlib_flockfile_end(x) {}
#define _ungetwc_r _sungetwc_r
#define __srefill_r __ssrefill_r
#define _fgetwc_r _sfgetwc_r
@@ -434,7 +436,7 @@ _DEFUN(__SVFWSCANF_R, (rptr, fp, fmt0, ap),
# define GET_ARG(n, ap, type) (va_arg (ap, type))
#endif
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
ORIENT (fp, 1);
@@ -712,7 +714,7 @@ _DEFUN(__SVFWSCANF_R, (rptr, fp, fmt0, ap),
* Disgusting backwards compatibility hacks. XXX
*/
case L'\0': /* compat */
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return EOF;
default: /* compat */
@@ -1440,12 +1442,12 @@ input_failure:
should have been set prior to here. On EOF failure (including
invalid format string), return EOF if no matches yet, else number
of matches made prior to failure. */
- _funlockfile (fp);
+ _newlib_flockfile_exit (fp);
return nassigned && !(fp->_flags & __SERR) ? nassigned : EOF;
match_failure:
all_done:
/* Return number of matches, which can be 0 on match failure. */
- _funlockfile (fp);
+ _newlib_flockfile_end (fp);
return nassigned;
}
diff --git a/newlib/libc/stdio64/fdopen64.c b/newlib/libc/stdio64/fdopen64.c
index 49d1f03..659d343 100644
--- a/newlib/libc/stdio64/fdopen64.c
+++ b/newlib/libc/stdio64/fdopen64.c
@@ -64,7 +64,7 @@ _DEFUN (_fdopen64_r, (ptr, fd, mode),
if ((fp = __sfp (ptr)) == 0)
return 0;
- _flockfile(fp);
+ _newlib_flockfile_start(fp);
fp->_flags = flags;
/* POSIX recommends setting the O_APPEND bit on fd to match append
@@ -101,7 +101,7 @@ _DEFUN (_fdopen64_r, (ptr, fd, mode),
fp->_flags |= __SL64;
- _funlockfile(fp);
+ _newlib_flockfile_end(fp);
return fp;
}
diff --git a/newlib/libc/stdio64/fopen64.c b/newlib/libc/stdio64/fopen64.c
index aa67751..84f7b6e 100644
--- a/newlib/libc/stdio64/fopen64.c
+++ b/newlib/libc/stdio64/fopen64.c
@@ -91,16 +91,16 @@ _DEFUN (_fopen64_r, (ptr, file, mode),
if ((f = _open64_r (ptr, file, oflags, 0666)) < 0)
{
- __sfp_lock_acquire ();
+ _newlib_sfp_lock_start ();
fp->_flags = 0; /* release */
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
- __sfp_lock_release ();
+ _newlib_sfp_lock_end ();
return NULL;
}
- _flockfile(fp);
+ _newlib_flockfile_start (fp);
fp->_file = f;
fp->_flags = flags;
@@ -121,7 +121,7 @@ _DEFUN (_fopen64_r, (ptr, file, mode),
fp->_flags |= __SL64;
- _funlockfile(fp);
+ _newlib_flockfile_end (fp);
return fp;
}
diff --git a/newlib/libc/stdio64/freopen64.c b/newlib/libc/stdio64/freopen64.c
index 1e2ec78..db0e1ee 100644
--- a/newlib/libc/stdio64/freopen64.c
+++ b/newlib/libc/stdio64/freopen64.c
@@ -100,11 +100,20 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp),
CHECK_INIT (ptr, fp);
- _flockfile(fp);
+ /* We can't use the _newlib_flockfile_XXX macros here due to the
+ interlocked locking with the sfp_lock. */
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+ int __oldcancel;
+ pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &__oldcancel);
+#endif
+ _flockfile (fp);
if ((flags = __sflags (ptr, mode, &oflags)) == 0)
{
- _funlockfile(fp);
+ _funlockfile (fp);
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+ pthread_setcancelstate (__oldcancel, &__oldcancel);
+#endif
_fclose_r (ptr, fp);
return NULL;
}
@@ -205,11 +214,14 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp),
__sfp_lock_acquire ();
fp->_flags = 0; /* set it free */
ptr->_errno = e; /* restore in case _close clobbered */
- _funlockfile(fp);
+ _funlockfile (fp);
#ifndef __SINGLE_THREAD__
__lock_close_recursive (fp->_lock);
#endif
__sfp_lock_release ();
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+ pthread_setcancelstate (__oldcancel, &__oldcancel);
+#endif
return NULL;
}
@@ -229,7 +241,10 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp),
fp->_flags |= __SL64;
- _funlockfile(fp);
+ _funlockfile (fp);
+#if !defined (__SINGLE_THREAD__) && defined (_POSIX_THREADS)
+ pthread_setcancelstate (__oldcancel, &__oldcancel);
+#endif
return fp;
}
diff --git a/newlib/libc/stdio64/fseeko64.c b/newlib/libc/stdio64/fseeko64.c
index 301d6f5..b323f97 100644
--- a/newlib/libc/stdio64/fseeko64.c
+++ b/newlib/libc/stdio64/fseeko64.c
@@ -126,7 +126,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence),
CHECK_INIT (ptr, fp);
- _flockfile (fp);
+ _newlib_flockfile_start (fp);
curoff = fp->_offset;
@@ -144,7 +144,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence),
if ((seekfn = fp->_seek64) == NULL)
{
ptr->_errno = ESPIPE; /* ??? */
- _funlockfile(fp);
+ _newlib_flockfile_exit(fp);
return EOF;
}
@@ -169,7 +169,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence),
curoff = seekfn (ptr, fp->_cookie, (_fpos64_t) 0, SEEK_CUR);
if (curoff == -1L)
{
- _funlockfile(fp);
+ _newlib_flockfile_exit(fp);
return EOF;
}
}
@@ -194,7 +194,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence),
default:
ptr->_errno = EINVAL;
- _funlockfile(fp);
+ _newlib_flockfile_exit(fp);
return (EOF);
}
@@ -294,7 +294,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence),
if (HASUB (fp))
FREEUB (ptr, fp);
fp->_flags &= ~__SEOF;
- _funlockfile(fp);
+ _newlib_flockfile_exit(fp);
return 0;
}
@@ -323,7 +323,7 @@ _DEFUN (_fseeko64_r, (ptr, fp, offset, whence),
fp->_p += n;
fp->_r -= n;
}
- _funlockfile(fp);
+ _newlib_flockfile_end(fp);
return 0;
/*
diff --git a/newlib/libc/stdio64/ftello64.c b/newlib/libc/stdio64/ftello64.c
index 51dcd27..c4d6da2 100644
--- a/newlib/libc/stdio64/ftello64.c
+++ b/newlib/libc/stdio64/ftello64.c
@@ -99,12 +99,12 @@ _DEFUN (_ftello64_r, (ptr, fp),
CHECK_INIT (ptr, fp);
- _flockfile(fp);
+ _newlib_flockfile_start(fp);
if (fp->_seek64 == NULL)
{
ptr->_errno = ESPIPE;
- _funlockfile(fp);
+ _newlib_flockfile_exit(fp);
return -1L;
}
@@ -121,7 +121,7 @@ _DEFUN (_ftello64_r, (ptr, fp),
pos = fp->_seek64 (ptr, fp->_cookie, (_fpos64_t) 0, SEEK_CUR);
if (pos == -1L)
{
- _funlockfile(fp);
+ _newlib_flockfile_exit(fp);
return pos;
}
}
@@ -146,7 +146,7 @@ _DEFUN (_ftello64_r, (ptr, fp),
pos += fp->_p - fp->_bf._base;
}
- _funlockfile(fp);
+ _newlib_flockfile_end(fp);
return pos;
}