2004-03-25 Thomas Pfaff <tpfaff@gmx.net>
* libc/stdio/fclose.c (fclose): Protect file pointer list when
        releasing a file.
         * libc/stdio/fcloseall.c (_fcloseall_r): Close all files via
        fwalk.
        * libc/stdio/fdopen.c (_fdopen_r): Add calls to
        _flockfile/_funlockfile.
        * libc/stdio/findfp.c: Move __sfp_lock. Change __sfp_lock type
        to recursive.
        Change __lock_acquire/__lock_release calls for __sfp_lock to
        __sfp_lock_acquire/__sfp_lock_release throughout.
        (std): Make sure that file lock is only initialized once.
        (__sfp): Move _file initialization. Initialize file lock.
        (__sfp_lock_acquire): New function.
        (__sfp_lock_release): Ditto.
        (__fp_lock_all): Remove __sfp_lock_acquire call.
        (__fp_unlock_all): Remove __sfp_lock_release call.
        * libc/stdio/fopen.c (_fopen_r): Protect file pointer list.
        Add calls to _flockfile/_funlockfile. Remove
        __lock_init_recursive call.
        * libc/stdio/freopen.c (_freopen_r): Protect file pointer list.
        * libc/stdio/fwalk.c (__fwalk): New static function.
        (_fwalk): Protect file pointer list. Use __fwalk to walk through
        file pointers.
        * libc/stdio/local.h: Add defines for
        __sfp_lock_acquire/__sfp_lock_release when
        single threaded. Add function prototypes otherwise.
        * libc/stdio64/fdopen64.c (_fdopen64_r): Add calls to
        _flockfile/_funlockfile.
        * libc/stdio/fopen64.c (_fopen64_r): Protect file pointer list.
        Add calls to _flockfile/_funlockfile. Remove
         __lock_init_recursive call.
        * libc/stdio/freopen64.c (_freopen64_r): Protect file pointer
        list.
			
			
This commit is contained in:
		| @@ -1,3 +1,39 @@ | ||||
