From a9c8cdc554dd93bb98b0f94563e87b00d58418fa Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Mon, 7 Mar 2005 11:16:43 +0000 Subject: [PATCH] - Moved the Workbench console stream initialization into the initialization code for the stdin/stdout/stderr streams and out of the program parameter setup. - The current program name is now set up in the stdlib initialization function. - Simplified the machine test code; moved the FPU check into the math initialization code. - Added more safety checks to verify that file descriptor file handles are valid. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14864 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/GNUmakefile.68k | 6 +- library/GNUmakefile.os4 | 6 +- library/changes | 16 + library/math_init_exit.c | 17 +- library/mount_fstatfs.c | 8 +- library/smakefile | 7 +- library/stat_fchmod.c | 8 +- library/stdio_fdhookentry.c | 83 ++--- library/stdio_file_init.c | 363 +++++++++++++++++++++ library/stdio_init_exit.c | 158 +-------- library/stdio_protos.h | 7 +- library/{stdlib_startup.c => stdlib_arg.c} | 174 +--------- library/stdlib_data.c | 7 +- library/stdlib_headers.h | 6 +- library/stdlib_init_exit.c | 40 ++- library/stdlib_machine_test.c | 30 +- library/stdlib_main.c | 6 +- library/stdlib_protos.h | 6 +- library/unistd_fchown.c | 8 +- library/unistd_fdatasync.c | 8 +- library/unistd_fsync.c | 8 +- library/unistd_ftruncate.c | 8 +- library/unistd_sync_fd.c | 23 +- 23 files changed, 558 insertions(+), 445 deletions(-) create mode 100644 library/stdio_file_init.c rename library/{stdlib_startup.c => stdlib_arg.c} (66%) diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index a7c5f15..85c6bc1 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.34 2005-03-03 14:20:55 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.35 2005-03-07 11:16:42 obarthel Exp $ # # :ts=8 # @@ -225,6 +225,7 @@ C_LIB = \ stdio_initializefd.o \ stdio_initializeiob.o \ stdio_init_exit.o \ + stdio_file_init.o \ stdio_iobhookentry.o \ stdio_lock.o \ stdio_locksemaphorename.o \ @@ -332,7 +333,7 @@ C_LIB = \ stdlib_stacksafezone.o \ stdlib_stacksize.o \ stdlib_stack_usage.o \ - stdlib_startup.o \ + stdlib_arg.o \ stdlib_stdio_window_spec.o \ stdlib_strtol.o \ stdlib_strtoll.o \ @@ -458,6 +459,7 @@ UNIX_LIB = \ stdio_fflush.o \ stdio_fopen.o \ stdio_init_exit.o \ + stdio_file_init.o \ stdio_locksemaphorename.o \ stdio_openiob.o \ stdio_popen.o \ diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index a47a54b..3b1d599 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.35 2005-03-05 17:55:26 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.36 2005-03-07 11:16:43 obarthel Exp $ # # :ts=8 # @@ -229,6 +229,7 @@ C_LIB = \ stdio_initializefd.o \ stdio_initializeiob.o \ stdio_init_exit.o \ + stdio_file_init.o \ stdio_iobhookentry.o \ stdio_lock.o \ stdio_locksemaphorename.o \ @@ -336,7 +337,7 @@ C_LIB = \ stdlib_stacksafezone.o \ stdlib_stacksize.o \ stdlib_stack_usage.o \ - stdlib_startup.o \ + stdlib_arg.o \ stdlib_stdio_window_spec.o \ stdlib_strtol.o \ stdlib_strtoll.o \ @@ -462,6 +463,7 @@ UNIX_LIB = \ stdio_fdhookentry.o \ stdio_fflush.o \ stdio_fopen.o \ + stdio_file_init.o \ stdio_init_exit.o \ stdio_locksemaphorename.o \ stdio_openiob.o \ diff --git a/library/changes b/library/changes index 2d4f96b..032d384 100644 --- a/library/changes +++ b/library/changes @@ -6,6 +6,22 @@ code can spend less time in Forbid() state and, heaven forbid, refrain from allocating memory while in that state. +- Split the general stdio initialization/cleanup code from the + initialization of the stdin/stdout/stderr streams. + +- Moved the Workbench console stream initialization into the + initialization code for the stdin/stdout/stderr streams and + out of the program parameter setup. + +- The current program name is now set up in the stdlib + initialization function. + +- Simplified the machine test code; moved the FPU check into + the math initialization code. + +- Added more safety checks to verify that file descriptor + file handles are valid. + c.lib 1.189 (5.3.2005) diff --git a/library/math_init_exit.c b/library/math_init_exit.c index 2df3397..01a8777 100644 --- a/library/math_init_exit.c +++ b/library/math_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: math_init_exit.c,v 1.7 2005-02-03 16:56:15 obarthel Exp $ + * $Id: math_init_exit.c,v 1.8 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -41,6 +41,10 @@ /****************************************************************************/ +#include + +/****************************************************************************/ + #include /****************************************************************************/ @@ -89,6 +93,17 @@ __math_init(void) { int result = ERROR; + #if defined(M68881_FLOATING_POINT_SUPPORT) + { + if(FLAG_IS_CLEAR(((struct ExecBase *)SysBase)->AttnFlags,AFF_68881)) + { + __show_error("This program requires a floating point processor."); + + goto out; + } + } + #endif /* M68881_FLOATING_POINT_SUPPORT */ + #if defined(IEEE_FLOATING_POINT_SUPPORT) { char * failed_library = NULL; diff --git a/library/mount_fstatfs.c b/library/mount_fstatfs.c index 822d4b2..d3f3e28 100644 --- a/library/mount_fstatfs.c +++ b/library/mount_fstatfs.c @@ -1,5 +1,5 @@ /* - * $Id: mount_fstatfs.c,v 1.8 2005-02-28 13:22:53 obarthel Exp $ + * $Id: mount_fstatfs.c,v 1.9 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -97,6 +97,12 @@ fstatfs(int file_descriptor, struct statfs *buf) goto out; } + if(fd->fd_DefaultFile == ZERO) + { + __set_errno(EBADF); + goto out; + } + PROFILE_OFF(); parent_dir = __safe_parent_of_file_handle(fd->fd_DefaultFile); PROFILE_ON(); diff --git a/library/smakefile b/library/smakefile index ece54be..cd552e2 100644 --- a/library/smakefile +++ b/library/smakefile @@ -1,5 +1,5 @@ # -# $Id: smakefile,v 1.28 2005-03-03 14:20:55 obarthel Exp $ +# $Id: smakefile,v 1.29 2005-03-07 11:16:43 obarthel Exp $ # # :ts=8 # @@ -329,6 +329,7 @@ STDIO_OBJ = \ stdio_grow_file.o \ stdio_initializefd.o \ stdio_initializeiob.o \ + stdio_file_init.o \ stdio_init_exit.o \ stdio_iobhookentry.o \ stdio_lock.o \ @@ -439,7 +440,7 @@ STDLIB_OBJ = \ stdlib_stacksafezone.o \ stdlib_stacksize.o \ stdlib_stack_usage.o \ - stdlib_startup.o \ + stdlib_arg.o \ stdlib_strtod.o \ stdlib_strtol.o \ stdlib_strtoul.o \ @@ -701,7 +702,7 @@ stdlib_atexit.o : stdlib_atexit.c stdlib_mem_debug.h stdlib_setenv.o : stdlib_setenv.c stdlib_mem_debug.h -stdlib_startup.o : stdlib_startup.c stdlib_mem_debug.h +stdlib_arg.o : stdlib_arg.c stdlib_mem_debug.h stdlib_system.o : stdlib_system.c stdlib_mem_debug.h diff --git a/library/stat_fchmod.c b/library/stat_fchmod.c index 6fb6580..91117ec 100644 --- a/library/stat_fchmod.c +++ b/library/stat_fchmod.c @@ -1,5 +1,5 @@ /* - * $Id: stat_fchmod.c,v 1.7 2005-02-28 13:22:53 obarthel Exp $ + * $Id: stat_fchmod.c,v 1.8 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -80,6 +80,12 @@ fchmod(int file_descriptor, mode_t mode) goto out; } + if(fd->fd_DefaultFile == ZERO) + { + __set_errno(EBADF); + goto out; + } + protection = 0; if(FLAG_IS_SET(mode,S_IRUSR)) diff --git a/library/stdio_fdhookentry.c b/library/stdio_fdhookentry.c index 39f995c..d96b0f5 100644 --- a/library/stdio_fdhookentry.c +++ b/library/stdio_fdhookentry.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_fdhookentry.c,v 1.16 2005-03-03 14:20:55 obarthel Exp $ + * $Id: stdio_fdhookentry.c,v 1.17 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -59,6 +59,7 @@ __fd_hook_entry( { D_S(struct FileInfoBlock,fib); BOOL fib_is_valid = FALSE; + struct FileHandle * fh; off_t current_position; off_t new_position; int new_mode; @@ -72,20 +73,20 @@ __fd_hook_entry( __fd_lock(fd); + if(fd->fd_DefaultFile == ZERO) + { + SHOWMSG("file is closed"); + + fam->fam_Error = EBADF; + goto out; + } + switch(fam->fam_Action) { case file_action_read: SHOWMSG("file_action_read"); - if(fd->fd_DefaultFile == ZERO) - { - SHOWMSG("file is closed"); - - fam->fam_Error = EBADF; - break; - } - assert( fam->fam_Data != NULL ); assert( fam->fam_Size > 0 ); @@ -102,7 +103,7 @@ __fd_hook_entry( D(("read failed ioerr=%ld",IoErr())); fam->fam_Error = __translate_io_error_to_errno(IoErr()); - break; + goto out; } if(FLAG_IS_SET(fd->fd_Flags,FDF_CACHE_POSITION)) @@ -114,14 +115,6 @@ __fd_hook_entry( SHOWMSG("file_action_write"); - if(fd->fd_DefaultFile == ZERO) - { - SHOWMSG("file is closed"); - - fam->fam_Error = EBADF; - break; - } - assert( fam->fam_Data != NULL ); assert( fam->fam_Size > 0 ); @@ -153,7 +146,7 @@ __fd_hook_entry( D(("write failed ioerr=%ld",IoErr())); fam->fam_Error = __translate_io_error_to_errno(IoErr()); - break; + goto out; } if(FLAG_IS_SET(fd->fd_Flags,FDF_CACHE_POSITION)) @@ -172,15 +165,6 @@ __fd_hook_entry( } else { - /* Is this file open in the first place? */ - if(fd->fd_DefaultFile == ZERO) - { - SHOWMSG("file is closed"); - - fam->fam_Error = EBADF; - break; - } - /* The following is almost guaranteed not to fail. */ result = 0; @@ -389,7 +373,7 @@ __fd_hook_entry( if(current_position < 0) { fam->fam_Error = EBADF; - break; + goto out; } } @@ -438,24 +422,24 @@ __fd_hook_entry( if(NOT fib_is_valid && CANNOT __safe_examine_file_handle(fd->fd_DefaultFile,fib)) { fam->fam_Error = __translate_io_error_to_errno(IoErr()); - break; + goto out; } if(new_position <= fib->fib_Size) { fam->fam_Error = __translate_io_error_to_errno(IoErr()); - break; + goto out; } if(__grow_file_size(fd,new_position - fib->fib_Size) < 0) { fam->fam_Error = __translate_io_error_to_errno(IoErr()); - break; + goto out; } } #else { - break; + goto out; } #endif /* UNIX_PATH_SEMANTICS */ } @@ -488,7 +472,7 @@ __fd_hook_entry( if(CANNOT SetMode(fd->fd_DefaultFile,mode)) { fam->fam_Error = __translate_io_error_to_errno(IoErr()); - break; + goto out; } result = 0; @@ -508,30 +492,19 @@ __fd_hook_entry( SHOWMSG("file_action_examine"); - if(fd->fd_DefaultFile != ZERO) + if(CANNOT __safe_examine_file_handle(fd->fd_DefaultFile,fam->fam_FileInfo)) { - struct FileHandle * fh; + SHOWMSG("couldn't examine the file"); - if(CANNOT __safe_examine_file_handle(fd->fd_DefaultFile,fam->fam_FileInfo)) - { - SHOWMSG("couldn't examine the file"); - - fam->fam_Error = __translate_io_error_to_errno(IoErr()); - break; - } - - fh = BADDR(fd->fd_DefaultFile); - - fam->fam_FileSystem = fh->fh_Type; - - result = 0; + fam->fam_Error = __translate_io_error_to_errno(IoErr()); + goto out; } - else - { - SHOWMSG("file is already closed"); - fam->fam_Error = EBADF; - } + fh = BADDR(fd->fd_DefaultFile); + + fam->fam_FileSystem = fh->fh_Type; + + result = 0; break; @@ -543,6 +516,8 @@ __fd_hook_entry( break; } + out: + __fd_unlock(fd); if(buffer != NULL) diff --git a/library/stdio_file_init.c b/library/stdio_file_init.c new file mode 100644 index 0000000..7335806 --- /dev/null +++ b/library/stdio_file_init.c @@ -0,0 +1,363 @@ +/* + * $Id: stdio_file_init.c,v 1.1 2005-03-07 11:16:43 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 _STDLIB_MEM_DEBUG_H +#include "stdlib_mem_debug.h" +#endif /* _STDLIB_MEM_DEBUG_H */ + +/****************************************************************************/ + +#ifndef _STDIO_HEADERS_H +#include "stdio_headers.h" +#endif /* _STDIO_HEADERS_H */ + +#ifndef _UNISTD_HEADERS_H +#include "unistd_headers.h" +#endif /* _UNISTD_HEADERS_H */ + +/****************************************************************************/ + +static struct MsgPort * old_console_task; +static BOOL restore_console_task; + +/****************************************************************************/ + +static BOOL restore_streams; + +/****************************************************************************/ + +static BPTR old_output; +static BPTR old_input; + +/****************************************************************************/ + +static BPTR output; +static BPTR input; + +/****************************************************************************/ + +CLIB_DESTRUCTOR(workbench_exit) +{ + ENTER(); + + PROFILE_OFF(); + + /* Now clean up after the streams set up for Workbench startup... */ + if(restore_console_task) + { + SetConsoleTask((struct MsgPort *)old_console_task); + old_console_task = NULL; + + restore_console_task = FALSE; + } + + if(restore_streams) + { + SelectInput(old_input); + old_input = ZERO; + + SelectOutput(old_output); + old_output = ZERO; + + restore_streams = FALSE; + } + + if(input != ZERO) + { + Close(input); + input = ZERO; + } + + if(output != ZERO) + { + Close(output); + output = ZERO; + } + + PROFILE_ON(); + + LEAVE(); +} + +/****************************************************************************/ + +STATIC int +wb_file_init(void) +{ + int result = -1; + + PROFILE_OFF(); + + __original_current_directory = CurrentDir(__WBenchMsg->sm_ArgList[0].wa_Lock); + __current_directory_changed = TRUE; + + if (__stdio_window_specification != NULL) + { + input = Open(__stdio_window_specification,MODE_NEWFILE); + } + else if (__WBenchMsg->sm_ToolWindow != NULL) + { + input = Open(__WBenchMsg->sm_ToolWindow,MODE_NEWFILE); + } + else + { + static const char console_prefix[] = "CON:20/20/600/150/"; + static const char console_suffix[] = " Output/AUTO/CLOSE/WAIT"; + STRPTR window_specifier; + STRPTR tool_name; + size_t len; + + tool_name = FilePart(__WBenchMsg->sm_ArgList[0].wa_Name); + + len = strlen(console_prefix) + strlen(tool_name) + strlen(console_suffix); + + window_specifier = malloc(len+1); + if(window_specifier == NULL) + goto out; + + strcpy(window_specifier,console_prefix); + strcat(window_specifier,tool_name); + strcat(window_specifier,console_suffix); + + input = Open(window_specifier,MODE_NEWFILE); + + free(window_specifier); + } + + if(input == ZERO) + input = Open("NIL:",MODE_NEWFILE); + + if(input != ZERO) + { + struct FileHandle * fh = BADDR(input); + + old_console_task = SetConsoleTask(fh->fh_Type); + + output = Open("CONSOLE:",MODE_NEWFILE); + if(output != ZERO) + restore_console_task = TRUE; + else + SetConsoleTask((struct MsgPort *)old_console_task); + } + + if(output == ZERO) + output = Open("NIL:",MODE_NEWFILE); + + if(input == ZERO || output == ZERO) + goto out; + + old_input = SelectInput(input); + old_output = SelectOutput(output); + + restore_streams = TRUE; + + result = 0; + + out: + + PROFILE_ON(); + + return(result); +} + +/****************************************************************************/ + +int +__stdio_file_init(void) +{ + struct SignalSemaphore * stdio_lock; + struct SignalSemaphore * fd_lock; + BPTR default_file; + ULONG fd_flags,iob_flags; + int result = ERROR; + char * buffer; + char * aligned_buffer; + int i; + + ENTER(); + + /* If we were invoked from Workbench, set up the standard I/O streams. */ + if(__WBenchMsg != NULL) + { + if(wb_file_init() < 0) + goto out; + } + + /* Now initialize the standard I/O streams (input, output, error). */ + for(i = STDIN_FILENO ; i <= STDERR_FILENO ; i++) + { + PROFILE_OFF(); + + switch(i) + { + case STDIN_FILENO: + + iob_flags = IOBF_IN_USE | IOBF_READ | IOBF_NO_NUL | IOBF_BUFFER_MODE_LINE; + fd_flags = FDF_IN_USE | FDF_READ | FDF_NO_CLOSE; + default_file = Input(); + break; + + case STDOUT_FILENO: + + iob_flags = IOBF_IN_USE | IOBF_WRITE | IOBF_NO_NUL | IOBF_BUFFER_MODE_LINE; + fd_flags = FDF_IN_USE | FDF_WRITE | FDF_NO_CLOSE; + default_file = Output(); + break; + + case STDERR_FILENO: + default: + + iob_flags = IOBF_IN_USE | IOBF_WRITE | IOBF_NO_NUL | IOBF_BUFFER_MODE_NONE; + fd_flags = FDF_IN_USE | FDF_WRITE; + default_file = ZERO; /* NOTE: this is really initialized later; see below... */ + break; + } + + PROFILE_ON(); + + /* Allocate a little more memory than necessary. */ + buffer = malloc(BUFSIZ + (CACHE_LINE_SIZE-1)); + if(buffer == NULL) + goto out; + + #if defined(__THREAD_SAFE) + { + /* Allocate memory for an arbitration mechanism, then + initialize it. */ + stdio_lock = __create_semaphore(); + fd_lock = __create_semaphore(); + + if(stdio_lock == NULL || fd_lock == NULL) + { + __delete_semaphore(stdio_lock); + __delete_semaphore(fd_lock); + + goto out; + } + } + #else + { + stdio_lock = NULL; + fd_lock = NULL; + } + #endif /* __THREAD_SAFE */ + + /* Check if this stream is attached to a console window. */ + if(default_file != ZERO) + { + PROFILE_OFF(); + + if(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)); + + __initialize_fd(__fd[i],__fd_hook_entry,default_file,fd_flags,fd_lock); + + __initialize_iob(__iob[i],__iob_hook_entry, + buffer, + aligned_buffer,BUFSIZ, + i, + i, + iob_flags, + stdio_lock); + } + + /* If the program was launched from Workbench, we continue by + duplicating the default output stream for use as the + standard error stream. */ + if(__WBenchMsg != NULL) + { + PROFILE_OFF(); + __fd[STDERR_FILENO]->fd_DefaultFile = Output(); + PROFILE_ON(); + + SET_FLAG(__fd[STDERR_FILENO]->fd_Flags,FDF_NO_CLOSE); + } + else + { + BPTR ces; + + PROFILE_OFF(); + + /* Figure out what the default error output stream is. */ + #if defined(__amigaos4__) + { + ces = ErrorOutput(); + } + #else + { + struct Process * this_process = (struct Process *)FindTask(NULL); + + ces = this_process->pr_CES; + } + #endif /* __amigaos4__ */ + + PROFILE_ON(); + + /* Is the standard error stream configured? If so, use it. + Otherwise, try to duplicate the standard output stream. */ + if(ces != ZERO) + { + __fd[STDERR_FILENO]->fd_DefaultFile = ces; + + SET_FLAG(__fd[STDERR_FILENO]->fd_Flags,FDF_NO_CLOSE); + } + else + { + __fd[STDERR_FILENO]->fd_DefaultFile = Open("CONSOLE:",MODE_NEWFILE); + } + } + + PROFILE_OFF(); + + /* Figure out if the standard error stream is bound to a console. */ + if(__fd[STDERR_FILENO]->fd_DefaultFile != ZERO) + { + if(IsInteractive(__fd[STDERR_FILENO]->fd_DefaultFile)) + SET_FLAG(__fd[STDERR_FILENO]->fd_Flags,FDF_IS_INTERACTIVE); + } + + PROFILE_ON(); + + result = OK; + + out: + + RETURN(result); + return(result); +} diff --git a/library/stdio_init_exit.c b/library/stdio_init_exit.c index ce6da23..71ee2de 100644 --- a/library/stdio_init_exit.c +++ b/library/stdio_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_init_exit.c,v 1.23 2005-03-04 09:07:09 obarthel Exp $ + * $Id: stdio_init_exit.c,v 1.24 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -47,16 +47,6 @@ /****************************************************************************/ -#include "stdlib_protos.h" - -/****************************************************************************/ - -#ifndef ID_RAWCON -#define ID_RAWCON 0x52415700L /* "RAW\0" */ -#endif /* ID_RAWCON */ - -/****************************************************************************/ - void __close_all_files(void) { @@ -115,16 +105,9 @@ CLIB_DESTRUCTOR(__stdio_exit) int __stdio_init(void) { - const int num_standard_files = (STDERR_FILENO-STDIN_FILENO+1); + const int num_standard_files = (STDERR_FILENO - STDIN_FILENO + 1); - struct SignalSemaphore * stdio_lock; - struct SignalSemaphore * fd_lock; - BPTR default_file; - ULONG fd_flags,iob_flags; int result = ERROR; - char * buffer; - char * aligned_buffer; - int i; ENTER(); @@ -137,143 +120,6 @@ __stdio_init(void) if(__grow_fd_table(num_standard_files) < 0) goto out; - /* Now initialize the standard I/O streams (input, output, error). */ - for(i = STDIN_FILENO ; i <= STDERR_FILENO ; i++) - { - PROFILE_OFF(); - - switch(i) - { - case STDIN_FILENO: - - iob_flags = IOBF_IN_USE | IOBF_READ | IOBF_NO_NUL | IOBF_BUFFER_MODE_LINE; - fd_flags = FDF_IN_USE | FDF_READ | FDF_NO_CLOSE; - default_file = Input(); - break; - - case STDOUT_FILENO: - - iob_flags = IOBF_IN_USE | IOBF_WRITE | IOBF_NO_NUL | IOBF_BUFFER_MODE_LINE; - fd_flags = FDF_IN_USE | FDF_WRITE | FDF_NO_CLOSE; - default_file = Output(); - break; - - case STDERR_FILENO: - default: - - iob_flags = IOBF_IN_USE | IOBF_WRITE | IOBF_NO_NUL | IOBF_BUFFER_MODE_NONE; - fd_flags = FDF_IN_USE | FDF_WRITE; - default_file = ZERO; /* NOTE: this is really initialized later; see below... */ - break; - } - - PROFILE_ON(); - - /* Allocate a little more memory than necessary. */ - buffer = malloc(BUFSIZ + (CACHE_LINE_SIZE-1)); - if(buffer == NULL) - goto out; - - #if defined(__THREAD_SAFE) - { - /* Allocate memory for an arbitration mechanism, then - initialize it. */ - stdio_lock = __create_semaphore(); - fd_lock = __create_semaphore(); - - if(stdio_lock == NULL || fd_lock == NULL) - { - __delete_semaphore(stdio_lock); - __delete_semaphore(fd_lock); - - goto out; - } - } - #else - { - stdio_lock = NULL; - fd_lock = NULL; - } - #endif /* __THREAD_SAFE */ - - /* Check if this stream is attached to a console window. */ - if(default_file != ZERO) - { - PROFILE_OFF(); - - if(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)); - - __initialize_fd(__fd[i],__fd_hook_entry,default_file,fd_flags,fd_lock); - - __initialize_iob(__iob[i],__iob_hook_entry, - buffer, - aligned_buffer,BUFSIZ, - i, - i, - iob_flags, - stdio_lock); - } - - /* If the program was launched from Workbench, we continue by - duplicating the default output stream for use as the - standard error stream. */ - if(__WBenchMsg != NULL) - { - PROFILE_OFF(); - __fd[STDERR_FILENO]->fd_DefaultFile = Output(); - PROFILE_ON(); - - SET_FLAG(__fd[STDERR_FILENO]->fd_Flags,FDF_NO_CLOSE); - } - else - { - BPTR ces; - - /* Figure out what the default error output stream is. */ - #if defined(__amigaos4__) - { - ces = ErrorOutput(); - } - #else - { - struct Process * this_process = (struct Process *)FindTask(NULL); - - ces = this_process->pr_CES; - } - #endif /* __amigaos4__ */ - - /* Is the standard error stream configured? If so, use it. - Otherwise, try to duplicate the standard output stream. */ - if(ces != ZERO) - { - __fd[STDERR_FILENO]->fd_DefaultFile = ces; - - SET_FLAG(__fd[STDERR_FILENO]->fd_Flags,FDF_NO_CLOSE); - } - else - { - __fd[STDERR_FILENO]->fd_DefaultFile = Open("CONSOLE:",MODE_NEWFILE); - } - } - - PROFILE_OFF(); - - /* Figure out if the standard error stream is bound to a console. */ - if(__fd[STDERR_FILENO]->fd_DefaultFile != ZERO) - { - if(IsInteractive(__fd[STDERR_FILENO]->fd_DefaultFile)) - SET_FLAG(__fd[STDERR_FILENO]->fd_Flags,FDF_IS_INTERACTIVE); - } - - PROFILE_ON(); - result = OK; out: diff --git a/library/stdio_protos.h b/library/stdio_protos.h index 6d1665b..313acb8 100644 --- a/library/stdio_protos.h +++ b/library/stdio_protos.h @@ -1,5 +1,5 @@ /* - * $Id: stdio_protos.h,v 1.12 2005-03-04 09:07:09 obarthel Exp $ + * $Id: stdio_protos.h,v 1.13 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -215,4 +215,9 @@ extern void __remove_fd_alias(struct fd * fd); /****************************************************************************/ +/* stdio_file_init.c */ +extern int __stdio_file_init(void); + +/****************************************************************************/ + #endif /* _STDIO_PROTOS_H */ diff --git a/library/stdlib_startup.c b/library/stdlib_arg.c similarity index 66% rename from library/stdlib_startup.c rename to library/stdlib_arg.c index 49f71a9..53ade88 100644 --- a/library/stdlib_startup.c +++ b/library/stdlib_arg.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_startup.c,v 1.8 2005-03-03 09:32:09 obarthel Exp $ + * $Id: stdlib_arg.c,v 1.1 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -41,12 +41,13 @@ /****************************************************************************/ +#ifndef _STDLIB_HEADERS_H #include "stdlib_headers.h" +#endif /* _STDLIB_HEADERS_H */ + +#ifndef _UNISTD_HEADERS_H #include "unistd_headers.h" - -/****************************************************************************/ - -#include +#endif /* _UNISTD_HEADERS_H */ /****************************************************************************/ @@ -62,25 +63,6 @@ /****************************************************************************/ -static struct MsgPort * old_console_task; -static BOOL restore_console_task; - -/****************************************************************************/ - -static BOOL restore_streams; - -/****************************************************************************/ - -static BPTR old_output; -static BPTR old_input; - -/****************************************************************************/ - -static BPTR output; -static BPTR input; - -/****************************************************************************/ - char ** __argv; int __argc; @@ -129,35 +111,19 @@ is_final_quote_character(const unsigned char * str) /****************************************************************************/ int -__startup_init(void) +__arg_init(void) { - int result = -1; + int result = ERROR; /* Shell startup? */ if(__WBenchMsg == NULL) { size_t number_of_arguments; - unsigned char * command_name; - size_t command_name_len; unsigned char * arg_str; size_t arg_len; unsigned char * command_line; unsigned char * str; - /* Make a copy of the current command name string. */ - command_name_len = (size_t)((UBYTE *)BADDR(Cli()->cli_CommandName))[0]; - - __free_program_name = TRUE; - - command_name = AllocVec((ULONG)(command_name_len + 1),MEMF_ANY); - if(command_name == NULL) - goto out; - - if(CANNOT GetProgramName(command_name,command_name_len + 1)) - goto out; - - __program_name = (char *)command_name; - /* Get the shell parameter string and find out how long it is, stripping a trailing line feed and blank spaces if necessary. */ @@ -242,7 +208,7 @@ __startup_init(void) goto out; /* The first parameter is the program name. */ - __argv[0] = command_name; + __argv[0] = __program_name; str = command_line; @@ -341,130 +307,20 @@ __startup_init(void) assert( str <= &command_line[arg_len] ); __argv[__argc] = NULL; + + /* If necessary, expand wildcard patterns found in the command + line string into file and directory names. */ + if(__wildcard_expand_init() < 0) + goto out; } else { - PROFILE_OFF(); - - __program_name = (char *)__WBenchMsg->sm_ArgList[0].wa_Name; - - __original_current_directory = CurrentDir(__WBenchMsg->sm_ArgList[0].wa_Lock); - __current_directory_changed = TRUE; - - if (__stdio_window_specification != NULL) - { - input = Open(__stdio_window_specification,MODE_NEWFILE); - } - else if (__WBenchMsg->sm_ToolWindow != NULL) - { - input = Open(__WBenchMsg->sm_ToolWindow,MODE_NEWFILE); - } - else - { - static const char console_prefix[] = "CON:20/20/600/150/"; - static const char console_suffix[] = " Output/AUTO/CLOSE/WAIT"; - STRPTR window_specifier; - STRPTR tool_name; - size_t len; - - tool_name = FilePart(__WBenchMsg->sm_ArgList[0].wa_Name); - - len = strlen(console_prefix) + strlen(tool_name) + strlen(console_suffix); - - window_specifier = malloc(len+1); - if(window_specifier == NULL) - goto out; - - strcpy(window_specifier,console_prefix); - strcat(window_specifier,tool_name); - strcat(window_specifier,console_suffix); - - input = Open(window_specifier,MODE_NEWFILE); - - free(window_specifier); - } - - if(input == ZERO) - input = Open("NIL:",MODE_NEWFILE); - - if(input != ZERO) - { - struct FileHandle * fh = BADDR(input); - - old_console_task = SetConsoleTask(fh->fh_Type); - - output = Open("CONSOLE:",MODE_NEWFILE); - if(output != ZERO) - restore_console_task = TRUE; - else - SetConsoleTask((struct MsgPort *)old_console_task); - } - - if(output == ZERO) - output = Open("NIL:",MODE_NEWFILE); - - if(input == ZERO || output == ZERO) - goto out; - - old_input = SelectInput(input); - old_output = SelectOutput(output); - - restore_streams = TRUE; - __argv = (char **)__WBenchMsg; - - PROFILE_ON(); } - result = 0; + result = OK; out: return(result); } - -/****************************************************************************/ - -CLIB_DESTRUCTOR(__startup_exit) -{ - ENTER(); - - PROFILE_OFF(); - - /* Now clean up after the streams set up for the Workbench - startup... */ - if(restore_console_task) - { - SetConsoleTask((struct MsgPort *)old_console_task); - old_console_task = NULL; - - restore_console_task = FALSE; - } - - if(restore_streams) - { - SelectInput(old_input); - old_input = ZERO; - - SelectOutput(old_output); - old_output = ZERO; - - restore_streams = FALSE; - } - - if(input != ZERO) - { - Close(input); - input = ZERO; - } - - if(output != ZERO) - { - Close(output); - output = ZERO; - } - - PROFILE_ON(); - - LEAVE(); -} diff --git a/library/stdlib_data.c b/library/stdlib_data.c index b615af5..00f4877 100644 --- a/library/stdlib_data.c +++ b/library/stdlib_data.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_data.c,v 1.5 2005-01-02 09:07:08 obarthel Exp $ + * $Id: stdlib_data.c,v 1.6 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -47,11 +47,6 @@ struct WBStartup * __WBenchMsg; /****************************************************************************/ -char * __program_name; -BOOL __free_program_name; - -/****************************************************************************/ - BOOL __stack_overflow; ULONG __stk_maxsize; ULONG __stk_extensions; diff --git a/library/stdlib_headers.h b/library/stdlib_headers.h index 8f2cbbc..d30ea47 100644 --- a/library/stdlib_headers.h +++ b/library/stdlib_headers.h @@ -1,5 +1,5 @@ /* - * $Id: stdlib_headers.h,v 1.12 2005-03-03 09:32:08 obarthel Exp $ + * $Id: stdlib_headers.h,v 1.13 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -240,10 +240,6 @@ extern BOOL NOCOMMON __is_resident; /****************************************************************************/ -extern BOOL NOCOMMON __free_program_name; - -/****************************************************************************/ - extern UBYTE NOCOMMON __shell_escape_character; /****************************************************************************/ diff --git a/library/stdlib_init_exit.c b/library/stdlib_init_exit.c index bed7532..67c5d3e 100644 --- a/library/stdlib_init_exit.c +++ b/library/stdlib_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_init_exit.c,v 1.5 2005-02-27 21:58:21 obarthel Exp $ + * $Id: stdlib_init_exit.c,v 1.6 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -43,6 +43,14 @@ /****************************************************************************/ +static BOOL free_program_name; + +/****************************************************************************/ + +char * __program_name; + +/****************************************************************************/ + void __stdlib_exit(void) { @@ -50,7 +58,7 @@ __stdlib_exit(void) __memory_exit(); - if(__free_program_name && __program_name != NULL) + if(free_program_name && __program_name != NULL) { FreeVec(__program_name); __program_name = NULL; @@ -64,11 +72,35 @@ __stdlib_exit(void) int __stdlib_init(void) { - int result; + int result = ERROR; ENTER(); - result = __memory_init(); + if(__WBenchMsg == NULL) + { + const size_t program_name_size = 256; + + /* Make a copy of the current command name string. */ + __program_name = AllocVec((ULONG)program_name_size,MEMF_ANY); + if(__program_name == NULL) + goto out; + + free_program_name = TRUE; + + if(CANNOT GetProgramName(__program_name,program_name_size)) + goto out; + } + else + { + __program_name = (char *)__WBenchMsg->sm_ArgList[0].wa_Name; + } + + if(__memory_init() < 0) + goto out; + + result = OK; + + out: RETURN(result); return(result); diff --git a/library/stdlib_machine_test.c b/library/stdlib_machine_test.c index a094d90..9dd0bba 100644 --- a/library/stdlib_machine_test.c +++ b/library/stdlib_machine_test.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_machine_test.c,v 1.2 2005-01-02 09:07:18 obarthel Exp $ + * $Id: stdlib_machine_test.c,v 1.3 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -48,38 +48,14 @@ __machine_test(void) #if defined(M68020) { - const struct ExecBase * UNUSED ex = (const struct ExecBase *)SysBase; - - #if defined(M68881_FLOATING_POINT_SUPPORT) - { - if(FLAG_IS_CLEAR(ex->AttnFlags,AFF_68881) || FLAG_IS_CLEAR(ex->AttnFlags,AFF_68020)) - { - __show_error("This program requires a floating point processor and an MC68020 CPU, or better."); - - goto out; - } - } - #endif /* M68881_FLOATING_POINT_SUPPORT */ - - if(FLAG_IS_CLEAR(ex->AttnFlags,AFF_68020)) + if(FLAG_IS_CLEAR(((struct ExecBase *)SysBase)->AttnFlags,AFF_68020)) { __show_error("This program requires an MC68020 CPU, or better."); goto out; } } - #elif defined(M68881_FLOATING_POINT_SUPPORT) - { - const struct ExecBase * UNUSED ex = (const struct ExecBase *)SysBase; - - if(FLAG_IS_CLEAR(ex->AttnFlags,AFF_68881)) - { - __show_error("This program requires a floating point processor."); - - goto out; - } - } - #endif /* M68881_FLOATING_POINT_SUPPORT */ + #endif /* M68020 */ result = OK; diff --git a/library/stdlib_main.c b/library/stdlib_main.c index 5f9c9d5..622d6e3 100644 --- a/library/stdlib_main.c +++ b/library/stdlib_main.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_main.c,v 1.11 2005-02-25 10:14:21 obarthel Exp $ + * $Id: stdlib_main.c,v 1.12 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -117,12 +117,12 @@ call_main(void) { __stdlib_init, __stk_init, - __startup_init, __stdio_init, + __stdio_file_init, __machine_test, __math_init, __socket_init, - __wildcard_expand_init, + __arg_init, NULL }; diff --git a/library/stdlib_protos.h b/library/stdlib_protos.h index 4c872b2..8fe9a12 100644 --- a/library/stdlib_protos.h +++ b/library/stdlib_protos.h @@ -1,5 +1,5 @@ /* - * $Id: stdlib_protos.h,v 1.11 2005-03-03 14:20:55 obarthel Exp $ + * $Id: stdlib_protos.h,v 1.12 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -132,8 +132,8 @@ void _fini(void); /****************************************************************************/ -/* stdlib_startup.c */ -extern int __startup_init(void); +/* stdlib_arg.c */ +extern int __arg_init(void); /****************************************************************************/ diff --git a/library/unistd_fchown.c b/library/unistd_fchown.c index 868984c..f5d3572 100644 --- a/library/unistd_fchown.c +++ b/library/unistd_fchown.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_fchown.c,v 1.7 2005-02-28 13:22:53 obarthel Exp $ + * $Id: unistd_fchown.c,v 1.8 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -80,6 +80,12 @@ fchown(int file_descriptor, uid_t owner, gid_t group) goto out; } + if(fd->fd_DefaultFile == ZERO) + { + __set_errno(EBADF); + goto out; + } + if(owner > 65535 || group > 65535) { SHOWMSG("owner or group not OK"); diff --git a/library/unistd_fdatasync.c b/library/unistd_fdatasync.c index f5a5f4b..b0a99eb 100644 --- a/library/unistd_fdatasync.c +++ b/library/unistd_fdatasync.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_fdatasync.c,v 1.3 2005-02-21 10:22:02 obarthel Exp $ + * $Id: unistd_fdatasync.c,v 1.4 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -77,6 +77,12 @@ fdatasync(int file_descriptor) goto out; } + if(fd->fd_DefaultFile == ZERO) + { + __set_errno(EBADF); + goto out; + } + __sync_fd(fd,0); /* flush just the data */ result = 0; diff --git a/library/unistd_fsync.c b/library/unistd_fsync.c index a84caf0..57d0c40 100644 --- a/library/unistd_fsync.c +++ b/library/unistd_fsync.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_fsync.c,v 1.3 2005-02-21 10:22:02 obarthel Exp $ + * $Id: unistd_fsync.c,v 1.4 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -76,6 +76,12 @@ fsync(int file_descriptor) goto out; } + if(fd->fd_DefaultFile == ZERO) + { + __set_errno(EBADF); + goto out; + } + __sync_fd(fd,1); /* flush everything */ result = 0; diff --git a/library/unistd_ftruncate.c b/library/unistd_ftruncate.c index 1a72f6b..53423f6 100644 --- a/library/unistd_ftruncate.c +++ b/library/unistd_ftruncate.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_ftruncate.c,v 1.6 2005-02-28 13:22:53 obarthel Exp $ + * $Id: unistd_ftruncate.c,v 1.7 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -77,6 +77,12 @@ ftruncate(int file_descriptor, off_t length) goto out; } + if(fd->fd_DefaultFile == ZERO) + { + __set_errno(EBADF); + goto out; + } + if(length < 0) { SHOWMSG("invalid length"); diff --git a/library/unistd_sync_fd.c b/library/unistd_sync_fd.c index 333f155..5233f63 100644 --- a/library/unistd_sync_fd.c +++ b/library/unistd_sync_fd.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_sync_fd.c,v 1.2 2005-02-28 13:22:53 obarthel Exp $ + * $Id: unistd_sync_fd.c,v 1.3 2005-03-07 11:16:43 obarthel Exp $ * * :ts=4 * @@ -54,20 +54,17 @@ __sync_fd(struct fd * fd,int mode) __fd_lock(fd); - if(fd->fd_DefaultFile != ZERO) + /* The mode tells us what to flush. 0 means "flush just the data", and + everything else means "flush everything. */ + Flush(fd->fd_DefaultFile); + + if(mode != 0) { - /* The mode tells us what to flush. 0 means "flush just the data", and - everything else means "flush everything. */ - Flush(fd->fd_DefaultFile); + struct FileHandle * fh = BADDR(fd->fd_DefaultFile); - if(mode != 0) - { - struct FileHandle * fh = BADDR(fd->fd_DefaultFile); - - /* Verify that this file is not bound to "NIL:". */ - if(fh->fh_Type != NULL) - DoPkt(fh->fh_Type,ACTION_FLUSH, 0,0,0,0,0); - } + /* Verify that this file is not bound to "NIL:". */ + if(fh->fh_Type != NULL) + DoPkt(fh->fh_Type,ACTION_FLUSH, 0,0,0,0,0); } __fd_unlock(fd);