From 49df44872db5813d1e7be1f1bfec3ab5bd1b0c9f Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Mon, 27 Dec 2004 09:15:55 +0000 Subject: [PATCH] - fwrite() now flushes the entire "buffer" for unbuffered files. The exception are "interactive" files such as console windows. For these line buffered output is used. - Whether or not a file is bound to an interactive device, such as a console window, is now checked and remembered after a file descriptor has been associated with it. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14788 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/changes | 8 ++++++++ library/fcntl_open.c | 20 ++++++++++++------- library/socket_select.c | 14 +++----------- library/stdio_fdhookentry.c | 19 ++---------------- library/stdio_fwrite.c | 19 ++++++++++-------- library/stdio_headers.h | 8 +++++++- library/stdio_init_exit.c | 31 +++++++++++++++++++++++++----- library/stdlib_assertion_failure.c | 14 ++++---------- library/unistd_isatty.c | 20 +++++-------------- 9 files changed, 79 insertions(+), 74 deletions(-) diff --git a/library/changes b/library/changes index 3e3187b..d63b534 100644 --- a/library/changes +++ b/library/changes @@ -32,6 +32,14 @@ for the 68040/68060 but not for the PowerPC, which uses 32 or 128 bytes per cache line. +- fwrite() now flushes the entire "buffer" for unbuffered files. The + exception are "interactive" files such as console windows. For these + line buffered output is used. + +- Whether or not a file is bound to an interactive device, such as a + console window, is now checked and remembered after a file descriptor + has been associated with it. + c.lib 1.184 (28.11.2004) diff --git a/library/fcntl_open.c b/library/fcntl_open.c index 2adcf75..e692f83 100644 --- a/library/fcntl_open.c +++ b/library/fcntl_open.c @@ -1,5 +1,5 @@ /* - * $Id: fcntl_open.c,v 1.2 2004-08-07 09:15:32 obarthel Exp $ + * $Id: fcntl_open.c,v 1.3 2004-12-27 09:15:54 obarthel Exp $ * * :ts=4 * @@ -67,7 +67,7 @@ open(const char *path_name, int open_flag, ... /* mode_t mode */ ) struct FileHandle * file_handle; BPTR handle = ZERO; BOOL create_new_file = FALSE; - LONG is_interactive; + LONG is_interactive = FALSE; int fd_slot_number; struct fd * fd; int access_mode; @@ -342,13 +342,19 @@ open(const char *path_name, int open_flag, ... /* mode_t mode */ ) __initialize_fd(fd,(HOOKFUNC)__fd_hook_entry,handle,0); + /* Figure out if this stream is attached to a console. */ PROFILE_OFF(); - is_interactive = IsInteractive(handle); + + if(file_handle->fh_Type != NULL) + is_interactive = IsInteractive(handle); + PROFILE_ON(); - if(FLAG_IS_SET(open_flag,O_NONBLOCK)) + if(is_interactive) { - if(is_interactive) + SET_FLAG(fd->fd_Flags,FDF_IS_INTERACTIVE); + + if(FLAG_IS_SET(open_flag,O_NONBLOCK)) { SHOWMSG("enabling non-blocking mode"); @@ -356,12 +362,12 @@ open(const char *path_name, int open_flag, ... /* mode_t mode */ ) SET_FLAG(fd->fd_Flags,FDF_NON_BLOCKING); } } - - if(NOT is_interactive) + else { size_t len; len = 0; + for(i = 0 ; i < (int)strlen(path_name) ; i++) { if(path_name[i] == ':') diff --git a/library/socket_select.c b/library/socket_select.c index 9caa91a..ae68995 100644 --- a/library/socket_select.c +++ b/library/socket_select.c @@ -1,5 +1,5 @@ /* - * $Id: socket_select.c,v 1.1.1.1 2004-07-26 16:31:19 obarthel Exp $ + * $Id: socket_select.c,v 1.2 2004-12-27 09:15:54 obarthel Exp $ * * :ts=4 * @@ -304,16 +304,8 @@ map_descriptor_sets( } else { - LONG is_interactive; - - /* We only watch files bound to - * console streams. - */ - PROFILE_OFF(); - is_interactive = IsInteractive(fd->fd_DefaultFile); - PROFILE_ON(); - - if(NOT is_interactive) + /* We only watch files bound to console streams. */ + if(FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_INTERACTIVE)) { SHOWMSG("this is a file"); continue; diff --git a/library/stdio_fdhookentry.c b/library/stdio_fdhookentry.c index 7cc4b5b..f33af96 100644 --- a/library/stdio_fdhookentry.c +++ b/library/stdio_fdhookentry.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_fdhookentry.c,v 1.3 2004-12-26 13:14:47 obarthel Exp $ + * $Id: stdio_fdhookentry.c,v 1.4 2004-12-27 09:15:55 obarthel Exp $ * * :ts=4 * @@ -1823,7 +1823,7 @@ __fd_hook_entry( PROFILE_OFF(); - if(fd->fd_DefaultFile != ZERO && ((struct FileHandle *)BADDR(fd->fd_DefaultFile))->fh_Type != NULL && IsInteractive(fd->fd_DefaultFile)) + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) { LONG mode; @@ -2169,21 +2169,6 @@ __fd_hook_entry( result = 0; break; - case file_hook_action_is_interactive: - - SHOWMSG("file_hook_action_is_interactive"); - - PROFILE_OFF(); - - if(fd->fd_DefaultFile != ZERO && ((struct FileHandle *)BADDR(fd->fd_DefaultFile))->fh_Type != NULL && IsInteractive(fd->fd_DefaultFile)) - result = 1; - else - result = 0; - - PROFILE_ON(); - - break; - default: SHOWVALUE(message->action); diff --git a/library/stdio_fwrite.c b/library/stdio_fwrite.c index 6addfa6..2cc8e19 100644 --- a/library/stdio_fwrite.c +++ b/library/stdio_fwrite.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_fwrite.c,v 1.1.1.1 2004-07-26 16:31:33 obarthel Exp $ + * $Id: stdio_fwrite.c,v 1.2 2004-12-27 09:15:55 obarthel Exp $ * * :ts=4 * @@ -113,7 +113,10 @@ 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) - buffer_mode = IOBF_BUFFER_MODE_LINE; + { + if(FLAG_IS_SET(__fd[file->iob_Descriptor]->fd_Flags,FDF_IS_INTERACTIVE)) + buffer_mode = IOBF_BUFFER_MODE_LINE; + } if(buffer_mode == IOBF_BUFFER_MODE_LINE) { @@ -126,12 +129,6 @@ fwrite(const void *ptr,size_t element_size,size_t count,FILE *stream) total_bytes_written++; } - - if((file->iob_Flags & IOBF_BUFFER_MODE) == IOBF_BUFFER_MODE_NONE) - { - if(__iob_write_buffer_is_valid(file) && __flush_iob_write_buffer(file) < 0) - goto out; - } } else { @@ -146,6 +143,12 @@ fwrite(const void *ptr,size_t element_size,size_t count,FILE *stream) } } + if((file->iob_Flags & IOBF_BUFFER_MODE) == IOBF_BUFFER_MODE_NONE) + { + if(__iob_write_buffer_is_valid(file) && __flush_iob_write_buffer(file) < 0) + goto out; + } + result = total_bytes_written / element_size; } diff --git a/library/stdio_headers.h b/library/stdio_headers.h index 725e0f2..86288b4 100644 --- a/library/stdio_headers.h +++ b/library/stdio_headers.h @@ -1,5 +1,5 @@ /* - * $Id: stdio_headers.h,v 1.6 2004-12-26 13:14:47 obarthel Exp $ + * $Id: stdio_headers.h,v 1.7 2004-12-27 09:15:55 obarthel Exp $ * * :ts=4 * @@ -108,7 +108,11 @@ This should be determined dynamically rather than preset here. For the 68040/68060 the cache line size is 16 bytes, for the PowerPC G4 it's 32 bytes and 128 bytes (gross!) for the PowerPC G5. */ +#if defined(__PPC__) #define CACHE_LINE_SIZE 32UL +#else +#define CACHE_LINE_SIZE 16UL +#endif /* __PPC__ */ /****************************************************************************/ @@ -262,6 +266,8 @@ struct iob #define FDF_CACHE_POSITION (1UL<<9) /* Cache the file position. */ #define FDF_ASYNC_IO (1UL<<10) /* File was switched into asynchronous I/O mode (sockets only). */ +#define FDF_IS_INTERACTIVE (1UL<<11) /* File is attached to a console window or + something like it. */ /****************************************************************************/ diff --git a/library/stdio_init_exit.c b/library/stdio_init_exit.c index af43e31..e83a44e 100644 --- a/library/stdio_init_exit.c +++ b/library/stdio_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_init_exit.c,v 1.4 2004-12-26 13:14:47 obarthel Exp $ + * $Id: stdio_init_exit.c,v 1.5 2004-12-27 09:15:55 obarthel Exp $ * * :ts=4 * @@ -180,6 +180,19 @@ __stdio_init(void) if(buffer == NULL) goto out; + /* Check if this stream is attached to a console window. */ + if(default_file != ZERO) + { + struct FileHandle * fh = BADDR(default_file); + + PROFILE_OFF(); + + if(fh->fh_Type != NULL && IsInteractive(default_file)) + SET_FLAG(fd_flags,FDF_IS_INTERACTIVE); + + PROFILE_ON(); + } + /* Align the buffer start address to a cache line boundary. */ aligned_buffer = (char *)((ULONG)(buffer + (CACHE_LINE_SIZE-1)) & ~(CACHE_LINE_SIZE-1)); @@ -241,11 +254,19 @@ __stdio_init(void) PROFILE_OFF(); - /* Check if the standard error output refers to a console or must + /* Figure out if the standard error stream is bound to a console. */ + if(__fd[STDERR_FILENO]->fd_DefaultFile != ZERO) + { + struct FileHandle * fh = BADDR(IsInteractive(__fd[STDERR_FILENO]->fd_DefaultFile)); + + if(fh->fh_Type != NULL && IsInteractive(__fd[STDERR_FILENO]->fd_DefaultFile)) + SET_FLAG(__fd[STDERR_FILENO]->fd_Flags,FDF_IS_INTERACTIVE); + } + + /* Check if the standard/error output refers to a console or must be considered unusable for console output. */ - if(__fd[STDERR_FILENO]->fd_DefaultFile == ZERO || - ((struct FileHandle *)BADDR(__fd[STDERR_FILENO]->fd_DefaultFile))->fh_Type == NULL || - NOT IsInteractive(__fd[STDERR_FILENO]->fd_DefaultFile)) + if(FLAG_IS_CLEAR(__fd[STDOUT_FILENO]->fd_Flags,FDF_IS_INTERACTIVE) || + FLAG_IS_CLEAR(__fd[STDERR_FILENO]->fd_Flags,FDF_IS_INTERACTIVE)) { /* The standard I/O streams are no longer attached to a console. */ __no_standard_io = TRUE; diff --git a/library/stdlib_assertion_failure.c b/library/stdlib_assertion_failure.c index 7e90172..944cab2 100644 --- a/library/stdlib_assertion_failure.c +++ b/library/stdlib_assertion_failure.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_assertion_failure.c,v 1.2 2004-12-26 10:28:56 obarthel Exp $ + * $Id: stdlib_assertion_failure.c,v 1.3 2004-12-27 09:15:55 obarthel Exp $ * * :ts=4 * @@ -80,17 +80,11 @@ __assertion_failure( if(fd != NULL && FLAG_IS_SET(fd->fd_Flags,FDF_IN_USE) && FLAG_IS_SET(fd->fd_Flags,FDF_WRITE) && - FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_SOCKET)) + FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) { - BPTR file_handle; + assert( FLAG_IS_CLEAR(fd->fd_Flags,FDF_IS_SOCKET) ); - file_handle = fd->fd_DefaultFile; - if(file_handle != ZERO && - ((struct FileHandle *)BADDR(file_handle))->fh_Type != NULL && - IsInteractive(file_handle)) - { - use_stderr = TRUE; - } + use_stderr = TRUE; } } } diff --git a/library/unistd_isatty.c b/library/unistd_isatty.c index 6505d88..da89dc2 100644 --- a/library/unistd_isatty.c +++ b/library/unistd_isatty.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_isatty.c,v 1.2 2004-08-07 09:15:32 obarthel Exp $ + * $Id: unistd_isatty.c,v 1.3 2004-12-27 09:15:55 obarthel Exp $ * * :ts=4 * @@ -44,8 +44,6 @@ int isatty(int file_descriptor) { - DECLARE_UTILITYBASE(); - struct file_hook_message message; int result = -1; struct fd * fd; @@ -53,8 +51,6 @@ isatty(int file_descriptor) SHOWVALUE(file_descriptor); - assert( UtilityBase != NULL ); - assert( file_descriptor >= 0 && file_descriptor < __num_fd ); assert( __fd[file_descriptor] != NULL ); assert( FLAG_IS_SET(__fd[file_descriptor]->fd_Flags,FDF_IN_USE) ); @@ -69,16 +65,10 @@ isatty(int file_descriptor) goto out; } - SHOWMSG("calling the hook"); - - message.action = file_hook_action_is_interactive; - - assert( fd->fd_Hook != NULL ); - - CallHookPkt(fd->fd_Hook,fd,&message); - - result = message.result; - errno = message.error; + if(FLAG_IS_SET(fd->fd_Flags,FDF_IS_INTERACTIVE)) + result = 1; + else + result = 0; out: