[RFA]: race safe fwalk
Thomas Pfaff
thomas.pfaff@gmx.net
Tue Mar 23 18:02:00 GMT 2004
Jeff Johnston wrote:
> Thomas Pfaff wrote:
>
>> This time with attachment.
>>
>> There is a possible race between fwalk and fopen:
>>
>> When a thread make a call to fopen the FILE * _flags will be set to 1
>> in findfp to mark it used and later it will be changed to the real
>> FILE flag.
>>
>> When another thread calls fwalk during that time fwalk will treat the
>> FILE as already opened and calls the callback functions with the yet
>> unopened and only partially initialized FILE *.
>>
>> This can be avoided by checking for fp->_flags != 0 && fp->_flags !=
>> 1. Since _flags is signed short i did not check for _flags > 1. The
>> flag should be set as the last step in an open call.
>> I do not think that 1 is a valid _flag for an open file. Correct me if
>> am wrong.
>>
>
> Unfortunately, 1 is also line-buffered: __SLBF.
>
> What if instead, we use the _file field to check for a valid file. It
> gets set to -1 by __sfp. Now, if we set _file inside the __sfp_lock and
> then had fwalk() use the __sfp lock as well and check for _file != -1,
> plus have the open routines set the _file field last, this should work
> equally as well. Comments?
>
I do not think that this can be done that easy anymore. The whole file
list stuff must be better protected.
Attached is a new patch. I am sorry for the delay.
2004-03-22 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.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: newlib-stdio.patch
URL: <http://sourceware.org/pipermail/newlib/attachments/20040323/57793f6e/attachment.ksh>
More information about the Newlib
mailing list