1
0
mirror of https://github.com/adtools/clib2.git synced 2025-12-08 14:59:05 +00:00

- 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
This commit is contained in:
Olaf Barthel
2005-03-07 11:16:43 +00:00
parent d370bd123b
commit a9c8cdc554
23 changed files with 558 additions and 445 deletions

View File

@ -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 # :ts=8
# #
@ -225,6 +225,7 @@ C_LIB = \
stdio_initializefd.o \ stdio_initializefd.o \
stdio_initializeiob.o \ stdio_initializeiob.o \
stdio_init_exit.o \ stdio_init_exit.o \
stdio_file_init.o \
stdio_iobhookentry.o \ stdio_iobhookentry.o \
stdio_lock.o \ stdio_lock.o \
stdio_locksemaphorename.o \ stdio_locksemaphorename.o \
@ -332,7 +333,7 @@ C_LIB = \
stdlib_stacksafezone.o \ stdlib_stacksafezone.o \
stdlib_stacksize.o \ stdlib_stacksize.o \
stdlib_stack_usage.o \ stdlib_stack_usage.o \
stdlib_startup.o \ stdlib_arg.o \
stdlib_stdio_window_spec.o \ stdlib_stdio_window_spec.o \
stdlib_strtol.o \ stdlib_strtol.o \
stdlib_strtoll.o \ stdlib_strtoll.o \
@ -458,6 +459,7 @@ UNIX_LIB = \
stdio_fflush.o \ stdio_fflush.o \
stdio_fopen.o \ stdio_fopen.o \
stdio_init_exit.o \ stdio_init_exit.o \
stdio_file_init.o \
stdio_locksemaphorename.o \ stdio_locksemaphorename.o \
stdio_openiob.o \ stdio_openiob.o \
stdio_popen.o \ stdio_popen.o \

View File

@ -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 # :ts=8
# #
@ -229,6 +229,7 @@ C_LIB = \
stdio_initializefd.o \ stdio_initializefd.o \
stdio_initializeiob.o \ stdio_initializeiob.o \
stdio_init_exit.o \ stdio_init_exit.o \
stdio_file_init.o \
stdio_iobhookentry.o \ stdio_iobhookentry.o \
stdio_lock.o \ stdio_lock.o \
stdio_locksemaphorename.o \ stdio_locksemaphorename.o \
@ -336,7 +337,7 @@ C_LIB = \
stdlib_stacksafezone.o \ stdlib_stacksafezone.o \
stdlib_stacksize.o \ stdlib_stacksize.o \
stdlib_stack_usage.o \ stdlib_stack_usage.o \
stdlib_startup.o \ stdlib_arg.o \
stdlib_stdio_window_spec.o \ stdlib_stdio_window_spec.o \
stdlib_strtol.o \ stdlib_strtol.o \
stdlib_strtoll.o \ stdlib_strtoll.o \
@ -462,6 +463,7 @@ UNIX_LIB = \
stdio_fdhookentry.o \ stdio_fdhookentry.o \
stdio_fflush.o \ stdio_fflush.o \
stdio_fopen.o \ stdio_fopen.o \
stdio_file_init.o \
stdio_init_exit.o \ stdio_init_exit.o \
stdio_locksemaphorename.o \ stdio_locksemaphorename.o \
stdio_openiob.o \ stdio_openiob.o \

View File

@ -6,6 +6,22 @@
code can spend less time in Forbid() state and, heaven forbid, code can spend less time in Forbid() state and, heaven forbid,
refrain from allocating memory while in that state. 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) c.lib 1.189 (5.3.2005)

View File

