* 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.
This commit is contained in:
Corinna Vinschen 2012-05-30 08:58:42 +00:00
parent 75b6133098
commit 4aa28d8ae2
46 changed files with 301 additions and 161 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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));

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
/*

View File

@ -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;
}