diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 537415f16fe63b5e9c18c094005580717beef3cb..c2218fba7179f20167d8321404635d8c89a318fd 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,14 @@ +2005-01-22 David Edelsohn <edelsohn@gnu.org> + + PR libgfortran/19052 + * libgfortran.h (options_t): Add stderr_unit. + * io/io.h (error_stream): Declare. + * io/open.c (new_unit): Do not terminate abnormally if opening + file preconnected to stdin, stdout, or stderr. + * io/unit.c (init_units): Initialize stderr_unit. + * io/unix.c (error_stream): New function. + * runtime/environ.c (GFORTRAN_STDERR_UNIT): New environment variable. + 2005-01-22 Thomas Koenig <Thomas.Koenig@online.de> PR libfortran/18982 diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 2975f9e73adb126649401826736e4e53fd74ccce..694ca1d7ac553bb3eaa5d994bc169e179b2b43a6 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -395,6 +395,9 @@ internal_proto(input_stream); extern stream *output_stream (void); internal_proto(output_stream); +extern stream *error_stream (void); +internal_proto(error_stream); + extern int compare_file_filename (stream *, const char *, int); internal_proto(compare_file_filename); diff --git a/libgfortran/io/open.c b/libgfortran/io/open.c index 9c23131f97ee70b9fa518ace5dc51cf2ff2b0ca4..eaeb5a298c0c694c94363af9a73593fb26948cb2 100644 --- a/libgfortran/io/open.c +++ b/libgfortran/io/open.c @@ -323,9 +323,14 @@ new_unit (unit_flags * flags) internal_error ("new_unit(): Bad status"); } - /* Make sure the file isn't already open someplace else. */ - - if (find_file () != NULL) + /* Make sure the file isn't already open someplace else. + Do not error if opening file preconnected to stdin, stdout, stderr. */ + + u = find_file (); + if (u != NULL + && (options.stdin_unit < 0 || u->unit_number != options.stdin_unit) + && (options.stdout_unit < 0 || u->unit_number != options.stdout_unit) + && (options.stderr_unit < 0 || u->unit_number != options.stderr_unit)) { generate_error (ERROR_ALREADY_OPEN, NULL); goto cleanup; diff --git a/libgfortran/io/unit.c b/libgfortran/io/unit.c index bf68b7880f117b3dadf08c461a58c9c0c4622d84..ae0771f0816027b6d2c5ddbbe230309d5b8fd233 100644 --- a/libgfortran/io/unit.c +++ b/libgfortran/io/unit.c @@ -334,6 +334,27 @@ init_units (void) insert_unit (u); } + if (options.stderr_unit >= 0) + { /* STDERR */ + u = get_mem (sizeof (gfc_unit)); + + u->unit_number = options.stderr_unit; + u->s = error_stream (); + + u->flags.action = ACTION_WRITE; + + u->flags.access = ACCESS_SEQUENTIAL; + u->flags.form = FORM_FORMATTED; + u->flags.status = STATUS_OLD; + u->flags.blank = BLANK_ZERO; + u->flags.position = POSITION_ASIS; + + u->recl = options.default_recl; + u->endfile = AT_ENDFILE; + + insert_unit (u); + } + /* Calculate the maximum file offset in a portable manner. * max will be the largest signed number for the type gfc_offset. * diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index daa0fb1107263a8dbf22c8369279786488e5fa89..5dc31a513d9511d40616306268be0b3ab688dba4 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -1160,7 +1160,7 @@ input_stream (void) } -/* output_stream()-- Return a stream pointer to the default input stream. +/* output_stream()-- Return a stream pointer to the default output stream. * Called on initialization. */ stream * @@ -1170,6 +1170,15 @@ output_stream (void) } +/* error_stream()-- Return a stream pointer to the default error stream. + * Called on initialization. */ + +stream * +error_stream (void) +{ + return fd_to_stream (STDERR_FILENO, PROT_WRITE); +} + /* init_error_stream()-- Return a pointer to the error stream. This * subroutine is called when the stream is needed, rather than at * initialization. We want to work even if memory has been seriously diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h index ccafb7c979b66def7974278b567eebed60c9c06d..dfa2e409f4b69b338aea3be95cc3036898f2e8f5 100644 --- a/libgfortran/libgfortran.h +++ b/libgfortran/libgfortran.h @@ -292,7 +292,7 @@ enum typedef struct { - int stdin_unit, stdout_unit, optional_plus; + int stdin_unit, stdout_unit, stderr_unit, optional_plus; int allocate_init_flag, allocate_init_value; int locus; diff --git a/libgfortran/runtime/environ.c b/libgfortran/runtime/environ.c index 87fe565729d383cc2aa0aeb9f88c25b979d099f3..ae82f562b7548841454eaa81444f32aa1634a854 100644 --- a/libgfortran/runtime/environ.c +++ b/libgfortran/runtime/environ.c @@ -443,6 +443,11 @@ static variable variable_table[] = { "Unit number that will be preconnected to standard output\n" "(No preconnection if negative)"}, + {"GFORTRAN_STDERR_UNIT", 0, &options.stderr_unit, init_integer, + show_integer, + "Unit number that will be preconnected to standard error\n" + "(No preconnection if negative)"}, + {"GFORTRAN_USE_STDERR", 1, &options.use_stderr, init_boolean, show_boolean, "Sends library output to standard error instead of standard output."},