This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB 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]

[binutils-gdb] source.c:openp: save/restore errno


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=79b289e2d8083691ccb2c943d4502e1af54e81e2

commit 79b289e2d8083691ccb2c943d4502e1af54e81e2
Author: Pedro Alves <palves@redhat.com>
Date:   Tue Oct 27 16:03:24 2015 +0000

    source.c:openp: save/restore errno
    
    openp's return is documented as:
    
    ~~~
       If a file is found, return the descriptor.
       Otherwise, return -1, with errno set for the last name we tried to open.  */
    ~~~
    
    By inspection, I noticed that there are function calls after the ones
    that first set errno, and those may clobber errno.  It's safer to save
    errno when see an open fail, and restore it on exit.
    
    Tested on x86_64 Fedora 20.
    
    gdb/ChangeLog:
    2015-10-27  Pedro Alves  <palves@redhat.com>
    
    	* source.c (openp): New local 'last_errno'.  Use it to
    	save/restore errno.

Diff:
---
 gdb/ChangeLog | 5 +++++
 gdb/source.c  | 7 +++++++
 2 files changed, 12 insertions(+)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6c81a9f..0e40c7e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
 2015-10-27  Pedro Alves  <palves@redhat.com>
 
+	* source.c (openp): New local 'last_errno'.  Use it to
+	save/restore errno.
+
+2015-10-27  Pedro Alves  <palves@redhat.com>
+
 	* psymtab.c (dump_psymtab_addrmap_1): Add casts.
 
 2015-10-27  Simon Marchi  <simon.marchi@polymtl.ca>
diff --git a/gdb/source.c b/gdb/source.c
index 3e5e15c..194b044 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -746,6 +746,9 @@ openp (const char *path, int opts, const char *string,
   struct cleanup *back_to;
   int ix;
   char *dir;
+  /* The errno set for the last name we tried to open (and
+     failed).  */
+  int last_errno = 0;
 
   /* The open syscall MODE parameter is not specified.  */
   gdb_assert ((mode & O_CREAT) == 0);
@@ -786,6 +789,7 @@ openp (const char *path, int opts, const char *string,
 	  filename = NULL;
 	  fd = -1;
 	}
+      last_errno = errno;
 
       if (!(opts & OPF_SEARCH_IN_PATH))
 	for (i = 0; string[i]; i++)
@@ -808,6 +812,7 @@ openp (const char *path, int opts, const char *string,
   alloclen = strlen (path) + strlen (string) + 2;
   filename = (char *) alloca (alloclen);
   fd = -1;
+  last_errno = ENOENT;
 
   dir_vec = dirnames_to_char_ptr_vec (path);
   back_to = make_cleanup_free_char_ptr_vec (dir_vec);
@@ -878,6 +883,7 @@ openp (const char *path, int opts, const char *string,
 	  fd = gdb_open_cloexec (filename, mode, 0);
 	  if (fd >= 0)
 	    break;
+	  last_errno = errno;
 	}
     }
 
@@ -895,6 +901,7 @@ done:
 	*filename_opened = gdb_abspath (filename);
     }
 
+  errno = last_errno;
   return fd;
 }


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