* 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:
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user