| 2004-03-25  Thomas Pfaff  <tpfaff@gmx.net> | ||||
|  | ||||
| 	* libc/stdio/fclose.c (fclose): Protect file pointer list when | ||||
| 	releasing a file. | ||||
| 	 * libc/stdio/fcloseall.c (_fcloseall_r): Close all files via | ||||
| 	fwalk. | ||||
| 	* libc/stdio/fdopen.c (_fdopen_r): Add calls to | ||||
| 	_flockfile/_funlockfile. | ||||
| 	* libc/stdio/findfp.c: Move __sfp_lock. Change __sfp_lock type | ||||
| 	to recursive. | ||||
| 	Change __lock_acquire/__lock_release calls for __sfp_lock to | ||||
| 	__sfp_lock_acquire/__sfp_lock_release throughout. | ||||
| 	(std): Make sure that file lock is only initialized once. | ||||
| 	(__sfp): Move _file initialization. Initialize file lock. | ||||
| 	(__sfp_lock_acquire): New function. | ||||
| 	(__sfp_lock_release): Ditto. | ||||
| 	(__fp_lock_all): Remove __sfp_lock_acquire call. | ||||
| 	(__fp_unlock_all): Remove __sfp_lock_release call. | ||||
| 	* libc/stdio/fopen.c (_fopen_r): Protect file pointer list. | ||||
| 	Add calls to _flockfile/_funlockfile. Remove | ||||
| 	__lock_init_recursive call. | ||||
| 	* libc/stdio/freopen.c (_freopen_r): Protect file pointer list. | ||||
| 	* libc/stdio/fwalk.c (__fwalk): New static function. | ||||
| 	(_fwalk): Protect file pointer list. Use __fwalk to walk through | ||||
| 	file pointers. | ||||
| 	* libc/stdio/local.h: Add defines for | ||||
| 	__sfp_lock_acquire/__sfp_lock_release when | ||||
| 	single threaded. Add function prototypes otherwise. | ||||
| 	* libc/stdio64/fdopen64.c (_fdopen64_r): Add calls to | ||||
| 	_flockfile/_funlockfile. | ||||
| 	* libc/stdio/fopen64.c (_fopen64_r): Protect file pointer list. | ||||
| 	Add calls to _flockfile/_funlockfile. Remove | ||||
| 	 __lock_init_recursive call. | ||||
| 	* libc/stdio/freopen64.c (_freopen64_r): Protect file pointer | ||||
| 	list.  | ||||
|  | ||||
| 2004-03-25  Jeff Johnston  <jjohnstn@redhat.com> | ||||
|  | ||||
| 	* libc/sys/linux/sys/lock.h: Turn on __USE_GNU flag if not already | ||||
|   | ||||
| @@ -65,6 +65,8 @@ _DEFUN (fclose, (fp), | ||||
|   if (fp == NULL) | ||||
|     return (0);			/* on NULL */ | ||||
|  | ||||
|   __sfp_lock_acquire (); | ||||
|  | ||||
|   _flockfile(fp); | ||||
|    | ||||
|   CHECK_INIT (fp); | ||||
| @@ -72,6 +74,7 @@ _DEFUN (fclose, (fp), | ||||
|   if (fp->_flags == 0)		/* not open! */ | ||||
|     { | ||||
|       _funlockfile(fp); | ||||
|       __sfp_lock_release (); | ||||
|       return (0); | ||||
|     } | ||||
|   r = fp->_flags & __SWR ? fflush (fp) : 0; | ||||
| @@ -83,11 +86,13 @@ _DEFUN (fclose, (fp), | ||||
|     FREEUB (fp); | ||||
|   if (HASLB (fp)) | ||||
|     FREELB (fp); | ||||
|   fp->_flags = 0;		/* release this FILE for reuse */ | ||||
|   _funlockfile(fp); | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|   __lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock); | ||||
| #endif | ||||
|   fp->_flags = 0;		/* release this FILE for reuse */ | ||||
|  | ||||
|   __sfp_lock_release (); | ||||
|  | ||||
|   return (r); | ||||
| } | ||||
|   | ||||
| @@ -66,15 +66,7 @@ int | ||||
| _fcloseall_r (ptr) | ||||
|      struct _reent *ptr; | ||||
| { | ||||
|   register FILE *fp; | ||||
|   register int n, ret = 0; | ||||
|   register struct _glue *g; | ||||
|  | ||||
|   for (g = &ptr->__sglue; g != NULL; g = g->_next) | ||||
|     for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++) | ||||
|       if (fp->_flags != 0) | ||||
|         ret |= fclose (fp); | ||||
|   return ret; | ||||
|   return _fwalk (ptr, fclose); | ||||
| } | ||||
|  | ||||
| #ifndef _REENT_ONLY | ||||
|   | ||||
| @@ -76,6 +76,9 @@ _DEFUN (_fdopen_r, (ptr, fd, mode), | ||||
|  | ||||
|   if ((fp = __sfp (ptr)) == 0) | ||||
|     return 0; | ||||
|  | ||||
|   _flockfile(fp); | ||||
|  | ||||
|   fp->_flags = flags; | ||||
|   /* | ||||
|    * If opened for appending, but underlying descriptor | ||||
| @@ -111,6 +114,7 @@ _DEFUN (_fdopen_r, (ptr, fd, mode), | ||||
|     fp->_flags |= __SCLE; | ||||
| #endif | ||||
|  | ||||
|   _funlockfile(fp); | ||||
|   return fp; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -25,10 +25,6 @@ | ||||
| #include <sys/lock.h> | ||||
| #include "local.h" | ||||
|  | ||||
| #ifndef __SINGLE_THREAD__ | ||||
| __LOCK_INIT(static, __sfp_lock); | ||||
| #endif | ||||
|  | ||||
| static void | ||||
| std (ptr, flags, file, data) | ||||
|      FILE *ptr; | ||||
| @@ -49,8 +45,12 @@ std (ptr, flags, file, data) | ||||
|   ptr->_write = __swrite; | ||||
|   ptr->_seek = __sseek; | ||||
|   ptr->_close = __sclose; | ||||
| #ifndef __SINGLE_THREAD__ | ||||
| #if !defined(__SINGLE_THREAD__) && !defined(_REENT_SMALL) | ||||
|   __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&ptr->_lock); | ||||
|   /* | ||||
|    * #else | ||||
|    * lock is already initialized in __sfp | ||||
|    */ | ||||
| #endif | ||||
|  | ||||
| #ifdef __SCLE | ||||
| @@ -90,9 +90,7 @@ __sfp (d) | ||||
|   int n; | ||||
|   struct _glue *g; | ||||
|  | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|   __lock_acquire(__sfp_lock);  | ||||
| #endif | ||||
|   __sfp_lock_acquire ();  | ||||
|  | ||||
|   if (!_GLOBAL_REENT->__sdidinit) | ||||
|     __sinit (_GLOBAL_REENT); | ||||
| @@ -105,24 +103,24 @@ __sfp (d) | ||||
| 	  (g->_next = __sfmoreglue (d, NDYNAMIC)) == NULL) | ||||
| 	break; | ||||
|     } | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|   __lock_release(__sfp_lock);  | ||||
| #endif | ||||
|   __sfp_lock_release ();  | ||||
|   d->_errno = ENOMEM; | ||||
|   return NULL; | ||||
|  | ||||
| found: | ||||
|   fp->_file = -1;		/* no file */ | ||||
|   fp->_flags = 1;		/* reserve this slot; caller sets real flags */ | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|   __lock_release(__sfp_lock);  | ||||
|   __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock); | ||||
| #endif | ||||
|   __sfp_lock_release ();  | ||||
|  | ||||
|   fp->_p = NULL;		/* no current pointer */ | ||||
|   fp->_w = 0;			/* nothing to read or write */ | ||||
|   fp->_r = 0; | ||||
|   fp->_bf._base = NULL;		/* no buffer */ | ||||
|   fp->_bf._size = 0; | ||||
|   fp->_lbfsize = 0;		/* not line buffered */ | ||||
|   fp->_file = -1;		/* no file */ | ||||
|   /* fp->_cookie = <any>; */	/* caller sets cookie, _read/_write etc */ | ||||
|   fp->_ub._base = NULL;		/* no ungetc buffer */ | ||||
|   fp->_ub._size = 0; | ||||
| @@ -197,6 +195,20 @@ __sinit (s) | ||||
|  | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|  | ||||
| __LOCK_INIT_RECURSIVE(static, __sfp_lock); | ||||
|  | ||||
| void | ||||
| __sfp_lock_acquire () | ||||
| { | ||||
|   __lock_acquire(__sfp_lock);  | ||||
| } | ||||
|  | ||||
| void | ||||
| __sfp_lock_release () | ||||
| { | ||||
|   __lock_release(__sfp_lock);  | ||||
| } | ||||
|  | ||||
| /* Walkable file locking routine.  */ | ||||
| static int | ||||
| __fp_lock (ptr) | ||||
| @@ -220,8 +232,6 @@ __fp_unlock (ptr) | ||||
| void | ||||
| __fp_lock_all () | ||||
| { | ||||
|   __lock_acquire(__sfp_lock);  | ||||
|  | ||||
|   (void) _fwalk (_REENT, __fp_lock); | ||||
| } | ||||
|  | ||||
| @@ -229,7 +239,5 @@ void | ||||
| __fp_unlock_all () | ||||
| { | ||||
|   (void) _fwalk (_REENT, __fp_unlock); | ||||
|  | ||||
|   __lock_release(__sfp_lock);  | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -138,10 +138,17 @@ _DEFUN (_fopen_r, (ptr, file, mode), | ||||
|  | ||||
|   if ((f = _open_r (ptr, file, oflags, 0666)) < 0) | ||||
|     { | ||||
|       __sfp_lock_acquire ();  | ||||
|       fp->_flags = 0;		/* release */ | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|       __lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock); | ||||
| #endif | ||||
|       __sfp_lock_release ();  | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
|   _flockfile(fp); | ||||
|  | ||||
|   fp->_file = f; | ||||
|   fp->_flags = flags; | ||||
|   fp->_cookie = (_PTR) fp; | ||||
| @@ -158,10 +165,7 @@ _DEFUN (_fopen_r, (ptr, file, mode), | ||||
|     fp->_flags |= __SCLE; | ||||
| #endif | ||||
|  | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|   __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock); | ||||
| #endif | ||||
|  | ||||
|   _funlockfile(fp); | ||||
|   return fp; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -87,14 +87,17 @@ _DEFUN (_freopen_r, (ptr, file, mode, fp), | ||||
|   register int f; | ||||
|   int flags, oflags, e; | ||||
|  | ||||
|   __sfp_lock_acquire (); | ||||
|  | ||||
|   _flockfile(fp); | ||||
|  | ||||
|   CHECK_INIT (fp); | ||||
|  | ||||
|   if ((flags = __sflags (ptr, mode, &oflags)) == 0) | ||||
|     { | ||||
|       (void) fclose (fp); | ||||
|       _funlockfile(fp); | ||||
|       (void) fclose (fp); | ||||
|       __sfp_lock_release (); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
| @@ -148,12 +151,13 @@ _DEFUN (_freopen_r, (ptr, file, mode, fp), | ||||
|  | ||||
|   if (f < 0) | ||||
|     {				/* did not get it after all */ | ||||
|       fp->_flags = 0;		/* set it free */ | ||||
|       ptr->_errno = e;		/* restore in case _close clobbered */ | ||||
|       _funlockfile(fp); | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|       __lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock); | ||||
| #endif | ||||
|       fp->_flags = 0;		/* set it free */ | ||||
|       __sfp_lock_release (); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
| @@ -171,6 +175,7 @@ _DEFUN (_freopen_r, (ptr, file, mode, fp), | ||||
| #endif | ||||
|  | ||||
|   _funlockfile(fp); | ||||
|   __sfp_lock_release (); | ||||
|   return fp; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -26,8 +26,8 @@ static char sccsid[] = "%W% (Berkeley) %G%"; | ||||
| #include <errno.h> | ||||
| #include "local.h" | ||||
|  | ||||
| int | ||||
| _fwalk (ptr, function) | ||||
| static int | ||||
| __fwalk (ptr, function) | ||||
|      struct _reent *ptr; | ||||
|      register int (*function) (); | ||||
| { | ||||
| @@ -35,20 +35,36 @@ _fwalk (ptr, function) | ||||
|   register int n, ret = 0; | ||||
|   register struct _glue *g; | ||||
|  | ||||
|   /* Must traverse given list for std streams.  */ | ||||
|   if (ptr != _GLOBAL_REENT) | ||||
|     { | ||||
|       for (g = &ptr->__sglue; g != NULL; g = g->_next) | ||||
|         for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++) | ||||
|           if (fp->_flags != 0) | ||||
| 	    ret |= (*function) (fp); | ||||
|     } | ||||
|  | ||||
|   /* Must traverse global list for all other streams.  */ | ||||
|   for (g = &_GLOBAL_REENT->__sglue; g != NULL; g = g->_next) | ||||
|   for (g = &ptr->__sglue; g != NULL; g = g->_next) | ||||
|     for (fp = g->_iobs, n = g->_niobs; --n >= 0; fp++) | ||||
|       if (fp->_flags != 0) | ||||
| 	ret |= (*function) (fp); | ||||
|         { | ||||
|           _flockfile (fp); | ||||
|           if (fp->_flags != 0 && fp->_file != -1) | ||||
|             ret |= (*function) (fp); | ||||
|           _funlockfile (fp); | ||||
|         } | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| int | ||||
| _fwalk (ptr, function) | ||||
|      struct _reent *ptr; | ||||
|      register int (*function) (); | ||||
| { | ||||
|   register int ret = 0; | ||||
|  | ||||
|   __sfp_lock_acquire (); | ||||
|  | ||||
|   /* Must traverse given list for std streams.  */ | ||||
|   if (ptr != _GLOBAL_REENT) | ||||
|     ret |= __fwalk (ptr, function); | ||||
|  | ||||
|   /* Must traverse global list for all other streams.  */ | ||||
|   ret |= __fwalk (_GLOBAL_REENT, function); | ||||
|  | ||||
|   __sfp_lock_release (); | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
|   | ||||
| @@ -87,3 +87,11 @@ char *_EXFUN(_llicvt,(char *, long long, char)); | ||||
| #define CVT_BUF_SIZE 128 | ||||
|  | ||||
| #define	NDYNAMIC 4	/* add four more whenever necessary */ | ||||
|  | ||||
| #ifdef __SINGLE_THREAD__ | ||||
| #define __sfp_lock_acquire() | ||||
| #define __sfp_lock_release() | ||||
| #else | ||||
| void _EXFUN(__sfp_lock_acquire,(void)); | ||||
| void _EXFUN(__sfp_lock_release,(void)); | ||||
| #endif | ||||
|   | ||||
| @@ -63,6 +63,9 @@ _DEFUN (_fdopen64_r, (ptr, fd, mode), | ||||
|  | ||||
|   if ((fp = __sfp (ptr)) == 0) | ||||
|     return 0; | ||||
|  | ||||
|   _flockfile(fp); | ||||
|  | ||||
|   fp->_flags = flags; | ||||
|   /* | ||||
|    * If opened for appending, but underlying descriptor | ||||
| @@ -99,12 +102,9 @@ _DEFUN (_fdopen64_r, (ptr, fd, mode), | ||||
|     fp->_flags |= __SCLE; | ||||
| #endif | ||||
|  | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|   __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock); | ||||
| #endif | ||||
|  | ||||
|   fp->_flags |= __SL64; | ||||
|  | ||||
|   _funlockfile(fp); | ||||
|   return fp; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -91,10 +91,17 @@ _DEFUN (_fopen64_r, (ptr, file, mode), | ||||
|  | ||||
|   if ((f = _open64_r (ptr, file, oflags, 0666)) < 0) | ||||
|     { | ||||
|       __sfp_lock_acquire ();  | ||||
|       fp->_flags = 0;		/* release */ | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|       __lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock); | ||||
| #endif | ||||
|       __sfp_lock_release ();  | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
|   _flockfile(fp); | ||||
|  | ||||
|   fp->_file = f; | ||||
|   fp->_flags = flags; | ||||
|   fp->_cookie = (_PTR) fp; | ||||
| @@ -114,10 +121,7 @@ _DEFUN (_fopen64_r, (ptr, file, mode), | ||||
|  | ||||
|   fp->_flags |= __SL64; | ||||
|  | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|   __lock_init_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock); | ||||
| #endif | ||||
|  | ||||
|   _funlockfile(fp); | ||||
|   return fp; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -70,6 +70,7 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, | ||||
| #include <stdio.h> | ||||
| #include <fcntl.h> | ||||
| #include <stdlib.h> | ||||
| #include <sys/lock.h> | ||||
| #include "local64.h" | ||||
|  | ||||
| /* | ||||
| @@ -88,14 +89,17 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp), | ||||
|   register int f; | ||||
|   int flags, oflags, e; | ||||
|  | ||||
|   __sfp_lock_acquire (); | ||||
|  | ||||
|   _flockfile(fp); | ||||
|  | ||||
|   CHECK_INIT (fp); | ||||
|  | ||||
|   if ((flags = __sflags (ptr, mode, &oflags)) == 0) | ||||
|     { | ||||
|       (void) fclose (fp); | ||||
|       _funlockfile(fp); | ||||
|       (void) fclose (fp); | ||||
|       __sfp_lock_release (); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
| @@ -152,6 +156,10 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp), | ||||
|       fp->_flags = 0;		/* set it free */ | ||||
|       ptr->_errno = e;		/* restore in case _close clobbered */ | ||||
|       _funlockfile(fp); | ||||
| #ifndef __SINGLE_THREAD__ | ||||
|       __lock_close_recursive (*(_LOCK_RECURSIVE_T *)&fp->_lock); | ||||
| #endif | ||||
|       __sfp_lock_release (); | ||||
|       return NULL; | ||||
|     } | ||||
|  | ||||
| @@ -172,6 +180,7 @@ _DEFUN (_freopen64_r, (ptr, file, mode, fp), | ||||
|   fp->_flags |= __SL64; | ||||
|  | ||||
|   _funlockfile(fp); | ||||
|   __sfp_lock_release (); | ||||
|   return fp; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user