From ffbfd24425c5fbace843a31caf9ed1fbc6cf0de7 Mon Sep 17 00:00:00 2001 From: jjgarcia Date: Wed, 27 Nov 2002 15:54:25 +0000 Subject: [PATCH] When illegally trying to access a closed stream, signal an error of type STREAM-ERROR. Also, check operations from the C library for possible errors and use FElibc_error() when these input/output operations fail. --- src/c/error.d | 6 ++ src/c/file.d | 178 +++++++++++++++++++---------------------------- src/c/print.d | 2 +- src/c/read.d | 2 +- src/h/external.h | 5 +- 5 files changed, 82 insertions(+), 111 deletions(-) diff --git a/src/c/error.d b/src/c/error.d index 897c66def..9668a21d6 100644 --- a/src/c/error.d +++ b/src/c/error.d @@ -139,6 +139,12 @@ FEend_of_file(cl_object strm) FEcondition(3, @'end-of-file', @':stream', strm); } +void +FEclosed_stream(cl_object strm) +{ + FEcondition(3, @'stream-error', @':stream', strm); +} + void FEwrong_type_argument(cl_object type, cl_object value) { diff --git a/src/c/file.d b/src/c/file.d index b5628fba0..a6955511f 100644 --- a/src/c/file.d +++ b/src/c/file.d @@ -51,7 +51,7 @@ BEGIN: FEtype_error_stream(strm); switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); break; case smm_io: @@ -97,7 +97,7 @@ BEGIN: FEtype_error_stream(strm); switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); return(FALSE); case smm_input: @@ -137,7 +137,7 @@ BEGIN: FEtype_error_stream(strm); switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); case smm_input: case smm_output: @@ -185,39 +185,39 @@ BEGIN: */ static void cannot_create(cl_object fn) __attribute__((noreturn)); -static void cannot_read(cl_object fn) __attribute__((noreturn)); -static void cannot_write(cl_object fn) __attribute__((noreturn)); -static void internal_stream_error(const char *routine, cl_object strm) __attribute__((noreturn)); +static void not_an_input_stream(cl_object fn) __attribute__((noreturn)); +static void not_an_output_stream(cl_object fn) __attribute__((noreturn)); +static void wrong_file_handler(cl_object strm) __attribute__((noreturn)); static void cannot_create(cl_object fn) { - FEerror("Cannot create the file ~A.", 1, fn); + FElibc_error("Cannot create the file ~A.", 1, fn); } static void -cannot_read(cl_object strm) +not_an_input_stream(cl_object strm) { FEerror("Cannot read the stream ~S.", 1, strm); } static void -cannot_write(cl_object strm) +not_an_output_stream(cl_object strm) { FEerror("Cannot write to the stream ~S.", 1, strm); } static void -internal_stream_error(const char *routine, cl_object strm) +io_error(cl_object strm) { - FEerror("~A : internal error, closed stream ~S without smm_mode flag.", - 2, make_constant_string(routine), strm); + FElibc_error("Read or write operation to stream ~S signaled an error.", + 1, strm); } -void -closed_stream(cl_object strm) +static void +wrong_file_handler(cl_object strm) { - FEerror("The stream ~S is already closed.", 1, strm); + FEerror("Internal error: closed stream ~S without smm_mode flag.", 1, strm); } /*---------------------------------------------------------------------- @@ -344,70 +344,30 @@ BEGIN: fp = strm->stream.file; switch ((enum smmode)strm->stream.mode) { case smm_closed: - /* It is permissible to close a closed stream, although the output - is unspecified in those cases. */ + /* It is permissible to close a closed stream, although the output + is unspecified in those cases. */ break; case smm_output: - if (fp == stdout) - FEerror("Cannot close the standard output.", 0); - if (fp == NULL) - internal_stream_error("close_stream", strm); - fflush(fp); - fclose(fp); -#if !defined(GBC_BOEHM) - cl_dealloc(strm->stream.buffer, BUFSIZ); - strm->stream.buffer = NULL; -#endif - strm->stream.file = NULL; - break; - + if (fp == stdout) + FEerror("Cannot close the standard output.", 0); + goto DO_CLOSE; case smm_input: if (fp == stdin) FEerror("Cannot close the standard input.", 0); - + DO_CLOSE: case smm_io: case smm_probe: - if (fp == NULL) - internal_stream_error("close_stream", strm); - fclose(fp); + if (fp == NULL) + wrong_file_handler(strm); + if (fclose(fp) != 0) + FElibc_error("Cannot close stream ~S.", 1, strm); #if !defined(GBC_BOEHM) - cl_dealloc(strm->stream.buffer, BUFSIZ); - strm->stream.file = NULL; + cl_dealloc(strm->stream.buffer, BUFSIZ); + strm->stream.file = NULL; #endif - break; -#if 0 - case smm_synonym: - strm = symbol_value(strm->stream.object0); - goto BEGIN; - - case smm_broadcast: - for (x = strm->stream.object0; !endp(x); x = CDR(x)) - close_stream(CAR(x), abort_flag); - strm->stream.object0 = Cnil; break; - case smm_concatenated: - for (x = strm->stream.object0; !endp(x); x = CDR(x)) - close_stream(CAR(x), abort_flag); - break; - - case smm_two_way: - close_stream(strm->stream.object0, abort_flag); - close_stream(strm->stream.object1, abort_flag); - break; - - case smm_echo: - close_stream(strm->stream.object0, abort_flag); - close_stream(strm->stream.object1, abort_flag); - break; - - case smm_string_input: - break; /* There is nothing to do. */ - - case smm_string_output: - break; /* There is nothing to do. */ -#else case smm_synonym: case smm_broadcast: case smm_concatenated: @@ -420,7 +380,7 @@ BEGIN: as it might contain an useful pathname */ strm->stream.object1 = OBJNULL; break; -#endif + default: error("illegal stream mode"); } @@ -551,16 +511,16 @@ BEGIN: fp = strm->stream.file; switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); break; case smm_input: case smm_io: if (fp == NULL) - internal_stream_error("ecl_getc",strm); + wrong_file_handler(strm); GETC(c, fp); if (c == EOF && ferror(fp)) - FElibc_error("File I/O error",0); + io_error(strm); break; case smm_synonym: @@ -608,7 +568,7 @@ BEGIN: case smm_probe: case smm_broadcast: case smm_string_output: - cannot_read(strm); + not_an_input_stream(strm); default: error("illegal stream mode"); @@ -642,14 +602,16 @@ BEGIN: fp = strm->stream.file; switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); break; case smm_input: case smm_io: if (fp == NULL) - internal_stream_error("ecl_ungetc",strm); + wrong_file_handler(strm); UNGETC(c, fp); + if (c == EOF) + io_error(strm); /* --strm->stream.int0; useless in smm_io, Beppe */ break; @@ -712,7 +674,7 @@ BEGIN: fp = strm->stream.file; switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); break; case smm_output: @@ -724,8 +686,9 @@ BEGIN: else strm->stream.int1++; if (fp == NULL) - internal_stream_error("writec",strm); - putc(c, fp); + wrong_file_handler(strm); + if (putc(c, fp) == EOF) + io_error(strm); break; case smm_synonym: @@ -767,7 +730,7 @@ BEGIN: case smm_probe: case smm_concatenated: case smm_string_input: - cannot_write(strm); + not_an_output_stream(strm); default: error("illegal stream mode"); @@ -800,14 +763,15 @@ BEGIN: fp = strm->stream.file; switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); break; case smm_output: case smm_io: if (fp == NULL) - internal_stream_error("flush_stream",strm); - fflush(fp); + wrong_file_handler(strm); + if (fflush(fp) == EOF) + io_error(strm); break; case smm_synonym: @@ -858,13 +822,14 @@ BEGIN: fp = strm->stream.file; switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); break; case smm_input: if (fp == NULL) - internal_stream_error("clear_input_stream",strm); - fseek(fp, 0L, 2); + wrong_file_handler(strm); + if (fseek(fp, 0L, 2) != 0) + io_error(strm); break; case smm_synonym: @@ -915,13 +880,14 @@ BEGIN: fp = strm->stream.file; switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); break; case smm_output: if (fp == NULL) - internal_stream_error("clear_output_stream",strm); - fseek(fp, 0L, 2); + wrong_file_handler(strm); + if (fseek(fp, 0L, 2) != 0) + io_error(strm); break; case smm_synonym: @@ -970,17 +936,17 @@ BEGIN: fp = strm->stream.file; switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); return(TRUE); case smm_io: case smm_input: if (fp == NULL) - closed_stream(strm); + FEclosed_stream(strm); GETC(c, fp); if (c == EOF) { if (ferror(fp)) - FElibc_error("File I/O error", 0); + io_error(strm); return(TRUE); } else { UNGETC(c, fp); @@ -1046,14 +1012,14 @@ BEGIN: FEtype_error_stream(strm); switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); return(FALSE); case smm_input: case smm_io: fp = strm->stream.file; if (fp == NULL) - internal_stream_error("listen_stream",strm); + wrong_file_handler(strm); if (feof(fp)) return(FALSE); if (FILE_CNT(fp) > 0) @@ -1110,7 +1076,7 @@ BEGIN: FEtype_error_stream(strm); switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); return(-1); case smm_input: @@ -1118,7 +1084,7 @@ BEGIN: case smm_io: fp = strm->stream.file; if (fp == NULL) - internal_stream_error("file_position",strm); + wrong_file_handler(strm); return(ftell(fp)); case smm_string_output: @@ -1155,7 +1121,7 @@ BEGIN: FEtype_error_stream(strm); switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); return(-1); case smm_input: @@ -1163,8 +1129,8 @@ BEGIN: case smm_io: fp = strm->stream.file; if (fp == NULL) - internal_stream_error("file_position_set",strm); - if (fseek(fp, disp, 0) < 0) + wrong_file_handler(strm); + if (fseek(fp, disp, 0) != 0) return(-1); return(0); @@ -1210,7 +1176,7 @@ BEGIN: FEtype_error_stream(strm); switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); return(-1); case smm_input: @@ -1218,7 +1184,7 @@ BEGIN: case smm_io: fp = strm->stream.file; if (fp == NULL) - internal_stream_error("file_length",strm); + wrong_file_handler(strm); return(file_len(fp)); case smm_synonym: @@ -1253,7 +1219,7 @@ BEGIN: FEtype_error_stream(strm); switch ((enum smmode)strm->stream.mode) { case smm_closed: - closed_stream(strm); + FEclosed_stream(strm); return(-1); case smm_output: @@ -1322,7 +1288,7 @@ cl_make_synonym_stream(cl_object sym) for (i = 0; i < narg; i++) { x = cl_va_arg(ap); if (type_of(x) != t_stream || !output_stream_p(x)) - cannot_write(x); + not_an_output_stream(x); streams = CONS(x, streams); } x = cl_alloc_object(t_stream); @@ -1342,7 +1308,7 @@ cl_make_synonym_stream(cl_object sym) for (i = 0; i < narg; i++) { x = cl_va_arg(ap); if (type_of(x) != t_stream || !input_stream_p(x)) - cannot_read(x); + not_an_input_stream(x); streams = CONS(x, streams); } x = cl_alloc_object(t_stream); @@ -1358,9 +1324,9 @@ cl_object cl_make_two_way_stream(cl_object strm1, cl_object strm2) { if (type_of(strm1) != t_stream || !input_stream_p(strm1)) - cannot_read(strm1); + not_an_input_stream(strm1); if (type_of(strm2) != t_stream || !output_stream_p(strm2)) - cannot_write(strm2); + not_an_output_stream(strm2); @(return make_two_way_stream(strm1, strm2)) } @@ -1368,9 +1334,9 @@ cl_object cl_make_echo_stream(cl_object strm1, cl_object strm2) { if (type_of(strm1) != t_stream || !input_stream_p(strm1)) - cannot_read(strm1); + not_an_input_stream(strm1); if (type_of(strm2) != t_stream || !output_stream_p(strm2)) - cannot_write(strm2); + not_an_output_stream(strm2); @(return make_echo_stream(strm1, strm2)) } diff --git a/src/c/print.d b/src/c/print.d index faead6052..da62b5b6f 100644 --- a/src/c/print.d +++ b/src/c/print.d @@ -1559,7 +1559,7 @@ si_write_bytes(cl_object stream, cl_object string, cl_object start, cl_object en assert_type_stream(stream); if (stream->stream.mode == smm_closed) - closed_stream(stream); + FEclosed_stream(stream); is = fix(start); /* FIXME: Unsafe! */ ie = fix(end); diff --git a/src/c/read.d b/src/c/read.d index 058d14251..75c71f38e 100644 --- a/src/c/read.d +++ b/src/c/read.d @@ -1531,7 +1531,7 @@ si_read_bytes(cl_object stream, cl_object string, cl_object start, cl_object end assert_type_stream(stream); if (stream->stream.mode == smm_closed) - closed_stream(stream); + FEclosed_stream(stream); /* FIXME! this may fail! */ is = fix(start); diff --git a/src/h/external.h b/src/h/external.h index 4a82e89c7..95a0d8615 100644 --- a/src/h/external.h +++ b/src/h/external.h @@ -292,6 +292,8 @@ extern void FEprogram_error(const char *s, int narg, ...) __attribute__((noretur extern void FEcontrol_error(const char *s, int narg, ...) __attribute__((noreturn)); extern void FEerror(char *s, int narg, ...) __attribute__((noreturn)); extern void FEcannot_open(cl_object fn) __attribute__((noreturn,regparm(2))); +extern void FEend_of_file(cl_object strm) __attribute__((noreturn,regparm(2))); +extern void FEclosed_stream(cl_object strm) __attribute__ ((noreturn,regparm(2))); extern void FEwrong_type_argument(cl_object type, cl_object value) __attribute__((noreturn,regparm(2))); extern void FEwrong_num_argumens(cl_object fun) __attribute__((noreturn,regparm(2))); extern void FEwrong_num_argumens_anonym(void) __attribute__((noreturn)); @@ -307,8 +309,6 @@ extern void FEtype_error_symbol(cl_object obj) __attribute__((noreturn,regparm(2 extern void FElibc_error(const char *msg, int narg, ...) __attribute__((noreturn)); extern void init_error(void); -extern void FEend_of_file(cl_object strm); - /* eval.c */ extern cl_object cl_funcall _ARGS((int narg, cl_object fun, ...)); @@ -357,7 +357,6 @@ extern cl_object cl_file_position _ARGS((int narg, cl_object file_stream, ...)); extern bool input_stream_p(cl_object strm); extern bool output_stream_p(cl_object strm); extern cl_object stream_element_type(cl_object strm); -extern void closed_stream(cl_object strm) __attribute__ ((noreturn,regparm(2))); extern cl_object open_stream(cl_object fn, enum smmode smm, cl_object if_exists, cl_object if_does_not_exist); extern void close_stream(cl_object strm, bool abort_flag); extern cl_object make_two_way_stream(cl_object istrm, cl_object ostrm);