From 92cc3e9a79a6421734ac9f55c5d2677ee37b1443 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Mon, 4 Apr 2005 10:10:02 +0000 Subject: [PATCH] - The stdio locking in fcntl() wasn't working correctly. Fixed. - Made the clearerr(), feof() and ferror() macros thread-safe. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14914 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/changes | 4 ++++ library/fcntl_fcntl.c | 11 ++++++++++- library/include/stdio.h | 20 +++++++++++++++++++- library/socket_hook_entry.c | 18 +++++++++++++++--- library/stdio_fdhookentry.c | 26 ++++++++++++++++---------- library/stdio_fwrite.c | 10 ++++++---- 6 files changed, 70 insertions(+), 19 deletions(-) diff --git a/library/changes b/library/changes index 0ee4bd1..5252505 100644 --- a/library/changes +++ b/library/changes @@ -57,6 +57,10 @@ - Added vfscanf() to . +- The stdio locking in fcntl() wasn't working correctly. Fixed. + +- Made the clearerr(), feof() and ferror() macros thread-safe. + c.lib 1.190 (25.3.2005) diff --git a/library/fcntl_fcntl.c b/library/fcntl_fcntl.c index 22332b9..4c8b6cc 100644 --- a/library/fcntl_fcntl.c +++ b/library/fcntl_fcntl.c @@ -1,5 +1,5 @@ /* - * $Id: fcntl_fcntl.c,v 1.15 2005-03-25 08:59:22 obarthel Exp $ + * $Id: fcntl_fcntl.c,v 1.16 2005-04-04 10:09:56 obarthel Exp $ * * :ts=4 * @@ -67,6 +67,12 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ ) if(__check_abort_enabled) __check_abort(); + /* F_DUPFD will need to modify the file descriptor table, which is why + the stdio lock needs to be obtained here, before the individual + file descriptor lock is held. */ + if(cmd == F_DUPFD) + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { @@ -268,6 +274,9 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ ) __fd_unlock(fd); + if(cmd == F_DUPFD) + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/include/stdio.h b/library/include/stdio.h index 8da5a0f..4c58941 100644 --- a/library/include/stdio.h +++ b/library/include/stdio.h @@ -1,5 +1,5 @@ /* - * $Id: stdio.h,v 1.10 2005-04-03 10:22:48 obarthel Exp $ + * $Id: stdio.h,v 1.11 2005-04-04 10:10:02 obarthel Exp $ * * :ts=4 * @@ -306,12 +306,30 @@ extern char *tmpnam(char *buf); /****************************************************************************/ +#if defined(__THREAD_SAFE) + +/****************************************************************************/ + +#define clearerr(file) ((void)(flockfile(file), (file)->flags &= ~(__FILE_EOF|__FILE_ERROR), unlockfile(file))) +#define feof(file) (flockfile(file), __unlockfile((file),((file)->flags & __FILE_EOF) != 0)) +#define ferror(file) (flockfile(file), __unlockfile((file),((file)->flags & __FILE_ERROR) != 0)) + +/****************************************************************************/ + +#else + +/****************************************************************************/ + #define clearerr(file) ((void)((file)->flags &= ~(__FILE_EOF|__FILE_ERROR))) #define feof(file) (((file)->flags & __FILE_EOF) != 0) #define ferror(file) (((file)->flags & __FILE_ERROR) != 0) /****************************************************************************/ +#endif /* __THREAD_SAFE */ + +/****************************************************************************/ + #endif /* __C_MACROS__ */ /****************************************************************************/ diff --git a/library/socket_hook_entry.c b/library/socket_hook_entry.c index bd524ab..1ddb603 100644 --- a/library/socket_hook_entry.c +++ b/library/socket_hook_entry.c @@ -1,5 +1,5 @@ /* - * $Id: socket_hook_entry.c,v 1.13 2005-03-12 09:43:47 obarthel Exp $ + * $Id: socket_hook_entry.c,v 1.14 2005-04-04 10:09:56 obarthel Exp $ * * :ts=4 * @@ -51,11 +51,18 @@ __socket_hook_entry( struct file_action_message * fam) { struct FileInfoBlock * fib; + BOOL is_aliased; int result; int param; assert( fam != NULL && fd != NULL ); + /* Careful: file_action_close has to monkey with the file descriptor + table and therefore needs to obtain the stdio lock before + it locks this particular descriptor entry. */ + if(fam->fam_Action == file_action_close) + __stdio_lock(); + __fd_lock(fd); switch(fam->fam_Action) @@ -107,7 +114,8 @@ __socket_hook_entry( result = 0; /* If this is an alias, just remove it. */ - if(__fd_is_aliased(fd)) + is_aliased = __fd_is_aliased(fd); + if(is_aliased) { __remove_fd_alias(fd); } @@ -129,7 +137,8 @@ __socket_hook_entry( #if defined(__THREAD_SAFE) { /* Free the lock semaphore now. */ - __delete_semaphore(fd->fd_Lock); + if(NOT is_aliased) + __delete_semaphore(fd->fd_Lock); } #endif /* __THREAD_SAFE */ @@ -203,6 +212,9 @@ __socket_hook_entry( __fd_unlock(fd); + if(fam->fam_Action == file_action_close) + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/stdio_fdhookentry.c b/library/stdio_fdhookentry.c index 15a70df..e5c3755 100644 --- a/library/stdio_fdhookentry.c +++ b/library/stdio_fdhookentry.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_fdhookentry.c,v 1.27 2005-04-02 18:02:54 obarthel Exp $ + * $Id: stdio_fdhookentry.c,v 1.28 2005-04-04 10:09:57 obarthel Exp $ * * :ts=4 * @@ -73,6 +73,12 @@ __fd_hook_entry( assert( fam != NULL && fd != NULL ); assert( __is_valid_fd(fd) ); + /* Careful: file_action_close has to monkey with the file descriptor + table and therefore needs to obtain the stdio lock before + it locks this particular descriptor entry. */ + if(fam->fam_Action == file_action_close) + __stdio_lock(); + __fd_lock(fd); #if defined(__THREAD_SAFE) @@ -240,15 +246,12 @@ __fd_hook_entry( } else if (FLAG_IS_CLEAR(fd->fd_Flags,FDF_STDIO)) { - /* Are we disallowed to close this file? */ - if(FLAG_IS_SET(fd->fd_Flags,FDF_NO_CLOSE)) - { - /* OK, so we cannot close it. But we might be obliged to - reset a console into buffered mode. */ - if(FLAG_IS_SET(fd->fd_Flags,FDF_NON_BLOCKING) && FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) - SetMode(fd->fd_DefaultFile,DOSFALSE); - } - else + /* Should we reset this file into line buffered mode? */ + if(FLAG_IS_SET(fd->fd_Flags,FDF_NON_BLOCKING) && FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) + SetMode(fd->fd_DefaultFile,DOSFALSE); + + /* Are we allowed to close this file? */ + if(FLAG_IS_CLEAR(fd->fd_Flags,FDF_NO_CLOSE)) { BOOL name_and_path_valid = FALSE; D_S(struct FileInfoBlock,fib); @@ -621,6 +624,9 @@ __fd_hook_entry( __fd_unlock(fd); + if(fam->fam_Action == file_action_close) + __stdio_unlock(); + if(buffer != NULL) free(buffer); diff --git a/library/stdio_fwrite.c b/library/stdio_fwrite.c index 2b62dba..24a707f 100644 --- a/library/stdio_fwrite.c +++ b/library/stdio_fwrite.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_fwrite.c,v 1.7 2005-02-27 21:58:21 obarthel Exp $ + * $Id: stdio_fwrite.c,v 1.8 2005-04-04 10:09:57 obarthel Exp $ * * :ts=4 * @@ -118,12 +118,14 @@ fwrite(const void *ptr,size_t element_size,size_t count,FILE *stream) buffer_mode = (file->iob_Flags & IOBF_BUFFER_MODE); if(buffer_mode == IOBF_BUFFER_MODE_NONE) { - __stdio_lock(); + struct fd * fd = __fd[file->iob_Descriptor]; - if(FLAG_IS_SET(__fd[file->iob_Descriptor]->fd_Flags,FDF_IS_INTERACTIVE)) + __fd_lock(fd); + + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) buffer_mode = IOBF_BUFFER_MODE_LINE; - __stdio_unlock(); + __fd_unlock(fd); } if(buffer_mode == IOBF_BUFFER_MODE_LINE)