@ -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 * :ts=4
* *
@ -41,6 +41,10 @@
/****************************************************************************/ /****************************************************************************/
#include <exec/execbase.h>
/****************************************************************************/
#include <proto/exec.h> #include <proto/exec.h>
/****************************************************************************/ /****************************************************************************/
@ -89,6 +93,17 @@ __math_init(void)
{ {
int result = ERROR; 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) #if defined(IEEE_FLOATING_POINT_SUPPORT)
{ {
char * failed_library = NULL; char * failed_library = NULL;

View File

@ -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 * :ts=4
* *
@ -97,6 +97,12 @@ fstatfs(int file_descriptor, struct statfs *buf)
goto out; goto out;
} }
if(fd->fd_DefaultFile == ZERO)
{
__set_errno(EBADF);
goto out;
}
PROFILE_OFF(); PROFILE_OFF();
parent_dir = __safe_parent_of_file_handle(fd->fd_DefaultFile); parent_dir = __safe_parent_of_file_handle(fd->fd_DefaultFile);
PROFILE_ON(); PROFILE_ON();

View File

@ -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 # :ts=8
# #
@ -329,6 +329,7 @@ STDIO_OBJ = \
stdio_grow_file.o \ stdio_grow_file.o \
stdio_initializefd.o \ stdio_initializefd.o \
stdio_initializeiob.o \ stdio_initializeiob.o \
stdio_file_init.o \
stdio_init_exit.o \ stdio_init_exit.o \
stdio_iobhookentry.o \ stdio_iobhookentry.o \
stdio_lock.o \ stdio_lock.o \
@ -439,7 +440,7 @@ STDLIB_OBJ = \
stdlib_stacksafezone.o \ stdlib_stacksafezone.o \
stdlib_stacksize.o \ stdlib_stacksize.o \
stdlib_stack_usage.o \ stdlib_stack_usage.o \
stdlib_startup.o \ stdlib_arg.o \
stdlib_strtod.o \ stdlib_strtod.o \
stdlib_strtol.o \ stdlib_strtol.o \
stdlib_strtoul.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_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 stdlib_system.o : stdlib_system.c stdlib_mem_debug.h

View File

@ -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 * :ts=4
* *
@ -80,6 +80,12 @@ fchmod(int file_descriptor, mode_t mode)
goto out; goto out;
} }
if(fd->fd_DefaultFile == ZERO)
{
__set_errno(EBADF);
goto out;
}
protection = 0; protection = 0;
if(FLAG_IS_SET(mode,S_IRUSR)) if(FLAG_IS_SET(mode,S_IRUSR))

View File

@ -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 * :ts=4
* *
@ -59,6 +59,7 @@ __fd_hook_entry(
{ {
D_S(struct FileInfoBlock,fib); D_S(struct FileInfoBlock,fib);
BOOL fib_is_valid = FALSE; BOOL fib_is_valid = FALSE;
struct FileHandle * fh;
off_t current_position; off_t current_position;
off_t new_position; off_t new_position;
int new_mode; int new_mode;
@ -72,20 +73,20 @@ __fd_hook_entry(
__fd_lock(fd); __fd_lock(fd);
if(fd->fd_DefaultFile == ZERO)
{
SHOWMSG("file is closed");
fam->fam_Error = EBADF;
goto out;
}
switch(fam->fam_Action) switch(fam->fam_Action)
{ {
case file_action_read: case file_action_read:
SHOWMSG("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_Data != NULL );
assert( fam->fam_Size > 0 ); assert( fam->fam_Size > 0 );
@ -102,7 +103,7 @@ __fd_hook_entry(
D(("read failed ioerr=%ld",IoErr())); D(("read failed ioerr=%ld",IoErr()));
fam->fam_Error = __translate_io_error_to_errno(IoErr()); fam->fam_Error = __translate_io_error_to_errno(IoErr());
break; goto out;
} }
if(FLAG_IS_SET(fd->fd_Flags,FDF_CACHE_POSITION)) if(FLAG_IS_SET(fd->fd_Flags,FDF_CACHE_POSITION))
@ -114,14 +115,6 @@ __fd_hook_entry(
SHOWMSG("file_action_write"); 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_Data != NULL );
assert( fam->fam_Size > 0 ); assert( fam->fam_Size > 0 );
@ -153,7 +146,7 @@ __fd_hook_entry(
D(("write failed ioerr=%ld",IoErr())); D(("write failed ioerr=%ld",IoErr()));
fam->fam_Error = __translate_io_error_to_errno(IoErr()); fam->fam_Error = __translate_io_error_to_errno(IoErr());
break; goto out;
} }
if(FLAG_IS_SET(fd->fd_Flags,FDF_CACHE_POSITION)) if(FLAG_IS_SET(fd->fd_Flags,FDF_CACHE_POSITION))
@ -172,15 +165,6 @@ __fd_hook_entry(
} }
else 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. */ /* The following is almost guaranteed not to fail. */
result = 0; result = 0;
@ -389,7 +373,7 @@ __fd_hook_entry(
if(current_position < 0) if(current_position < 0)
{ {
fam->fam_Error = EBADF; 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)) if(NOT fib_is_valid && CANNOT __safe_examine_file_handle(fd->fd_DefaultFile,fib))
{ {
fam->fam_Error = __translate_io_error_to_errno(IoErr()); fam->fam_Error = __translate_io_error_to_errno(IoErr());
break; goto out;
} }
if(new_position <= fib->fib_Size) if(new_position <= fib->fib_Size)
{ {
fam->fam_Error = __translate_io_error_to_errno(IoErr()); fam->fam_Error = __translate_io_error_to_errno(IoErr());
break; goto out;
} }
if(__grow_file_size(fd,new_position - fib->fib_Size) < 0) if(__grow_file_size(fd,new_position - fib->fib_Size) < 0)
{ {
fam->fam_Error = __translate_io_error_to_errno(IoErr()); fam->fam_Error = __translate_io_error_to_errno(IoErr());
break; goto out;
} }
} }
#else #else
{ {
break; goto out;
} }
#endif /* UNIX_PATH_SEMANTICS */ #endif /* UNIX_PATH_SEMANTICS */
} }
@ -488,7 +472,7 @@ __fd_hook_entry(
if(CANNOT SetMode(fd->fd_DefaultFile,mode)) if(CANNOT SetMode(fd->fd_DefaultFile,mode))
{ {
fam->fam_Error = __translate_io_error_to_errno(IoErr()); fam->fam_Error = __translate_io_error_to_errno(IoErr());
break; goto out;
} }
result = 0; result = 0;
@ -508,30 +492,19 @@ __fd_hook_entry(
SHOWMSG("file_action_examine"); 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)) fam->fam_Error = __translate_io_error_to_errno(IoErr());
{ goto out;
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;
} }
else
{
SHOWMSG("file is already closed");
fam->fam_Error = EBADF; fh = BADDR(fd->fd_DefaultFile);
}
fam->fam_FileSystem = fh->fh_Type;
result = 0;
break; break;
@ -543,6 +516,8 @@ __fd_hook_entry(
break; break;
} }
out:
__fd_unlock(fd); __fd_unlock(fd);
if(buffer != NULL) if(buffer != NULL)

