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