This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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."


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]