363
library/stdio_file_init.c Normal file
View File

@ -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 <olsen@sourcery.han.de>
* 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);
}

View File

@ -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 * :ts=4
* *
@ -47,16 +47,6 @@
/****************************************************************************/ /****************************************************************************/
#include "stdlib_protos.h"
/****************************************************************************/
#ifndef ID_RAWCON
#define ID_RAWCON 0x52415700L /* "RAW\0" */
#endif /* ID_RAWCON */
/****************************************************************************/
void void
__close_all_files(void) __close_all_files(void)
{ {
@ -115,16 +105,9 @@ CLIB_DESTRUCTOR(__stdio_exit)
int int
__stdio_init(void) __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; int result = ERROR;
char * buffer;
char * aligned_buffer;
int i;
ENTER(); ENTER();
@ -137,143 +120,6 @@ __stdio_init(void)
if(__grow_fd_table(num_standard_files) < 0) if(__grow_fd_table(num_standard_files) < 0)
goto out; 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; result = OK;
out: out:

View File

@ -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 * :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 */ #endif /* _STDIO_PROTOS_H */

View File

@ -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 * :ts=4
* *
@ -41,12 +41,13 @@
/****************************************************************************/ /****************************************************************************/
#ifndef _STDLIB_HEADERS_H
#include "stdlib_headers.h" #include "stdlib_headers.h"
#endif /* _STDLIB_HEADERS_H */
#ifndef _UNISTD_HEADERS_H
#include "unistd_headers.h" #include "unistd_headers.h"
#endif /* _UNISTD_HEADERS_H */
/****************************************************************************/
#include <exec/execbase.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; char ** __argv;
int __argc; int __argc;
@ -129,35 +111,19 @@ is_final_quote_character(const unsigned char * str)
/****************************************************************************/ /****************************************************************************/
int int
__startup_init(void) __arg_init(void)
{ {
int result = -1; int result = ERROR;
/* Shell startup? */ /* Shell startup? */
if(__WBenchMsg == NULL) if(__WBenchMsg == NULL)
{ {
size_t number_of_arguments; size_t number_of_arguments;
unsigned char * command_name;
size_t command_name_len;
unsigned char * arg_str; unsigned char * arg_str;
size_t arg_len; size_t arg_len;
unsigned char * command_line; unsigned char * command_line;
unsigned char * str; 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 /* Get the shell parameter string and find out
how long it is, stripping a trailing line how long it is, stripping a trailing line
feed and blank spaces if necessary. */ feed and blank spaces if necessary. */
@ -242,7 +208,7 @@ __startup_init(void)
goto out; goto out;
/* The first parameter is the program name. */ /* The first parameter is the program name. */
__argv[0] = command_name; __argv[0] = __program_name;
str = command_line; str = command_line;
@ -341,130 +307,20 @@ __startup_init(void)
assert( str <= &command_line[arg_len] ); assert( str <= &command_line[arg_len] );
__argv[__argc] = NULL; __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 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; __argv = (char **)__WBenchMsg;
PROFILE_ON();
} }
result = 0; result = OK;
out: out:
return(result); 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();
}

View File

@ -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 * :ts=4
* *
@ -47,11 +47,6 @@ struct WBStartup * __WBenchMsg;
/****************************************************************************/ /****************************************************************************/
char * __program_name;
BOOL __free_program_name;
/****************************************************************************/
BOOL __stack_overflow; BOOL __stack_overflow;
ULONG __stk_maxsize; ULONG __stk_maxsize;
ULONG __stk_extensions; ULONG __stk_extensions;

View File

@ -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 * :ts=4
* *
@ -240,10 +240,6 @@ extern BOOL NOCOMMON __is_resident;
/****************************************************************************/ /****************************************************************************/
extern BOOL NOCOMMON __free_program_name;
/****************************************************************************/
extern UBYTE NOCOMMON __shell_escape_character; extern UBYTE NOCOMMON __shell_escape_character;
/****************************************************************************/ /****************************************************************************/

View File

@ -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 * :ts=4
* *
@ -43,6 +43,14 @@
/****************************************************************************/ /****************************************************************************/
static BOOL free_program_name;
/****************************************************************************/
char * __program_name;
/****************************************************************************/
void void
__stdlib_exit(void) __stdlib_exit(void)
{ {
@ -50,7 +58,7 @@ __stdlib_exit(void)
__memory_exit(); __memory_exit();
if(__free_program_name && __program_name != NULL) if(free_program_name && __program_name != NULL)
{ {
FreeVec(__program_name); FreeVec(__program_name);
__program_name = NULL; __program_name = NULL;
@ -64,11 +72,35 @@ __stdlib_exit(void)
int int
__stdlib_init(void) __stdlib_init(void)
{ {
int result; int result = ERROR;
ENTER(); 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);
return(result); return(result);

View File

@ -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 * :ts=4
* *
@ -48,38 +48,14 @@ __machine_test(void)
#if defined(M68020) #if defined(M68020)
{ {
const struct ExecBase * UNUSED ex = (const struct ExecBase *)SysBase; if(FLAG_IS_CLEAR(((struct ExecBase *)SysBase)->AttnFlags,AFF_68020))
#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))
{ {
__show_error("This program requires an MC68020 CPU, or better."); __show_error("This program requires an MC68020 CPU, or better.");
goto out; goto out;
} }
} }
#elif defined(M68881_FLOATING_POINT_SUPPORT) #endif /* M68020 */
{
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 */
result = OK; result = OK;

View File

@ -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 * :ts=4
* *
@ -117,12 +117,12 @@ call_main(void)
{ {
__stdlib_init, __stdlib_init,
__stk_init, __stk_init,
__startup_init,
__stdio_init, __stdio_init,
__stdio_file_init,
__machine_test, __machine_test,
__math_init, __math_init,
__socket_init, __socket_init,
__wildcard_expand_init, __arg_init,
NULL NULL
}; };

View File

@ -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 * :ts=4
* *
@ -132,8 +132,8 @@ void _fini(void);
/****************************************************************************/ /****************************************************************************/
/* stdlib_startup.c */ /* stdlib_arg.c */
extern int __startup_init(void); extern int __arg_init(void);
/****************************************************************************/ /****************************************************************************/

View File

@ -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 * :ts=4
* *
@ -80,6 +80,12 @@ fchown(int file_descriptor, uid_t owner, gid_t group)
goto out; goto out;
} }
if(fd->fd_DefaultFile == ZERO)
{
__set_errno(EBADF);
goto out;
}
if(owner > 65535 || group > 65535) if(owner > 65535 || group > 65535)
{ {
SHOWMSG("owner or group not OK"); SHOWMSG("owner or group not OK");

View File

@ -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 * :ts=4
* *
@ -77,6 +77,12 @@ fdatasync(int file_descriptor)
goto out; goto out;
} }
if(fd->fd_DefaultFile == ZERO)
{
__set_errno(EBADF);
goto out;
}
__sync_fd(fd,0); /* flush just the data */ __sync_fd(fd,0); /* flush just the data */
result = 0; result = 0;

View File

@ -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 * :ts=4
* *
@ -76,6 +76,12 @@ fsync(int file_descriptor)
goto out; goto out;
} }
if(fd->fd_DefaultFile == ZERO)
{
__set_errno(EBADF);
goto out;
}
__sync_fd(fd,1); /* flush everything */ __sync_fd(fd,1); /* flush everything */
result = 0; result = 0;

View File

@ -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 * :ts=4
* *
@ -77,6 +77,12 @@ ftruncate(int file_descriptor, off_t length)
goto out; goto out;
} }
if(fd->fd_DefaultFile == ZERO)
{
__set_errno(EBADF);
goto out;
}
if(length < 0) if(length < 0)
{ {
SHOWMSG("invalid length"); SHOWMSG("invalid length");

View File

@ -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 * :ts=4
* *
@ -54,20 +54,17 @@ __sync_fd(struct fd * fd,int mode)
__fd_lock(fd); __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 struct FileHandle * fh = BADDR(fd->fd_DefaultFile);
everything else means "flush everything. */
Flush(fd->fd_DefaultFile);
if(mode != 0) /* Verify that this file is not bound to "NIL:". */
{ if(fh->fh_Type != NULL)
struct FileHandle * fh = BADDR(fd->fd_DefaultFile); 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); __fd_unlock(fd);