From c799b17bb9a82e0edb037e3556db6a03d4b7d8f2 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Mon, 28 Feb 2005 13:22:53 +0000 Subject: [PATCH] - Extended the thread-safety locking to the file descriptors. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14844 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/GNUmakefile.68k | 3 +- library/GNUmakefile.os4 | 3 +- library/changes | 2 ++ library/fcntl_fcntl.c | 8 +++-- library/fcntl_lock.c | 62 +++++++++++++++++++++++++++++++++ library/fcntl_open.c | 22 ++++++++++-- library/mount_fstatfs.c | 8 +++-- library/smakefile | 3 +- library/socket_accept.c | 28 +++++++++++++-- library/socket_hook_entry.c | 11 +++++- library/socket_init_exit.c | 23 ++++++++++-- library/socket_ioctl.c | 12 ++++--- library/socket_select.c | 10 +++++- library/socket_socket.c | 22 ++++++++++-- library/stat_fchmod.c | 8 +++-- library/stdio_duplicate_fd.c | 8 +++-- library/stdio_fdhookentry.c | 11 +++++- library/stdio_headers.h | 14 +++++++- library/stdio_init_exit.c | 32 ++++++++++++----- library/stdio_initializefd.c | 12 ++++--- library/stdio_protos.h | 4 +-- library/stdio_remove_fd_alias.c | 6 +++- library/unistd_fchown.c | 8 +++-- library/unistd_ftruncate.c | 8 +++-- library/unistd_sync_fd.c | 6 +++- 25 files changed, 282 insertions(+), 52 deletions(-) create mode 100644 library/fcntl_lock.c diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index 2593d23..87c180e 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.31 2005-02-27 21:58:20 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.32 2005-02-28 13:22:53 obarthel Exp $ # # :ts=8 # @@ -143,6 +143,7 @@ C_LIB = \ fcntl_creat.o \ fcntl_fcntl.o \ fcntl_get_default_file.o \ + fcntl_lock.o \ fcntl_lseek.o \ fcntl_open.o \ fcntl_read.o \ diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index 6b343d6..11ac75d 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.31 2005-02-27 21:58:21 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.32 2005-02-28 13:22:53 obarthel Exp $ # # :ts=8 # @@ -147,6 +147,7 @@ C_LIB = \ fcntl_creat.o \ fcntl_fcntl.o \ fcntl_get_default_file.o \ + fcntl_lock.o \ fcntl_lseek.o \ fcntl_open.o \ fcntl_read.o \ diff --git a/library/changes b/library/changes index 834fcfb..6c74977 100644 --- a/library/changes +++ b/library/changes @@ -72,6 +72,8 @@ preprocessor symbol __THREAD_SAFE defined to get thread-safe code. +- Extended the thread-safety locking to the file descriptors. + c.lib 1.188 (7.2.2005) diff --git a/library/fcntl_fcntl.c b/library/fcntl_fcntl.c index eee8bf5..89f6243 100644 --- a/library/fcntl_fcntl.c +++ b/library/fcntl_fcntl.c @@ -1,5 +1,5 @@ /* - * $Id: fcntl_fcntl.c,v 1.10 2005-02-27 21:58:21 obarthel Exp $ + * $Id: fcntl_fcntl.c,v 1.11 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -48,7 +48,7 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ ) struct flock * l; int vacant_slot; int result = -1; - struct fd * fd; + struct fd * fd = NULL; va_list arg; int error; int flags; @@ -74,6 +74,8 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ ) goto out; } + __fd_lock(fd); + switch(cmd) { case F_GETLK: @@ -277,6 +279,8 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ ) out: + __fd_unlock(fd); + RETURN(result); return(result); } diff --git a/library/fcntl_lock.c b/library/fcntl_lock.c new file mode 100644 index 0000000..3128ea5 --- /dev/null +++ b/library/fcntl_lock.c @@ -0,0 +1,62 @@ +/* + * $Id: fcntl_lock.c,v 1.1 2005-02-28 13:22:53 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _STDIO_HEADERS_H +#include "stdio_headers.h" +#endif /* _STDIO_HEADERS_H */ + +/****************************************************************************/ + +#if defined(__THREAD_SAFE) + +/****************************************************************************/ + +void +__fd_lock(struct fd * fd) +{ + if(fd != NULL && fd->fd_Lock != NULL) + ObtainSemaphore(fd->fd_Lock); +} + +/****************************************************************************/ + +void +__fd_unlock(struct fd * fd) +{ + if(fd != NULL && fd->fd_Lock != NULL) + ReleaseSemaphore(fd->fd_Lock); +} + +/****************************************************************************/ + +#endif /* __THREAD_SAFE */ diff --git a/library/fcntl_open.c b/library/fcntl_open.c index 483fbd5..020daea 100644 --- a/library/fcntl_open.c +++ b/library/fcntl_open.c @@ -1,5 +1,5 @@ /* - * $Id: fcntl_open.c,v 1.11 2005-02-27 21:58:21 obarthel Exp $ + * $Id: fcntl_open.c,v 1.12 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -94,6 +94,7 @@ open(const char *path_name, int open_flag, ... /* mode_t mode */ ) struct name_translation_info path_name_nti; #endif /* UNIX_PATH_SEMANTICS */ D_S(struct FileInfoBlock,fib); + struct SignalSemaphore * fd_lock; LONG is_file_system = FALSE; LONG open_mode; BPTR lock = ZERO; @@ -328,9 +329,26 @@ open(const char *path_name, int open_flag, ... /* mode_t mode */ ) goto out; } + #if defined(__THREAD_SAFE) + { + fd_lock = AllocVec(sizeof(*fd_lock),MEMF_ANY|MEMF_PUBLIC); + if(fd_lock == NULL) + { + __set_errno(ENOMEM); + goto out; + } + + InitSemaphore(fd_lock); + } + #else + { + fd_lock = NULL; + } + #endif /* __THREAD_SAFE */ + fd = __fd[fd_slot_number]; - __initialize_fd(fd,__fd_hook_entry,handle,0); + __initialize_fd(fd,__fd_hook_entry,handle,0,fd_lock); /* Figure out if this stream is attached to a console. */ PROFILE_OFF(); diff --git a/library/mount_fstatfs.c b/library/mount_fstatfs.c index 5669fbb..822d4b2 100644 --- a/library/mount_fstatfs.c +++ b/library/mount_fstatfs.c @@ -1,5 +1,5 @@ /* - * $Id: mount_fstatfs.c,v 1.7 2005-02-28 10:07:30 obarthel Exp $ + * $Id: mount_fstatfs.c,v 1.8 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -53,7 +53,7 @@ fstatfs(int file_descriptor, struct statfs *buf) D_S(struct InfoData,id); BPTR parent_dir = ZERO; int result = -1; - struct fd * fd; + struct fd * fd = NULL; LONG success; ENTER(); @@ -89,6 +89,8 @@ fstatfs(int file_descriptor, struct statfs *buf) goto out; } + __fd_lock(fd); + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET)) { __set_errno(EINVAL); @@ -125,6 +127,8 @@ fstatfs(int file_descriptor, struct statfs *buf) out: + __fd_unlock(fd); + UnLock(parent_dir); RETURN(result); diff --git a/library/smakefile b/library/smakefile index 423d239..aeedb0b 100644 --- a/library/smakefile +++ b/library/smakefile @@ -1,5 +1,5 @@ _# -# $Id: smakefile,v 1.25 2005-02-27 21:58:21 obarthel Exp $ +# $Id: smakefile,v 1.26 2005-02-28 13:22:53 obarthel Exp $ # # :ts=8 # @@ -161,6 +161,7 @@ FCNTL_OBJ = \ fcntl_close.o \ fcntl_creat.o \ fcntl_fcntl.o \ + fcntl_lock.o \ fcntl_lseek.o \ fcntl_open.o \ fcntl_read.o \ diff --git a/library/socket_accept.c b/library/socket_accept.c index e169dd3..90221ad 100644 --- a/library/socket_accept.c +++ b/library/socket_accept.c @@ -1,5 +1,5 @@ /* - * $Id: socket_accept.c,v 1.6 2005-02-27 21:58:21 obarthel Exp $ + * $Id: socket_accept.c,v 1.7 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -50,7 +50,8 @@ int accept(int sockfd,struct sockaddr *cliaddr,int *addrlen) { - struct fd * fd; + struct SignalSemaphore * lock = NULL; + struct fd * fd = NULL; struct fd * new_fd; int new_fd_slot_number; int result = -1; @@ -88,6 +89,8 @@ accept(int sockfd,struct sockaddr *cliaddr,int *addrlen) if(fd == NULL) goto out; + __fd_lock(fd); + new_fd_slot_number = __find_vacant_fd_entry(); if(new_fd_slot_number < 0) { @@ -101,6 +104,19 @@ accept(int sockfd,struct sockaddr *cliaddr,int *addrlen) assert( new_fd_slot_number >= 0 ); } + #if defined(__THREAD_SAFE) + { + lock = AllocVec(sizeof(*lock),MEMF_ANY|MEMF_PUBLIC); + if(lock == NULL) + { + __set_errno(ENOMEM); + goto out; + } + + InitSemaphore(lock); + } + #endif /* __THREAD_SAFE */ + PROFILE_OFF(); new_socket_fd = __accept((LONG)fd->fd_DefaultFile,cliaddr,(LONG *)addrlen); PROFILE_ON(); @@ -113,14 +129,20 @@ accept(int sockfd,struct sockaddr *cliaddr,int *addrlen) new_fd = __fd[new_fd_slot_number]; - __initialize_fd(new_fd,__socket_hook_entry,(BPTR)new_socket_fd,FDF_IN_USE | FDF_IS_SOCKET | FDF_READ | FDF_WRITE); + __initialize_fd(new_fd,__socket_hook_entry,(BPTR)new_socket_fd,FDF_IN_USE | FDF_IS_SOCKET | FDF_READ | FDF_WRITE,lock); + + lock = NULL; result = new_fd_slot_number; out: + __fd_unlock(fd); + __stdio_unlock(); + FreeVec(lock); + if(__check_abort_enabled) __check_abort(); diff --git a/library/socket_hook_entry.c b/library/socket_hook_entry.c index 350e1ea..cd2ae84 100644 --- a/library/socket_hook_entry.c +++ b/library/socket_hook_entry.c @@ -1,5 +1,5 @@ /* - * $Id: socket_hook_entry.c,v 1.9 2005-02-20 15:46:52 obarthel Exp $ + * $Id: socket_hook_entry.c,v 1.10 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -56,6 +56,8 @@ __socket_hook_entry( assert( fam != NULL && fd != NULL ); + __fd_lock(fd); + switch(fam->fam_Action) { case file_action_read: @@ -120,6 +122,11 @@ __socket_hook_entry( } } + __fd_unlock(fd); + + /* Free the lock semaphore now. */ + FreeVec(fd->fd_Lock); + /* And that's the last for this file descriptor. */ memset(fd,0,sizeof(*fd)); @@ -190,6 +197,8 @@ __socket_hook_entry( break; } + __fd_unlock(fd); + RETURN(result); return(result); } diff --git a/library/socket_init_exit.c b/library/socket_init_exit.c index 483595d..67d0e93 100644 --- a/library/socket_init_exit.c +++ b/library/socket_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: socket_init_exit.c,v 1.9 2005-02-20 13:19:40 obarthel Exp $ + * $Id: socket_init_exit.c,v 1.10 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -221,6 +221,7 @@ __socket_init(void) if(TypeOfMem(dm) != 0 && TypeOfMem(((char *)dm) + sizeof(*dm)-1) != 0) { + struct SignalSemaphore * lock; int daemon_socket; struct fd * fd; int sockfd; @@ -254,6 +255,20 @@ __socket_init(void) /* Put the socket into the three standard I/O streams. */ for(i = STDIN_FILENO ; i <= STDERR_FILENO ; i++) { + #if defined(__THREAD_SAFE) + { + lock = AllocVec(sizeof(*lock),MEMF_ANY|MEMF_PUBLIC); + if(lock == NULL) + goto out; + + InitSemaphore(lock); + } + #else + { + lock = NULL; + } + #endif /* __THREAD_SAFE */ + fd = __fd[i]; assert( fd != NULL && FLAG_IS_CLEAR(fd->fd_Flags,FDF_IN_USE) ); @@ -271,13 +286,15 @@ __socket_init(void) if(sockfd == -1) { SHOWMSG("could not duplicate daemon socket"); - + + FreeVec(lock); + __show_error("Network server streams could not be initialized."); goto out; } } - __initialize_fd(fd,__socket_hook_entry,(BPTR)sockfd,FDF_IN_USE | FDF_IS_SOCKET | FDF_READ | FDF_WRITE); + __initialize_fd(fd,__socket_hook_entry,(BPTR)sockfd,FDF_IN_USE | FDF_IS_SOCKET | FDF_READ | FDF_WRITE,lock); } /* This program now runs as an internet superserver client (daemon). */ diff --git a/library/socket_ioctl.c b/library/socket_ioctl.c index 3312205..6aae6ed 100644 --- a/library/socket_ioctl.c +++ b/library/socket_ioctl.c @@ -1,5 +1,5 @@ /* - * $Id: socket_ioctl.c,v 1.6 2005-02-21 10:21:43 obarthel Exp $ + * $Id: socket_ioctl.c,v 1.7 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -56,7 +56,7 @@ ioctl(int sockfd,unsigned long request, ... /* char *arg */) { va_list arg; char * param; - struct fd * fd; + struct fd * fd = NULL; int result = -1; ENTER(); @@ -75,9 +75,11 @@ ioctl(int sockfd,unsigned long request, ... /* char *arg */) if(fd == NULL) goto out; - va_start(arg,request); + __fd_lock(fd); + va_start(arg,request); param = va_arg(arg,char *); + va_end(arg); SHOWPOINTER(param); @@ -105,10 +107,10 @@ ioctl(int sockfd,unsigned long request, ... /* char *arg */) } } - va_end(arg); - out: + __fd_unlock(fd); + if(__check_abort_enabled) __check_abort(); diff --git a/library/socket_select.c b/library/socket_select.c index 245deaa..cc53e7f 100644 --- a/library/socket_select.c +++ b/library/socket_select.c @@ -1,5 +1,5 @@ /* - * $Id: socket_select.c,v 1.6 2005-02-27 21:58:21 obarthel Exp $ + * $Id: socket_select.c,v 1.7 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -592,10 +592,14 @@ select(int num_fds,fd_set *read_fds,fd_set *write_fds,fd_set *except_fds,struct * to the local copies, which take the files and sockets * into account. */ + __stdio_lock(); + map_descriptor_sets(read_fds, num_fds, socket_read_fds, num_socket_used, &total_socket_fd, file_read_fds, num_file_used, &total_file_fd); map_descriptor_sets(write_fds, num_fds, socket_write_fds, num_socket_used, &total_socket_fd, file_write_fds, num_file_used, &total_file_fd); map_descriptor_sets(except_fds, num_fds, socket_except_fds, num_socket_used, &total_socket_fd, NULL, 0, &total_file_fd); + __stdio_unlock(); + /* Wait for socket input? */ if(total_socket_fd > 0) { @@ -981,9 +985,13 @@ select(int num_fds,fd_set *read_fds,fd_set *write_fds,fd_set *except_fds,struct { SHOWMSG("remapping fd_sets"); + __stdio_lock(); + remap_descriptor_sets(socket_read_fds, total_socket_fd, file_read_fds, total_file_fd, read_fds, num_fds); remap_descriptor_sets(socket_write_fds, total_socket_fd, file_write_fds, total_file_fd, write_fds, num_fds); remap_descriptor_sets(socket_except_fds, total_socket_fd, NULL, 0, except_fds, num_fds); + + __stdio_unlock(); } if(__check_abort_enabled) diff --git a/library/socket_socket.c b/library/socket_socket.c index b2bd0be..9a94867 100644 --- a/library/socket_socket.c +++ b/library/socket_socket.c @@ -1,5 +1,5 @@ /* - * $Id: socket_socket.c,v 1.4 2005-02-27 21:58:21 obarthel Exp $ + * $Id: socket_socket.c,v 1.5 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -44,6 +44,7 @@ int socket(int domain,int type,int protocol) { + struct SignalSemaphore * lock = NULL; int result = -1; struct fd * fd; int fd_slot_number; @@ -70,6 +71,19 @@ socket(int domain,int type,int protocol) assert( fd_slot_number >= 0 ); } + #if defined(__THREAD_SAFE) + { + lock = AllocVec(sizeof(*lock),MEMF_ANY|MEMF_PUBLIC); + if(lock == NULL) + { + __set_errno(ENOMEM); + goto out; + } + + InitSemaphore(lock); + } + #endif /* __THREAD_SAFE */ + PROFILE_OFF(); socket_fd = __socket(domain,type,protocol); PROFILE_ON(); @@ -82,7 +96,9 @@ socket(int domain,int type,int protocol) fd = __fd[fd_slot_number]; - __initialize_fd(fd,__socket_hook_entry,(BPTR)socket_fd,FDF_IN_USE | FDF_IS_SOCKET | FDF_READ | FDF_WRITE); + __initialize_fd(fd,__socket_hook_entry,(BPTR)socket_fd,FDF_IN_USE | FDF_IS_SOCKET | FDF_READ | FDF_WRITE,lock); + + lock = NULL; result = fd_slot_number; @@ -90,6 +106,8 @@ socket(int domain,int type,int protocol) __stdio_unlock(); + FreeVec(lock); + if(__check_abort_enabled) __check_abort(); diff --git a/library/stat_fchmod.c b/library/stat_fchmod.c index 212ab54..6fb6580 100644 --- a/library/stat_fchmod.c +++ b/library/stat_fchmod.c @@ -1,5 +1,5 @@ /* - * $Id: stat_fchmod.c,v 1.6 2005-02-21 10:21:44 obarthel Exp $ + * $Id: stat_fchmod.c,v 1.7 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -50,7 +50,7 @@ fchmod(int file_descriptor, mode_t mode) BPTR old_current_dir = ZERO; BOOL current_dir_changed = FALSE; int result = -1; - struct fd * fd; + struct fd * fd = NULL; LONG success; ENTER(); @@ -72,6 +72,8 @@ fchmod(int file_descriptor, mode_t mode) goto out; } + __fd_lock(fd); + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET)) { __set_errno(EINVAL); @@ -159,6 +161,8 @@ fchmod(int file_descriptor, mode_t mode) out: + __fd_unlock(fd); + if(current_dir_changed) CurrentDir(old_current_dir); diff --git a/library/stdio_duplicate_fd.c b/library/stdio_duplicate_fd.c index 67619a1..46cbb8c 100644 --- a/library/stdio_duplicate_fd.c +++ b/library/stdio_duplicate_fd.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_duplicate_fd.c,v 1.3 2005-02-20 13:19:40 obarthel Exp $ + * $Id: stdio_duplicate_fd.c,v 1.4 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -42,8 +42,10 @@ __duplicate_fd(struct fd * duplicate_fd,struct fd * original_fd) { assert( duplicate_fd != NULL && original_fd != NULL ); + __fd_lock(original_fd); + /* Initialize the duplicate to match the original. */ - __initialize_fd(duplicate_fd,original_fd->fd_Action,original_fd->fd_DefaultFile,original_fd->fd_Flags); + __initialize_fd(duplicate_fd,original_fd->fd_Action,original_fd->fd_DefaultFile,original_fd->fd_Flags,original_fd->fd_Lock); /* Figure out where the linked list of file descriptors associated with this one starts. */ @@ -55,4 +57,6 @@ __duplicate_fd(struct fd * duplicate_fd,struct fd * original_fd) /* Add the duplicate at the beginning of the list. */ duplicate_fd->fd_NextLink = duplicate_fd->fd_Original->fd_NextLink; duplicate_fd->fd_Original->fd_NextLink = duplicate_fd; + + __fd_unlock(original_fd); } diff --git a/library/stdio_fdhookentry.c b/library/stdio_fdhookentry.c index 134bea5..ac46acd 100644 --- a/library/stdio_fdhookentry.c +++ b/library/stdio_fdhookentry.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_fdhookentry.c,v 1.14 2005-02-21 10:21:45 obarthel Exp $ + * $Id: stdio_fdhookentry.c,v 1.15 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -70,6 +70,8 @@ __fd_hook_entry( assert( fam != NULL && fd != NULL ); assert( __is_valid_fd(fd) ); + __fd_lock(fd); + switch(fam->fam_Action) { case file_action_read: @@ -351,6 +353,11 @@ __fd_hook_entry( } } + __fd_unlock(fd); + + /* Free the lock semaphore now. */ + FreeVec(fd->fd_Lock); + /* And that's the last for this file descriptor. */ memset(fd,0,sizeof(*fd)); @@ -536,6 +543,8 @@ __fd_hook_entry( break; } + __fd_unlock(fd); + if(buffer != NULL) free(buffer); diff --git a/library/stdio_headers.h b/library/stdio_headers.h index 78afa3f..8ab6d9c 100644 --- a/library/stdio_headers.h +++ b/library/stdio_headers.h @@ -1,5 +1,5 @@ /* - * $Id: stdio_headers.h,v 1.17 2005-02-28 10:07:31 obarthel Exp $ + * $Id: stdio_headers.h,v 1.18 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -341,6 +341,8 @@ struct fd BPTR fd_DefaultFile; /* A dos.library file handle */ LONG fd_Position; /* Cached file position (seek offset). */ fd_cleanup_t fd_Cleanup; /* Cleanup function, if any. */ + + struct SignalSemaphore * fd_Lock; /* For thread locking */ }; /****************************************************************************/ @@ -439,6 +441,11 @@ extern int __stdio_lock_init(void); /****************************************************************************/ +extern void __fd_lock(struct fd *fd); +extern void __fd_unlock(struct fd *fd); + +/****************************************************************************/ + #else /****************************************************************************/ @@ -450,6 +457,11 @@ extern int __stdio_lock_init(void); /****************************************************************************/ +#define __fd_lock(fd) ((void)0) +#define __fd_unlock(fd) ((void)0) + +/****************************************************************************/ + #endif /* __THREAD_SAFE */ /****************************************************************************/ diff --git a/library/stdio_init_exit.c b/library/stdio_init_exit.c index 68838db..84694ad 100644 --- a/library/stdio_init_exit.c +++ b/library/stdio_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_init_exit.c,v 1.20 2005-02-28 10:07:31 obarthel Exp $ + * $Id: stdio_init_exit.c,v 1.21 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -66,6 +66,8 @@ __close_all_files(void) __check_abort_enabled = FALSE; + __stdio_lock(); + if(__iob != NULL && __num_iob > 0) { for(i = 0 ; i < __num_iob ; i++) @@ -90,6 +92,8 @@ __close_all_files(void) __fd = NULL; } + __stdio_unlock(); + LEAVE(); } @@ -113,7 +117,8 @@ __stdio_init(void) { const int num_standard_files = (STDERR_FILENO-STDIN_FILENO+1); - struct SignalSemaphore * lock; + struct SignalSemaphore * stdio_lock; + struct SignalSemaphore * fd_lock; BPTR default_file; ULONG fd_flags,iob_flags; int result = ERROR; @@ -197,15 +202,24 @@ __stdio_init(void) { /* Allocate memory for an arbitration mechanism, then initialize it. */ - lock = AllocVec(sizeof(*lock),MEMF_ANY|MEMF_PUBLIC); - if(lock == NULL) - goto out; + stdio_lock = AllocVec(sizeof(*stdio_lock),MEMF_ANY|MEMF_PUBLIC); + fd_lock = AllocVec(sizeof(*fd_lock),MEMF_ANY|MEMF_PUBLIC); - InitSemaphore(lock); + if(stdio_lock == NULL || fd_lock == NULL) + { + FreeVec(stdio_lock); + FreeVec(fd_lock); + + goto out; + } + + InitSemaphore(stdio_lock); + InitSemaphore(fd_lock); } #else { - lock = NULL; + stdio_lock = NULL; + fd_lock = NULL; } #endif /* __THREAD_SAFE */ @@ -223,7 +237,7 @@ __stdio_init(void) /* Align the buffer start address to a cache line boundary. */ aligned_buffer = (char *)((ULONG)(buffer + (CACHE_LINE_SIZE-1)) & ~(CACHE_LINE_SIZE-1)); - __initialize_fd(__fd[i],__fd_hook_entry,default_file,fd_flags); + __initialize_fd(__fd[i],__fd_hook_entry,default_file,fd_flags,fd_lock); __initialize_iob(__iob[i],__iob_hook_entry, buffer, @@ -231,7 +245,7 @@ __stdio_init(void) i, i, iob_flags, - lock); + stdio_lock); } /* If the program was launched from Workbench, we continue by diff --git a/library/stdio_initializefd.c b/library/stdio_initializefd.c index d429c17..d574610 100644 --- a/library/stdio_initializefd.c +++ b/library/stdio_initializefd.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_initializefd.c,v 1.3 2005-02-20 13:19:40 obarthel Exp $ + * $Id: stdio_initializefd.c,v 1.4 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -39,10 +39,11 @@ void __initialize_fd( - struct fd * fd, - file_action_fd_t action_function, - BPTR default_file, - ULONG flags) + struct fd * fd, + file_action_fd_t action_function, + BPTR default_file, + ULONG flags, + struct SignalSemaphore * lock) { assert( fd != NULL && action_function != NULL ); @@ -51,4 +52,5 @@ __initialize_fd( fd->fd_DefaultFile = default_file; fd->fd_Flags = flags; fd->fd_Action = action_function; + fd->fd_Lock = lock; } diff --git a/library/stdio_protos.h b/library/stdio_protos.h index c23b32f..e4ee6ab 100644 --- a/library/stdio_protos.h +++ b/library/stdio_protos.h @@ -1,5 +1,5 @@ /* - * $Id: stdio_protos.h,v 1.10 2005-02-28 10:07:31 obarthel Exp $ + * $Id: stdio_protos.h,v 1.11 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -92,7 +92,7 @@ extern int __fd_hook_entry(struct fd * fd,struct file_action_message * fam); /****************************************************************************/ /* stdio_initializefd.c */ -extern void __initialize_fd(struct fd * fd,file_action_fd_t action_function,BPTR default_file,ULONG flags); +extern void __initialize_fd(struct fd * fd,file_action_fd_t action_function,BPTR default_file,ULONG flags,struct SignalSemaphore * lock); /****************************************************************************/ diff --git a/library/stdio_remove_fd_alias.c b/library/stdio_remove_fd_alias.c index 66e9355..757b644 100644 --- a/library/stdio_remove_fd_alias.c +++ b/library/stdio_remove_fd_alias.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_remove_fd_alias.c,v 1.1 2005-02-20 13:19:40 obarthel Exp $ + * $Id: stdio_remove_fd_alias.c,v 1.2 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -42,6 +42,8 @@ __remove_fd_alias(struct fd * fd) { assert( fd != NULL ); + __stdio_lock(); + if(fd->fd_Original != NULL) /* this is an alias */ { struct fd * list_fd; @@ -78,4 +80,6 @@ __remove_fd_alias(struct fd * fd) list_fd->fd_Original = first_alias; } } + + __stdio_unlock(); } diff --git a/library/unistd_fchown.c b/library/unistd_fchown.c index d9ca826..868984c 100644 --- a/library/unistd_fchown.c +++ b/library/unistd_fchown.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_fchown.c,v 1.6 2005-02-21 10:22:02 obarthel Exp $ + * $Id: unistd_fchown.c,v 1.7 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -49,7 +49,7 @@ fchown(int file_descriptor, uid_t owner, gid_t group) BPTR old_current_dir = ZERO; BOOL current_dir_changed = FALSE; int result = -1; - struct fd * fd; + struct fd * fd = NULL; LONG success; ENTER(); @@ -72,6 +72,8 @@ fchown(int file_descriptor, uid_t owner, gid_t group) goto out; } + __fd_lock(fd); + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET)) { __set_errno(EINVAL); @@ -163,6 +165,8 @@ fchown(int file_descriptor, uid_t owner, gid_t group) out: + __fd_unlock(fd); + PROFILE_OFF(); UnLock(parent_dir); diff --git a/library/unistd_ftruncate.c b/library/unistd_ftruncate.c index c38aba9..1a72f6b 100644 --- a/library/unistd_ftruncate.c +++ b/library/unistd_ftruncate.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_ftruncate.c,v 1.5 2005-02-18 18:53:17 obarthel Exp $ + * $Id: unistd_ftruncate.c,v 1.6 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -46,7 +46,7 @@ ftruncate(int file_descriptor, off_t length) { D_S(struct FileInfoBlock,fib); int result = -1; - struct fd * fd; + struct fd * fd = NULL; long int position; BOOL success; @@ -69,6 +69,8 @@ ftruncate(int file_descriptor, off_t length) goto out; } + __fd_lock(fd); + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_SOCKET)) { __set_errno(EINVAL); @@ -145,6 +147,8 @@ ftruncate(int file_descriptor, off_t length) out: + __fd_unlock(fd); + RETURN(result); return(result); } diff --git a/library/unistd_sync_fd.c b/library/unistd_sync_fd.c index 153da78..333f155 100644 --- a/library/unistd_sync_fd.c +++ b/library/unistd_sync_fd.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_sync_fd.c,v 1.1 2005-02-18 18:53:17 obarthel Exp $ + * $Id: unistd_sync_fd.c,v 1.2 2005-02-28 13:22:53 obarthel Exp $ * * :ts=4 * @@ -52,6 +52,8 @@ __sync_fd(struct fd * fd,int mode) { assert( fd != NULL ); + __fd_lock(fd); + if(fd->fd_DefaultFile != ZERO) { /* The mode tells us what to flush. 0 means "flush just the data", and @@ -67,4 +69,6 @@ __sync_fd(struct fd * fd,int mode) DoPkt(fh->fh_Type,ACTION_FLUSH, 0,0,0,0,0); } } + + __fd_unlock(fd); }