This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Gas vs irregular files
Nick Clifton <nickc@redhat.com> writes:
> Hi Andreas,
>
>>> Error: can't open <name-of-directory> for reading
>>> <name-of-directory>: No error
>>
>> But only because the handling of errno is flawed. as_bad makes
>> library calls that may alter errno, so the original value is lost
>> when as_perror is called.
>
> Are you sure ? Which library calls ? [I am assuming that fprintf
> and friends do not set errno. Is this correct ?]
No. Every C library function may alter errno (with a few exceptions).
In general, the value of errno is only defined after an unsuccessful
call to a library function until the next library call. Note that
there are also calls to gettext in as_show_where and as_bad that can
result in further system calls.
>> This continues to be a problem even with your patch, because
>> as_perror is also broken in this regard.
>
> I think that the real problem is that as_perror() uses the bfd error
> number in preference to errno if BFD_ASSEMBLER is defined. So I would
> like to offer the following patch to fix this behaviour and to
> simplify the code in input_file_open() as a result.
>
> What do you think ?
bfd_errmsg already calls strerror for bfd_error_system_call, so the
right thing should be to always call bfd_set_error with
bfd_error_system_call before we call as_perror. Then as_perror has to
be fixed to save and restore errno. Finally, removing the calls to
as_bad as in your patch should make sure the right error is reported.
This patch also fixes some more as_perror calls.
Andreas.
2003-12-19 Nick Clifton <nickc@redhat.com>
Andreas Schwab <schwab@suse.de>
* messages.c (as_perror): Save errno around library calls.
* input-file.c [BFD_ASSEMBLER]: Set the BFD error to
bfd_error_system_call before each call to as_perror.
(input_file_open): Simplify the error reporting code to just use
as_perror().
* output-file.c (output_file_create) [BFD_ASSEMBLER]: Set the BFD
error to bfd_error_system_call before calling as_perror.
(output_file_close) [BFD_ASSEMBLER]: Likewise.
(output_file_append) [BFD_ASSEMBLER]: Likewise.
* listing.c (listing_print) [BFD_ASSEMBLER]: Likewise.
--- gas/input-file.c.~1.14.~ 2003-12-19 11:57:23.000000000 +0100
+++ gas/input-file.c 2003-12-19 13:27:54.336257920 +0100
@@ -151,18 +151,10 @@ input_file_open (char *filename, /* "" m
if (f_in == NULL || ferror (f_in))
{
- switch (errno)
- {
- case ENOENT:
- as_bad (_("%s: no such file"), filename);
- break;
- case EISDIR:
- as_bad (_("%s: is a directory"), filename);
- break;
- default:
- as_bad (_("can't open %s for reading"), file_name);
- as_perror ("%s", file_name);
- }
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("Can't open %s for reading"), file_name);
if (f_in)
{
@@ -227,6 +219,9 @@ input_file_get (char *buf, int buflen)
size = fread (buf, sizeof (char), buflen, f_in);
if (size < 0)
{
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
as_perror (_("Can't read from %s"), file_name);
size = 0;
}
@@ -253,6 +248,9 @@ input_file_give_next_buffer (char *where
size = fread (where, sizeof (char), BUFFER_SIZE, f_in);
if (size < 0)
{
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
as_perror (_("Can't read from %s"), file_name);
size = 0;
}
@@ -261,7 +259,12 @@ input_file_give_next_buffer (char *where
else
{
if (fclose (f_in))
- as_perror (_("Can't close %s"), file_name);
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("Can't close %s"), file_name);
+ }
f_in = (FILE *) 0;
return_value = 0;
}
--- gas/listing.c.~1.24.~ 2003-11-28 23:08:36.000000000 +0100
+++ gas/listing.c 2003-12-19 13:39:17.862346160 +0100
@@ -1,6 +1,6 @@
/* listing.c - maintain assembly listings
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002
+ 2001, 2002, 2003
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -1103,6 +1103,9 @@ listing_print (char *name)
using_stdout = 0;
else
{
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
as_perror (_("can't open list file: %s"), name);
list_file = stdout;
using_stdout = 1;
@@ -1127,7 +1130,12 @@ listing_print (char *name)
if (! using_stdout)
{
if (fclose (list_file) == EOF)
- as_perror (_("error closing list file: %s"), name);
+ {
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
+ as_perror (_("error closing list file: %s"), name);
+ }
}
if (last_open_file)
--- gas/messages.c.~1.7.~ 2003-11-28 23:08:37.000000000 +0100
+++ gas/messages.c 2003-12-19 13:07:34.454636000 +0100
@@ -144,9 +144,11 @@ as_perror (const char *gripe, /* Unpunc
const char *filename)
{
const char *errtxt;
+ int error_number = errno;
as_show_where ();
fprintf (stderr, gripe, filename);
+ errno = error_number;
#ifdef BFD_ASSEMBLER
errtxt = bfd_errmsg (bfd_get_error ());
#else
--- gas/output-file.c.~1.7.~ 2003-12-04 09:08:20.000000000 +0100
+++ gas/output-file.c 2003-12-19 13:39:28.788685104 +0100
@@ -1,5 +1,5 @@
/* output-file.c - Deal with the output file
- Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2001
+ Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2001, 2003
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -110,6 +110,9 @@ output_file_create (name)
stdoutput = fopen (name, FOPEN_WB);
if (stdoutput == NULL)
{
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
as_perror (_("FATAL: can't create %s"), name);
exit (EXIT_FAILURE);
}
@@ -121,6 +124,9 @@ output_file_close (filename)
{
if (EOF == fclose (stdoutput))
{
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
as_perror (_("FATAL: can't close %s"), filename);
exit (EXIT_FAILURE);
}
@@ -142,6 +148,9 @@ output_file_append (where, length, filen
if (ferror (stdoutput))
/* if ( EOF == (putc( *where, stdoutput )) ) */
{
+#ifdef BFD_ASSEMBLER
+ bfd_set_error (bfd_error_system_call);
+#endif
as_perror (_("Failed to emit an object byte"), filename);
as_fatal (_("can't continue"));
}
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, MaxfeldstraÃe 5, 90409 NÃrnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."