diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index b7f335e..5c95f04 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.44 2005-03-18 12:38:20 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.45 2005-03-19 11:06:56 obarthel Exp $ # # :ts=8 # @@ -202,6 +202,7 @@ C_LIB = \ stdio_findvacantiobentry.o \ stdio_flockfile.o \ stdio_flush.o \ + stdio_flush_all_files.o \ stdio_flushiobwritebuffer.o \ stdio_fopen.o \ stdio_fprintf.o \ @@ -523,6 +524,7 @@ MATH_LIB = \ math_tanh.o \ stdio_asprintf.o \ stdio_flush.o \ + stdio_flush_all_files.o \ stdio_fprintf.o \ stdio_fscanf.o \ stdio_printf.o \ diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index 581399c..3db6715 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.44 2005-03-18 12:38:21 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.45 2005-03-19 11:06:57 obarthel Exp $ # # :ts=8 # @@ -200,6 +200,7 @@ C_LIB = \ stdio_findvacantiobentry.o \ stdio_flockfile.o \ stdio_flush.o \ + stdio_flush_all_files.o \ stdio_flushiobwritebuffer.o \ stdio_fopen.o \ stdio_fprintf.o \ @@ -529,6 +530,7 @@ MATH_LIB = \ math_kernel_sin.o \ stdio_asprintf.o \ stdio_flush.o \ + stdio_flush_all_files.o \ stdio_fprintf.o \ stdio_fscanf.o \ stdio_printf.o \ diff --git a/library/changes b/library/changes index 4738b0e..a73ed5d 100644 --- a/library/changes +++ b/library/changes @@ -108,6 +108,11 @@ - Added the first real C99 function: _Exit(). +- assertion failures early on during program initialization + should no longer spell big trouble on account of the stdio + data structures possibly not being in a well-defined and + initialized state. + c.lib 1.189 (5.3.2005) diff --git a/library/smakefile b/library/smakefile index 922fb4e..99284aa 100644 --- a/library/smakefile +++ b/library/smakefile @@ -1,5 +1,5 @@ # -# $Id: smakefile,v 1.34 2005-03-18 12:38:22 obarthel Exp $ +# $Id: smakefile,v 1.35 2005-03-19 11:06:57 obarthel Exp $ # # :ts=8 # @@ -299,6 +299,7 @@ STDIO_OBJ = \ stdio_findvacantiobentry.o \ stdio_flockfile.o \ stdio_flush.o \ + stdio_flush_all_files.o \ stdio_flushiobwritebuffer.o \ stdio_fopen.o \ stdio_fprintf.o \ diff --git a/library/stdio_filliobreadbuffer.c b/library/stdio_filliobreadbuffer.c index 5b42c62..f37360e 100644 --- a/library/stdio_filliobreadbuffer.c +++ b/library/stdio_filliobreadbuffer.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_filliobreadbuffer.c,v 1.8 2005-02-27 21:58:21 obarthel Exp $ + * $Id: stdio_filliobreadbuffer.c,v 1.9 2005-03-19 11:06:57 obarthel Exp $ * * :ts=4 * @@ -56,30 +56,7 @@ __fill_iob_read_buffer(struct iob * file) /* Flush all line buffered streams before we proceed to fill this buffer. */ if((file->iob_Flags & IOBF_BUFFER_MODE) == IOBF_BUFFER_MODE_LINE) { - int failed_iob = -1; - int i; - - __stdio_lock(); - - for(i = 0 ; i < __num_iob ; i++) - { - if(__iob[i] != NULL && - FLAG_IS_SET(__iob[i]->iob_Flags,IOBF_IN_USE) && - FLAG_IS_SET(__iob[i]->iob_Flags,IOBF_WRITE) && - (__iob[i]->iob_Flags & IOBF_BUFFER_MODE) == IOBF_BUFFER_MODE_LINE && - __iob_write_buffer_is_valid(__iob[i])) - { - if(__flush_iob_write_buffer(__iob[i]) < 0) - { - failed_iob = i; - break; - } - } - } - - __stdio_unlock(); - - if(failed_iob >= 0) + if(__flush_all_files(IOBF_BUFFER_MODE_LINE) < 0) goto out; } diff --git a/library/stdio_flush_all_files.c b/library/stdio_flush_all_files.c new file mode 100644 index 0000000..35b0ca2 --- /dev/null +++ b/library/stdio_flush_all_files.c @@ -0,0 +1,71 @@ +/* + * $Id: stdio_flush_all_files.c,v 1.1 2005-03-19 11:06:57 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _STDIO_HEADERS_H +#include "stdio_headers.h" +#endif /* _STDIO_HEADERS_H */ + +/****************************************************************************/ + +int +__flush_all_files(int buffer_mode) +{ + int result; + int i; + + __stdio_lock(); + + for(i = 0 ; i < __num_iob ; i++) + { + if(__iob[i] != NULL && + FLAG_IS_SET(__iob[i]->iob_Flags,IOBF_IN_USE) && + FLAG_IS_SET(__iob[i]->iob_Flags,IOBF_WRITE) && + (buffer_mode < 0 || (__iob[i]->iob_Flags & IOBF_BUFFER_MODE) == (ULONG)buffer_mode) && + __iob_write_buffer_is_valid(__iob[i])) + { + if(__flush_iob_write_buffer(__iob[i]) < 0) + { + result = -1; + goto out; + } + } + } + + result = 0; + + out: + + __stdio_unlock(); + + return(result); +} diff --git a/library/stdio_protos.h b/library/stdio_protos.h index eafe40a..61d37b8 100644 --- a/library/stdio_protos.h +++ b/library/stdio_protos.h @@ -1,5 +1,5 @@ /* - * $Id: stdio_protos.h,v 1.14 2005-03-07 11:58:50 obarthel Exp $ + * $Id: stdio_protos.h,v 1.15 2005-03-19 11:06:57 obarthel Exp $ * * :ts=4 * @@ -220,4 +220,9 @@ extern int __stdio_file_init(void); /****************************************************************************/ +/* stdio_flush_all_files.c */ +extern int __flush_all_files(int buffer_mode); + +/****************************************************************************/ + #endif /* _STDIO_PROTOS_H */ diff --git a/library/stdlib_assertion_failure.c b/library/stdlib_assertion_failure.c index b41a40d..1c929aa 100644 --- a/library/stdlib_assertion_failure.c +++ b/library/stdlib_assertion_failure.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_assertion_failure.c,v 1.9 2005-03-19 10:15:56 obarthel Exp $ + * $Id: stdlib_assertion_failure.c,v 1.10 2005-03-19 11:06:57 obarthel Exp $ * * :ts=4 * @@ -118,17 +118,90 @@ __assertion_failure( } else { - if(__program_name != NULL) - fprintf(stderr,"[%s] ",__program_name); + if(__num_iob > STDERR_FILENO) + { + if(__program_name != NULL) + fprintf(stderr,"[%s] ",__program_name); - fprintf(stderr, - "%s:%d: failed assertion \"%s\".\n", - file_name, - line_number, - expression); + fprintf(stderr, + "%s:%d: failed assertion \"%s\".\n", + file_name, + line_number, + expression); + + abort(); + } + else + { + #if defined(__amigaos4__) + struct DOSIFace * IDOS = NULL; + #endif /* __amigaos4__ */ + + struct Library * DOSBase; + + DOSBase = OpenLibrary("dos.library",37); + + #if defined(__amigaos4__) + { + if(DOSBase != NULL) + { + IDOS = (struct DOSIFace *)GetInterface(DOSBase, "main", 1, 0); + if(IDOS == NULL) + { + CloseLibrary(DOSBase); + DOSBase = NULL; + } + } + } + #endif /* __amigaos4__ */ + + if(DOSBase != NULL) + { + BPTR output; + + /* Dump all currently unwritten data, especially to the console. */ + __flush_all_files(-1); + + #if defined(__amigaos4__) + { + /* Try to print the error message on the default error output stream. */ + output = ErrorOutput(); + } + #else + { + struct Process * this_process = (struct Process *)FindTask(NULL); + + output = this_process->pr_CES; + } + #endif /* __amigaos4__ */ + + if(output == ZERO) + output = Output(); + + if(output != ZERO) + { + if(__program_name != NULL) + FPrintf(output,"[%s] ",__program_name); + + FPrintf(output, + "%s:%ld: failed assertion \"%s\".\n", + file_name, + line_number, + expression); + } + + #if defined(__amigaos4__) + { + DropInterface((struct Interface *)IDOS); + } + #endif /* __amigaos4__ */ + + CloseLibrary(DOSBase); + } + + _exit(EXIT_FAILURE); + } } - - abort(); } been_here_before--; diff --git a/library/stdlib_main.c b/library/stdlib_main.c index 336d790..b6efba6 100644 --- a/library/stdlib_main.c +++ b/library/stdlib_main.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_main.c,v 1.18 2005-03-19 10:15:56 obarthel Exp $ + * $Id: stdlib_main.c,v 1.19 2005-03-19 11:06:57 obarthel Exp $ * * :ts=4 * @@ -117,11 +117,8 @@ call_main(void) complicated than they already are. */ __check_abort_enabled = FALSE; - if(stdout != NULL) - fflush(stdout); - - if(stderr != NULL) - fflush(stderr); + /* Dump all currently unwritten data, especially to the console. */ + __flush_all_files(-1); __show_error("Stack overflow detected"); diff --git a/library/stdlib_termination_message.c b/library/stdlib_termination_message.c index d09731e..f417ac1 100644 --- a/library/stdlib_termination_message.c +++ b/library/stdlib_termination_message.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_termination_message.c,v 1.4 2005-01-09 10:10:41 obarthel Exp $ + * $Id: stdlib_termination_message.c,v 1.5 2005-03-19 11:06:57 obarthel Exp $ * * :ts=4 * @@ -54,7 +54,7 @@ __print_termination_message(const char * termination_message) { termination_message_printed = TRUE; - if(NOT __no_standard_io) + if(NOT __no_standard_io && __num_iob > STDERR_FILENO) { fputs((termination_message != NULL) ? termination_message : "Abnormal program termination",stderr);