From 882875d79a5f0ef54c069d7c2029e5818bc0a183 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Wed, 6 Jul 2005 18:48:53 +0000 Subject: [PATCH] - The thread-safe version of isatty() should now work for stdio file descriptors, too. - Retrofitted thread-safety into the termios code. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@15010 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/changes | 7 ++- library/fcntl_lseek.c | 12 ++++- library/fcntl_read.c | 12 ++++- library/fcntl_write.c | 12 ++++- library/mount_fstatfs.c | 6 ++- library/stat_fchmod.c | 6 ++- library/stat_fstat.c | 12 ++++- library/termios_tcdrain.c | 69 ++++++++++++++++++++++++++++- library/termios_tcflow.c | 12 ++++- library/termios_tcflush.c | 75 +++++++++++++++++++++++++++++--- library/termios_tcgetattr.c | 14 ++++-- library/termios_tcsendbreak.c | 10 ++++- library/termios_tcsetattr.c | 78 +++++++++++++++++++++++++++++---- library/uio_readv.c | 12 ++++- library/uio_writev.c | 14 ++++-- library/unistd_fchown.c | 6 ++- library/unistd_fdatasync.c | 10 ++++- library/unistd_fsync.c | 10 ++++- library/unistd_ftruncate.c | 6 ++- library/unistd_isatty.c | 82 ++++++++++++++++++++++++++++++++--- library/unistd_ttyname.c | 80 +++++++++++++++++++++++++++++++++- library/unistd_ttyname_r.c | 80 +++++++++++++++++++++++++++++++++- 22 files changed, 575 insertions(+), 50 deletions(-) diff --git a/library/changes b/library/changes index 6fcc5e1..655e51a 100644 --- a/library/changes +++ b/library/changes @@ -29,7 +29,7 @@ - Fixed a bug in vfprintf that would surface when the buffer was enlarged if the pattern was too large to fit the static internal buffer -- Added file system names to statfx +- Added file system names to statfs - Moved all the constructor code out of "stdlib_init_exit.c" and into the files which initialize global data, such as the new "stdlib_program_name.c" @@ -51,6 +51,11 @@ AmigaOS and the PowerPC native AmigaOS4. The example source code can be found in the "skeleton_library" subdirectory. +- The thread-safe version of isatty() should now work for stdio + file descriptors, too. + +- Retrofitted thread-safety into the termios code. + c.lib 1.193 (4.6.2005) diff --git a/library/fcntl_lseek.c b/library/fcntl_lseek.c index f19218a..5f2c8d1 100644 --- a/library/fcntl_lseek.c +++ b/library/fcntl_lseek.c @@ -1,5 +1,5 @@ /* - * $Id: fcntl_lseek.c,v 1.9 2005-04-24 09:53:11 obarthel Exp $ + * $Id: fcntl_lseek.c,v 1.10 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -46,8 +46,8 @@ lseek(int file_descriptor, off_t offset, int mode) { struct file_action_message fam; off_t result = SEEK_ERROR; + struct fd * fd = NULL; off_t position; - struct fd * fd; ENTER(); @@ -62,6 +62,8 @@ lseek(int file_descriptor, off_t offset, int mode) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { @@ -69,6 +71,8 @@ lseek(int file_descriptor, off_t offset, int mode) goto out; } + __fd_lock(fd); + if(mode < SEEK_SET || mode > SEEK_END) { SHOWMSG("seek mode is invalid"); @@ -104,6 +108,10 @@ lseek(int file_descriptor, off_t offset, int mode) out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/fcntl_read.c b/library/fcntl_read.c index ecb1857..a91cef7 100644 --- a/library/fcntl_read.c +++ b/library/fcntl_read.c @@ -1,5 +1,5 @@ /* - * $Id: fcntl_read.c,v 1.8 2005-04-24 08:46:37 obarthel Exp $ + * $Id: fcntl_read.c,v 1.9 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -51,8 +51,8 @@ ssize_t read(int file_descriptor, void * buffer, size_t num_bytes) { ssize_t num_bytes_read; + struct fd * fd = NULL; ssize_t result = EOF; - struct fd * fd; ENTER(); @@ -66,6 +66,8 @@ read(int file_descriptor, void * buffer, size_t num_bytes) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + #if defined(CHECK_FOR_NULL_POINTERS) { if(buffer == NULL) @@ -89,6 +91,8 @@ read(int file_descriptor, void * buffer, size_t num_bytes) goto out; } + __fd_lock(fd); + if(FLAG_IS_CLEAR(fd->fd_Flags,FDF_READ)) { SHOWMSG("this descriptor is not read-enabled"); @@ -125,6 +129,10 @@ read(int file_descriptor, void * buffer, size_t num_bytes) out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/fcntl_write.c b/library/fcntl_write.c index 3dc4f65..b2a61aa 100644 --- a/library/fcntl_write.c +++ b/library/fcntl_write.c @@ -1,5 +1,5 @@ /* - * $Id: fcntl_write.c,v 1.8 2005-04-24 08:46:37 obarthel Exp $ + * $Id: fcntl_write.c,v 1.9 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -51,8 +51,8 @@ ssize_t write(int file_descriptor, const void * buffer, size_t num_bytes) { ssize_t num_bytes_written; + struct fd * fd = NULL; ssize_t result = EOF; - struct fd * fd; ENTER(); @@ -66,6 +66,8 @@ write(int file_descriptor, const void * buffer, size_t num_bytes) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + #if defined(CHECK_FOR_NULL_POINTERS) { if(buffer == NULL) @@ -89,6 +91,8 @@ write(int file_descriptor, const void * buffer, size_t num_bytes) goto out; } + __fd_lock(fd); + if(FLAG_IS_CLEAR(fd->fd_Flags,FDF_WRITE)) { SHOWMSG("file descriptor is not write-enabled"); @@ -125,6 +129,10 @@ write(int file_descriptor, const void * buffer, size_t num_bytes) out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/mount_fstatfs.c b/library/mount_fstatfs.c index 579d39f..8612b50 100644 --- a/library/mount_fstatfs.c +++ b/library/mount_fstatfs.c @@ -1,5 +1,5 @@ /* - * $Id: mount_fstatfs.c,v 1.11 2005-04-24 08:46:37 obarthel Exp $ + * $Id: mount_fstatfs.c,v 1.12 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -66,6 +66,8 @@ fstatfs(int file_descriptor, struct statfs *buf) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + #if defined(CHECK_FOR_NULL_POINTERS) { if(buf == NULL) @@ -135,6 +137,8 @@ fstatfs(int file_descriptor, struct statfs *buf) __fd_unlock(fd); + __stdio_unlock(); + UnLock(parent_dir); RETURN(result); diff --git a/library/stat_fchmod.c b/library/stat_fchmod.c index f97e21d..b8a9697 100644 --- a/library/stat_fchmod.c +++ b/library/stat_fchmod.c @@ -1,5 +1,5 @@ /* - * $Id: stat_fchmod.c,v 1.10 2005-04-24 08:46:37 obarthel Exp $ + * $Id: stat_fchmod.c,v 1.11 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -65,6 +65,8 @@ fchmod(int file_descriptor, mode_t mode) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { @@ -169,6 +171,8 @@ fchmod(int file_descriptor, mode_t mode) __fd_unlock(fd); + __stdio_unlock(); + if(current_dir_changed) CurrentDir(old_current_dir); diff --git a/library/stat_fstat.c b/library/stat_fstat.c index 6eaccba..3482e25 100644 --- a/library/stat_fstat.c +++ b/library/stat_fstat.c @@ -1,5 +1,5 @@ /* - * $Id: stat_fstat.c,v 1.8 2005-04-24 08:46:37 obarthel Exp $ + * $Id: stat_fstat.c,v 1.9 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -52,8 +52,8 @@ fstat(int file_descriptor, struct stat * buffer) { struct file_action_message fam; D_S(struct FileInfoBlock,fib); + struct fd * fd = NULL; int result = ERROR; - struct fd * fd; ENTER(); @@ -65,6 +65,8 @@ fstat(int file_descriptor, struct stat * buffer) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + #if defined(CHECK_FOR_NULL_POINTERS) { if(buffer == NULL) @@ -88,6 +90,8 @@ fstat(int file_descriptor, struct stat * buffer) goto out; } + __fd_lock(fd); + SHOWMSG("calling the hook"); fam.fam_Action = file_action_examine; @@ -108,6 +112,10 @@ fstat(int file_descriptor, struct stat * buffer) out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/termios_tcdrain.c b/library/termios_tcdrain.c index e8340fc..f38989d 100755 --- a/library/termios_tcdrain.c +++ b/library/termios_tcdrain.c @@ -1,5 +1,5 @@ /* - * $Id: termios_tcdrain.c,v 1.1 2005-06-04 10:46:21 obarthel Exp $ + * $Id: termios_tcdrain.c,v 1.2 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -49,6 +49,7 @@ tcdrain(int file_descriptor) int result = ERROR; struct fd *fd; struct termios *tios; + BPTR file; ENTER(); @@ -57,6 +58,8 @@ tcdrain(int file_descriptor) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { @@ -64,6 +67,58 @@ tcdrain(int file_descriptor) goto out; } + __fd_lock(fd); + + file = fd->fd_DefaultFile; + + #if defined(__THREAD_SAFE) + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO)) + { + switch(fd->fd_DefaultFile) + { + case STDIN_FILENO: + + file = Input(); + break; + + case STDOUT_FILENO: + + file = Output(); + break; + + case STDERR_FILENO: + + #if defined(__amigaos4__) + { + file = ErrorOutput(); + } + #else + { + struct Process * this_process = (struct Process *)FindTask(NULL); + + file = this_process->pr_CES; + } + #endif /* __amigaos4__ */ + + /* The following is rather controversial; if the standard error stream + is unavailable, we default to reuse the standard output stream. This + is problematic if the standard output stream was redirected and should + not be the same as the standard error output stream. */ + if(file == ZERO) + file = Output(); + + break; + + default: + + file = ZERO; + break; + } + } + } + #endif /* __THREAD_SAFE */ + if(FLAG_IS_SET(fd->fd_Flags,FDF_TERMIOS)) { tios = fd->fd_Aux; @@ -72,10 +127,16 @@ tcdrain(int file_descriptor) { case TIOST_CONSOLE: + if(file == ZERO) + { + __set_errno(EBADF); + goto out; + } + /* This also discards any buffered input, but it does not appear possible to drain the output buffer otherwise. (?) */ - if(CANNOT Flush(fd->fd_DefaultFile)) + if(CANNOT Flush(file)) goto out; break; @@ -95,6 +156,10 @@ tcdrain(int file_descriptor) out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/termios_tcflow.c b/library/termios_tcflow.c index 66485f1..1c630b2 100755 --- a/library/termios_tcflow.c +++ b/library/termios_tcflow.c @@ -1,5 +1,5 @@ /* - * $Id: termios_tcflow.c,v 1.1 2005-06-04 10:46:21 obarthel Exp $ + * $Id: termios_tcflow.c,v 1.2 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -48,18 +48,26 @@ tcflow(int file_descriptor,int UNUSED action) SHOWVALUE(file_descriptor); SHOWVALUE(action); - fd=__get_file_descriptor(file_descriptor); + __stdio_lock(); + + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { __set_errno(EBADF); goto out; } + __fd_lock(fd); + /* XXX TODO */ result = OK; out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/termios_tcflush.c b/library/termios_tcflush.c index 08a6003..22bd9db 100755 --- a/library/termios_tcflush.c +++ b/library/termios_tcflush.c @@ -1,5 +1,5 @@ /* - * $Id: termios_tcflush.c,v 1.2 2005-06-04 13:57:08 obarthel Exp $ + * $Id: termios_tcflush.c,v 1.3 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -52,6 +52,7 @@ tcflush(int file_descriptor,int queue) struct fd *fd; char buf[64]; struct termios *tios; + BPTR file; ENTER(); @@ -60,6 +61,8 @@ tcflush(int file_descriptor,int queue) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL || FLAG_IS_CLEAR(fd->fd_Flags,FDF_TERMIOS)) { @@ -67,6 +70,8 @@ tcflush(int file_descriptor,int queue) goto out; } + __fd_lock(fd); + if(queue < TCIFLUSH || queue > TCIOFLUSH) { SHOWMSG("Invalid queue specified to tcflush()."); @@ -75,27 +80,83 @@ tcflush(int file_descriptor,int queue) goto out; } + file = fd->fd_DefaultFile; + + #if defined(__THREAD_SAFE) + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO)) + { + switch(fd->fd_DefaultFile) + { + case STDIN_FILENO: + + file = Input(); + break; + + case STDOUT_FILENO: + + file = Output(); + break; + + case STDERR_FILENO: + + #if defined(__amigaos4__) + { + file = ErrorOutput(); + } + #else + { + struct Process * this_process = (struct Process *)FindTask(NULL); + + file = this_process->pr_CES; + } + #endif /* __amigaos4__ */ + + /* The following is rather controversial; if the standard error stream + is unavailable, we default to reuse the standard output stream. This + is problematic if the standard output stream was redirected and should + not be the same as the standard error output stream. */ + if(file == ZERO) + file = Output(); + + break; + + default: + + file = ZERO; + break; + } + } + } + #endif /* __THREAD_SAFE */ + tios = fd->fd_Aux; if(queue == TCIFLUSH || queue == TCIOFLUSH) { LONG num_bytes_read; + if(file == ZERO) + { + __set_errno(EBADF); + goto out; + } + /* Set raw mode so we can read without blocking. */ if(FLAG_IS_SET(tios->c_lflag,ICANON)) { - SetMode(fd->fd_DefaultFile,DOSTRUE); + SetMode(file,DOSTRUE); SET_FLAG(fd->fd_Flags,FDF_NON_BLOCKING); } - while(WaitForChar(fd->fd_DefaultFile,1) != DOSFALSE) + while(WaitForChar(file,1) != DOSFALSE) { if(__check_abort_enabled) __check_abort(); /* Read away available data. (upto 8k) */ - num_bytes_read = Read(fd->fd_DefaultFile,buf,64); + num_bytes_read = Read(file,buf,64); if(num_bytes_read == ERROR || num_bytes_read == 0) break; } @@ -103,7 +164,7 @@ tcflush(int file_descriptor,int queue) /* Restore the Raw/Cooked mode. */ if(FLAG_IS_SET(tios->c_lflag,ICANON)) { - SetMode(fd->fd_DefaultFile,DOSFALSE); /* Set Cooked = Canonical mode. */ + SetMode(file,DOSFALSE); /* Set Cooked = Canonical mode. */ CLEAR_FLAG(fd->fd_Flags,FDF_NON_BLOCKING); } @@ -120,6 +181,10 @@ tcflush(int file_descriptor,int queue) out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/termios_tcgetattr.c b/library/termios_tcgetattr.c index 00050d0..a9c631a 100755 --- a/library/termios_tcgetattr.c +++ b/library/termios_tcgetattr.c @@ -1,5 +1,5 @@ /* - * $Id: termios_tcgetattr.c,v 1.1 2005-06-04 10:46:21 obarthel Exp $ + * $Id: termios_tcgetattr.c,v 1.2 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -135,9 +135,11 @@ int tcgetattr(int file_descriptor,struct termios *user_tios) { int result = ERROR; - struct fd *fd; + struct fd *fd = NULL; struct termios *tios; + __stdio_lock(); + if(user_tios == NULL) { __set_errno(EFAULT); @@ -151,6 +153,8 @@ tcgetattr(int file_descriptor,struct termios *user_tios) goto out; } + __fd_lock(fd); + if(FLAG_IS_SET(fd->fd_Flags,FDF_TERMIOS)) { assert(fd->fd_Aux != NULL); @@ -168,7 +172,11 @@ tcgetattr(int file_descriptor,struct termios *user_tios) result = OK; -out: + out: + + __fd_unlock(fd); + + __stdio_unlock(); return(result); } diff --git a/library/termios_tcsendbreak.c b/library/termios_tcsendbreak.c index 04cc25b..cc0db10 100755 --- a/library/termios_tcsendbreak.c +++ b/library/termios_tcsendbreak.c @@ -1,5 +1,5 @@ /* - * $Id: termios_tcsendbreak.c,v 1.1 2005-06-04 10:46:21 obarthel Exp $ + * $Id: termios_tcsendbreak.c,v 1.2 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -63,6 +63,8 @@ tcsendbreak(int file_descriptor,int duration) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL || FLAG_IS_CLEAR(fd->fd_Flags,FDF_TERMIOS)) { @@ -70,6 +72,8 @@ tcsendbreak(int file_descriptor,int duration) goto out; } + __fd_lock(fd); + assert( fd->fd_Aux != NULL ); tios = fd->fd_Aux; @@ -103,6 +107,10 @@ tcsendbreak(int file_descriptor,int duration) out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/termios_tcsetattr.c b/library/termios_tcsetattr.c index 92f1af5..f482453 100755 --- a/library/termios_tcsetattr.c +++ b/library/termios_tcsetattr.c @@ -1,5 +1,5 @@ /* - * $Id: termios_tcsetattr.c,v 1.1 2005-06-04 10:46:21 obarthel Exp $ + * $Id: termios_tcsetattr.c,v 1.2 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -42,6 +42,7 @@ set_console_termios(struct fd *fd,struct termios *new_tios) { struct termios *old_tios; int result = ERROR; + BPTR file; /* TODO: Check for some "impossible" combinations here? */ @@ -52,15 +53,68 @@ set_console_termios(struct fd *fd,struct termios *new_tios) if(old_tios->type != TIOST_CONSOLE) goto out; + file = fd->fd_DefaultFile; + + #if defined(__THREAD_SAFE) + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO)) + { + switch(fd->fd_DefaultFile) + { + case STDIN_FILENO: + + file = Input(); + break; + + case STDOUT_FILENO: + + file = Output(); + break; + + case STDERR_FILENO: + + #if defined(__amigaos4__) + { + file = ErrorOutput(); + } + #else + { + struct Process * this_process = (struct Process *)FindTask(NULL); + + file = this_process->pr_CES; + } + #endif /* __amigaos4__ */ + + /* The following is rather controversial; if the standard error stream + is unavailable, we default to reuse the standard output stream. This + is problematic if the standard output stream was redirected and should + not be the same as the standard error output stream. */ + if(file == ZERO) + file = Output(); + + break; + + default: + + file = ZERO; + break; + } + } + } + #endif /* __THREAD_SAFE */ + + if(file == ZERO) + goto out; + if(FLAG_IS_CLEAR(new_tios->c_lflag,ICANON)) { - SetMode(fd->fd_DefaultFile,DOSTRUE); /* Set Raw = Non-Canonical mode. */ + SetMode(file,DOSTRUE); /* Set Raw = Non-Canonical mode. */ SET_FLAG(fd->fd_Flags,FDF_NON_BLOCKING); } else { - SetMode(fd->fd_DefaultFile,DOSFALSE); /* Set Cooked = Canonical mode. */ + SetMode(file,DOSFALSE); /* Set Cooked = Canonical mode. */ CLEAR_FLAG(fd->fd_Flags,FDF_NON_BLOCKING); } @@ -81,18 +135,20 @@ int tcsetattr(int file_descriptor,int how,struct termios *tios) { int result = ERROR; - struct fd *fd_Term; + struct fd *fd; struct termios new_tios; int type; + __stdio_lock(); + if(tios == NULL) { __set_errno(EFAULT); goto out; } - fd_Term = __get_file_descriptor(file_descriptor); - if(fd_Term == NULL) + fd = __get_file_descriptor(file_descriptor); + if(fd == NULL) { SHOWMSG("tcsetattr() was not called with a file descriptor.\n"); @@ -100,6 +156,8 @@ tcsetattr(int file_descriptor,int how,struct termios *tios) goto out; } + __fd_lock(fd); + /* The following is in case the termios structure was manually constructed. (it should have been zero:ed in that case) */ if(tios->type == TIOST_INVALID) { @@ -136,7 +194,7 @@ tcsetattr(int file_descriptor,int how,struct termios *tios) goto out; } - if(set_console_termios(fd_Term,tios) != OK) + if(set_console_termios(fd,tios) != OK) { __set_errno(EIO); goto out; @@ -150,7 +208,11 @@ tcsetattr(int file_descriptor,int how,struct termios *tios) result = OK; -out: + out: + + __fd_unlock(fd); + + __stdio_unlock(); return(result); } diff --git a/library/uio_readv.c b/library/uio_readv.c index 7c159a2..87627d3 100644 --- a/library/uio_readv.c +++ b/library/uio_readv.c @@ -1,5 +1,5 @@ /* - * $Id: uio_readv.c,v 1.3 2005-04-24 08:46:37 obarthel Exp $ + * $Id: uio_readv.c,v 1.4 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -64,6 +64,8 @@ readv(int file_descriptor,const struct iovec *iov,int vec_count) SHOWPOINTER(iov); SHOWVALUE(vec_count); + __stdio_lock(); + #if defined(CHECK_FOR_NULL_POINTERS) { if(iov == NULL) @@ -98,6 +100,8 @@ readv(int file_descriptor,const struct iovec *iov,int vec_count) goto out; } + __fd_lock(fd); + total_num_bytes_read = 0; part_num_bytes_read = 0; @@ -142,7 +146,11 @@ readv(int file_descriptor,const struct iovec *iov,int vec_count) result = total_num_bytes_read; -out: + out: + + __fd_unlock(fd); + + __stdio_unlock(); RETURN(result); return(result); diff --git a/library/uio_writev.c b/library/uio_writev.c index 55b0138..6698581 100644 --- a/library/uio_writev.c +++ b/library/uio_writev.c @@ -1,5 +1,5 @@ /* - * $Id: uio_writev.c,v 1.3 2005-04-24 08:46:37 obarthel Exp $ + * $Id: uio_writev.c,v 1.4 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -54,7 +54,7 @@ writev(int file_descriptor,const struct iovec *iov,int vec_count) struct file_action_message msg; ssize_t total_num_bytes_written; char * buffer = NULL; - struct fd * fd; + struct fd * fd = NULL; int i; ENTER(); @@ -63,6 +63,8 @@ writev(int file_descriptor,const struct iovec *iov,int vec_count) SHOWPOINTER(iov); SHOWVALUE(vec_count); + __stdio_lock(); + #if defined(CHECK_FOR_NULL_POINTERS) { if(iov == NULL) @@ -98,6 +100,8 @@ writev(int file_descriptor,const struct iovec *iov,int vec_count) goto out; } + __fd_lock(fd); + buffer = malloc(total_num_bytes_written); if(buffer != NULL) { @@ -143,11 +147,15 @@ writev(int file_descriptor,const struct iovec *iov,int vec_count) result = total_num_bytes_written; -out: + out: if(buffer != NULL) free(buffer); + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/unistd_fchown.c b/library/unistd_fchown.c index 0bb0086..5b33362 100644 --- a/library/unistd_fchown.c +++ b/library/unistd_fchown.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_fchown.c,v 1.10 2005-04-24 08:46:37 obarthel Exp $ + * $Id: unistd_fchown.c,v 1.11 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -65,6 +65,8 @@ fchown(int file_descriptor, uid_t owner, gid_t group) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { @@ -182,6 +184,8 @@ fchown(int file_descriptor, uid_t owner, gid_t group) PROFILE_ON(); + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/unistd_fdatasync.c b/library/unistd_fdatasync.c index 80fee5e..0ce48f8 100644 --- a/library/unistd_fdatasync.c +++ b/library/unistd_fdatasync.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_fdatasync.c,v 1.6 2005-04-24 08:46:37 obarthel Exp $ + * $Id: unistd_fdatasync.c,v 1.7 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -64,6 +64,8 @@ fdatasync(int file_descriptor) assert( __fd[file_descriptor] != NULL ); assert( FLAG_IS_SET(__fd[file_descriptor]->fd_Flags,FDF_IN_USE) ); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { @@ -71,6 +73,8 @@ fdatasync(int file_descriptor) goto out; } + __fd_lock(fd); + if(__sync_fd(fd,0) < 0) /* flush just the data */ goto out; @@ -78,6 +82,10 @@ fdatasync(int file_descriptor) out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/unistd_fsync.c b/library/unistd_fsync.c index 680dacd..8ff2ad7 100644 --- a/library/unistd_fsync.c +++ b/library/unistd_fsync.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_fsync.c,v 1.6 2005-04-24 08:46:37 obarthel Exp $ + * $Id: unistd_fsync.c,v 1.7 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -63,6 +63,8 @@ fsync(int file_descriptor) assert( __fd[file_descriptor] != NULL ); assert( FLAG_IS_SET(__fd[file_descriptor]->fd_Flags,FDF_IN_USE) ); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { @@ -70,6 +72,8 @@ fsync(int file_descriptor) goto out; } + __fd_lock(fd); + if(__sync_fd(fd,1) < 0) /* flush everything */ goto out; @@ -77,6 +81,10 @@ fsync(int file_descriptor) out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/unistd_ftruncate.c b/library/unistd_ftruncate.c index b8bb62b..69f9ee9 100644 --- a/library/unistd_ftruncate.c +++ b/library/unistd_ftruncate.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_ftruncate.c,v 1.12 2005-04-24 09:53:12 obarthel Exp $ + * $Id: unistd_ftruncate.c,v 1.13 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -65,6 +65,8 @@ ftruncate(int file_descriptor, off_t length) PROFILE_OFF(); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { @@ -200,6 +202,8 @@ ftruncate(int file_descriptor, off_t length) __fd_unlock(fd); + __stdio_unlock(); + PROFILE_ON(); RETURN(result); diff --git a/library/unistd_isatty.c b/library/unistd_isatty.c index 8a49a19..b96db87 100644 --- a/library/unistd_isatty.c +++ b/library/unistd_isatty.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_isatty.c,v 1.6 2005-04-24 08:46:37 obarthel Exp $ + * $Id: unistd_isatty.c,v 1.7 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -58,6 +58,8 @@ isatty(int file_descriptor) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { @@ -65,13 +67,83 @@ isatty(int file_descriptor) goto out; } - if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) - result = 1; - else - result = 0; + __fd_lock(fd); + + #if defined(__THREAD_SAFE) + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO)) + { + BPTR file; + + switch(fd->fd_DefaultFile) + { + case STDIN_FILENO: + + file = Input(); + break; + + case STDOUT_FILENO: + + file = Output(); + break; + + case STDERR_FILENO: + + #if defined(__amigaos4__) + { + file = ErrorOutput(); + } + #else + { + struct Process * this_process = (struct Process *)FindTask(NULL); + + file = this_process->pr_CES; + } + #endif /* __amigaos4__ */ + + /* The following is rather controversial; if the standard error stream + is unavailable, we default to reuse the standard output stream. This + is problematic if the standard output stream was redirected and should + not be the same as the standard error output stream. */ + if(file == ZERO) + file = Output(); + + break; + + default: + + file = ZERO; + break; + } + + if(file != ZERO && IsInteractive(file)) + result = 1; + else + result = 0; + } + else + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) + result = 1; + else + result = 0; + } + } + #else + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) + result = 1; + else + result = 0; + } + #endif /* __THREAD_SAFE */ out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/unistd_ttyname.c b/library/unistd_ttyname.c index dd77e88..26eaf9a 100755 --- a/library/unistd_ttyname.c +++ b/library/unistd_ttyname.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_ttyname.c,v 1.1 2005-06-04 10:46:21 obarthel Exp $ + * $Id: unistd_ttyname.c,v 1.2 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -45,12 +45,15 @@ char * ttyname(int file_descriptor) { char * result = NULL; + BOOL is_tty = FALSE; struct fd *fd; ENTER(); SHOWVALUE(file_descriptor); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { @@ -58,7 +61,76 @@ ttyname(int file_descriptor) goto out; } - if(FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_INTERACTIVE)) + __fd_lock(fd); + + #if defined(__THREAD_SAFE) + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO)) + { + BPTR file; + + switch(fd->fd_DefaultFile) + { + case STDIN_FILENO: + + file = Input(); + break; + + case STDOUT_FILENO: + + file = Output(); + break; + + case STDERR_FILENO: + + #if defined(__amigaos4__) + { + file = ErrorOutput(); + } + #else + { + struct Process * this_process = (struct Process *)FindTask(NULL); + + file = this_process->pr_CES; + } + #endif /* __amigaos4__ */ + + /* The following is rather controversial; if the standard error stream + is unavailable, we default to reuse the standard output stream. This + is problematic if the standard output stream was redirected and should + not be the same as the standard error output stream. */ + if(file == ZERO) + file = Output(); + + break; + + default: + + file = ZERO; + break; + } + + __fd_lock(fd); + + if(file != ZERO && IsInteractive(file)) + is_tty = TRUE; + + __fd_unlock(fd); + } + else + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) + is_tty = TRUE; + } + } + #else + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) + is_tty = TRUE; + } + #endif /* __THREAD_SAFE */ + + if(NOT is_tty) { __set_errno(ENOTTY); goto out; @@ -68,6 +140,10 @@ ttyname(int file_descriptor) out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/unistd_ttyname_r.c b/library/unistd_ttyname_r.c index d5f49c1..995688b 100755 --- a/library/unistd_ttyname_r.c +++ b/library/unistd_ttyname_r.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_ttyname_r.c,v 1.1 2005-06-04 10:46:21 obarthel Exp $ + * $Id: unistd_ttyname_r.c,v 1.2 2005-07-06 18:48:53 obarthel Exp $ * * :ts=4 * @@ -44,6 +44,7 @@ int ttyname_r(int file_descriptor,char *name,size_t buflen) { + BOOL is_tty = FALSE; struct fd *fd; int result; @@ -51,6 +52,8 @@ ttyname_r(int file_descriptor,char *name,size_t buflen) SHOWVALUE(file_descriptor); + __stdio_lock(); + fd = __get_file_descriptor(file_descriptor); if(fd == NULL) { @@ -58,7 +61,76 @@ ttyname_r(int file_descriptor,char *name,size_t buflen) goto out; } - if(FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_INTERACTIVE)) + __fd_lock(fd); + + #if defined(__THREAD_SAFE) + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_STDIO)) + { + BPTR file; + + switch(fd->fd_DefaultFile) + { + case STDIN_FILENO: + + file = Input(); + break; + + case STDOUT_FILENO: + + file = Output(); + break; + + case STDERR_FILENO: + + #if defined(__amigaos4__) + { + file = ErrorOutput(); + } + #else + { + struct Process * this_process = (struct Process *)FindTask(NULL); + + file = this_process->pr_CES; + } + #endif /* __amigaos4__ */ + + /* The following is rather controversial; if the standard error stream + is unavailable, we default to reuse the standard output stream. This + is problematic if the standard output stream was redirected and should + not be the same as the standard error output stream. */ + if(file == ZERO) + file = Output(); + + break; + + default: + + file = ZERO; + break; + } + + __fd_lock(fd); + + if(file != ZERO && IsInteractive(file)) + is_tty = TRUE; + + __fd_unlock(fd); + } + else + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) + is_tty = TRUE; + } + } + #else + { + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) + is_tty = TRUE; + } + #endif /* __THREAD_SAFE */ + + if(NOT is_tty) { result = ENOTTY; goto out; @@ -76,6 +148,10 @@ ttyname_r(int file_descriptor,char *name,size_t buflen) out: + __fd_unlock(fd); + + __stdio_unlock(); + RETURN(result); return(result); }