emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] trunk r113395: Clean up errno reporting and fix some errno


From: Paul Eggert
Subject: [Emacs-diffs] trunk r113395: Clean up errno reporting and fix some errno-reporting bugs.
Date: Fri, 12 Jul 2013 17:30:52 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 113395
revision-id: address@hidden
parent: address@hidden
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Fri 2013-07-12 10:30:48 -0700
message:
  Clean up errno reporting and fix some errno-reporting bugs.
  
  * callproc.c (Fcall_process):
  * fileio.c (Fcopy_file, Finsert_file_contents, Fwrite_region):
  * process.c (create_process, Fmake_network_process):
  * unexaix.c (report_error):
  * unexcoff.c (report_error):
  Be more careful about reporting the errno of failed operations.
  The code previously reported the wrong errno sometimes.
  Also, prefer report_file_errno to setting errno + report_file_error.
  (Fcall_process): Look at openp return value rather than at path,
  as that's a bit faster and clearer when there's a numeric predicate.
  * fileio.c (report_file_errno): New function, with most of the
  old contents of report_file_error.
  (report_file_error): Use it.
  (Ffile_exists_p, Ffile_accessible_directory_p):
  Set errno to 0 when it is junk.
  * fileio.c (Faccess_file):
  * image.c (x_create_bitmap_from_file):
  Use faccessat rather than opening the file, to avoid the hassle of
  having a file descriptor open.
  * lisp.h (report_file_errno): New decl.
  * lread.c (Flocate_file_internal): File descriptor 0 is valid, too.
modified:
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/callproc.c                 callproc.c-20091113204419-o5vbwnq5f7feedwu-248
  src/fileio.c                   fileio.c-20091113204419-o5vbwnq5f7feedwu-210
  src/image.c                    image.c-20091113204419-o5vbwnq5f7feedwu-2969
  src/lisp.h                     lisp.h-20091113204419-o5vbwnq5f7feedwu-253
  src/lread.c                    lread.c-20091113204419-o5vbwnq5f7feedwu-266
  src/process.c                  process.c-20091113204419-o5vbwnq5f7feedwu-462
  src/unexaix.c                  unexaix.c-20091113204419-o5vbwnq5f7feedwu-147
  src/unexcoff.c                 unexec.c-20091113204419-o5vbwnq5f7feedwu-184
=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-07-12 14:31:42 +0000
+++ b/src/ChangeLog     2013-07-12 17:30:48 +0000
@@ -1,5 +1,28 @@
 2013-07-12  Paul Eggert  <address@hidden>
 
+       Clean up errno reporting and fix some errno-reporting bugs.
+       * callproc.c (Fcall_process):
+       * fileio.c (Fcopy_file, Finsert_file_contents, Fwrite_region):
+       * process.c (create_process, Fmake_network_process):
+       * unexaix.c (report_error):
+       * unexcoff.c (report_error):
+       Be more careful about reporting the errno of failed operations.
+       The code previously reported the wrong errno sometimes.
+       Also, prefer report_file_errno to setting errno + report_file_error.
+       (Fcall_process): Look at openp return value rather than at path,
+       as that's a bit faster and clearer when there's a numeric predicate.
+       * fileio.c (report_file_errno): New function, with most of the
+       old contents of report_file_error.
+       (report_file_error): Use it.
+       (Ffile_exists_p, Ffile_accessible_directory_p):
+       Set errno to 0 when it is junk.
+       * fileio.c (Faccess_file):
+       * image.c (x_create_bitmap_from_file):
+       Use faccessat rather than opening the file, to avoid the hassle of
+       having a file descriptor open.
+       * lisp.h (report_file_errno): New decl.
+       * lread.c (Flocate_file_internal): File descriptor 0 is valid, too.
+
        Minor EBADF fixes.
        * process.c (create_process, wait_reading_process_output) [AIX]:
        Remove obsolete SIGHUP-related  code, as Emacs no longer disables

=== modified file 'src/callproc.c'
--- a/src/callproc.c    2013-07-12 02:03:47 +0000
+++ b/src/callproc.c    2013-07-12 17:30:48 +0000
@@ -419,9 +419,10 @@
                              default_output_mode);
       if (fd_output < 0)
        {
+         int open_errno = errno;
          output_file = DECODE_FILE (output_file);
-         report_file_error ("Opening process output file",
-                            Fcons (output_file, Qnil));
+         report_file_errno ("Opening process output file",
+                            Fcons (output_file, Qnil), open_errno);
        }
       if (STRINGP (error_file) || NILP (error_file))
        output_to_buffer = 0;
@@ -430,18 +431,19 @@
   /* Search for program; barf if not found.  */
   {
     struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+    int ok;
 
     GCPRO4 (infile, buffer, current_dir, error_file);
-    openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number (X_OK));
+    ok = openp (Vexec_path, args[0], Vexec_suffixes, &path, make_number 
(X_OK));
     UNGCPRO;
+    if (ok < 0)
+      {
+       int openp_errno = errno;
+       emacs_close (filefd);
+       report_file_errno ("Searching for program",
+                          Fcons (args[0], Qnil), openp_errno);
+      }
   }
-  if (NILP (path))
-    {
-      int openp_errno = errno;
-      emacs_close (filefd);
-      errno = openp_errno;
-      report_file_error ("Searching for program", Fcons (args[0], Qnil));
-    }
 
   /* If program file name starts with /: for quoting a magic name,
      discard that.  */
@@ -499,11 +501,13 @@
       mktemp (tempfile);
       outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC,
                              S_IREAD | S_IWRITE);
-      if (outfilefd < 0) {
-       emacs_close (filefd);
-       report_file_error ("Opening process output file",
-                          Fcons (build_string (tempfile), Qnil));
-      }
+      if (outfilefd < 0)
+       {
+         int open_errno = errno;
+         emacs_close (filefd);
+         report_file_errno ("Opening process output file",
+                            Fcons (build_string (tempfile), Qnil), open_errno);
+       }
     }
   else
     outfilefd = fd_output;
@@ -524,8 +528,7 @@
        {
          int pipe_errno = errno;
          emacs_close (filefd);
-         errno = pipe_errno;
-         report_file_error ("Creating process pipe", Qnil);
+         report_file_errno ("Creating process pipe", Qnil, pipe_errno);
        }
       fd0 = fd[0];
       fd1 = fd[1];
@@ -547,6 +550,7 @@
 
     if (fd_error < 0)
       {
+       int open_errno = errno;
        emacs_close (filefd);
        if (fd0 != filefd)
          emacs_close (fd0);
@@ -559,7 +563,8 @@
          error_file = build_string (NULL_DEVICE);
        else if (STRINGP (error_file))
          error_file = DECODE_FILE (error_file);
-       report_file_error ("Cannot redirect stderr", Fcons (error_file, Qnil));
+       report_file_errno ("Cannot redirect stderr",
+                          Fcons (error_file, Qnil), open_errno);
       }
 
 #ifdef MSDOS /* MW, July 1993 */
@@ -587,10 +592,12 @@
        fd0 = emacs_open (tempfile, O_RDONLY | O_BINARY, 0);
        if (fd0 < 0)
          {
+           int open_errno = errno;
            unlink (tempfile);
            emacs_close (filefd);
-           report_file_error ("Cannot re-open temporary file",
-                              Fcons (build_string (tempfile), Qnil));
+           report_file_errno ("Cannot re-open temporary file",
+                              Fcons (build_string (tempfile), Qnil),
+                              open_errno);
          }
       }
     else
@@ -708,10 +715,7 @@
   }
 
   if (pid < 0)
-    {
-      errno = child_errno;
-      report_file_error ("Doing vfork", Qnil);
-    }
+    report_file_errno ("Doing vfork", Qnil, child_errno);
 
   if (INTEGERP (buffer))
     return unbind_to (count, Qnil);
@@ -1039,7 +1043,7 @@
 
 #if defined HAVE_MKOSTEMP || defined HAVE_MKSTEMP
     {
-      int fd;
+      int fd, open_errno;
 
       block_input ();
 # ifdef HAVE_MKOSTEMP
@@ -1047,23 +1051,19 @@
 # else
       fd = mkstemp (tempfile);
 # endif
+      open_errno = errno;
       unblock_input ();
-      if (fd == -1)
-       report_file_error ("Failed to open temporary file",
-                          Fcons (build_string (tempfile), Qnil));
-      else
-       emacs_close (fd);
+      if (fd < 0)
+       report_file_errno ("Failed to open temporary file",
+                          Fcons (build_string (tempfile), Qnil), open_errno);
+      emacs_close (fd);
     }
 #else
-    errno = 0;
+    errno = EEXIST;
     mktemp (tempfile);
     if (!*tempfile)
-      {
-       if (!errno)
-         errno = EEXIST;
-       report_file_error ("Failed to open temporary file using pattern",
-                          Fcons (pattern, Qnil));
-      }
+      report_file_error ("Failed to open temporary file using pattern",
+                        Fcons (pattern, Qnil));
 #endif
 
     filename_string = build_string (tempfile);

=== modified file 'src/fileio.c'
--- a/src/fileio.c      2013-07-10 06:26:23 +0000
+++ b/src/fileio.c      2013-07-12 17:30:48 +0000
@@ -159,11 +159,13 @@
                     struct coding_system *);
 
 
+/* Signal a file-access failure.  STRING describes the failure,
+   DATA the file that was involved, and ERRORNO the errno value.  */
+
 void
-report_file_error (const char *string, Lisp_Object data)
+report_file_errno (char const *string, Lisp_Object data, int errorno)
 {
   Lisp_Object errstring;
-  int errorno = errno;
   char *str;
 
   synchronize_system_messages_locale ();
@@ -196,6 +198,12 @@
       }
 }
 
+void
+report_file_error (char const *string, Lisp_Object data)
+{
+  report_file_errno (string, data, errno);
+}
+
 Lisp_Object
 close_file_unwind (Lisp_Object fd)
 {
@@ -2019,11 +2027,8 @@
     {
       /* CopyFile doesn't set errno when it fails.  By far the most
         "popular" reason is that the target is read-only.  */
-      if (GetLastError () == 5)
-       errno = EACCES;
-      else
-       errno = EPERM;
-      report_file_error ("Copying file", Fcons (file, Fcons (newname, Qnil)));
+      report_file_errno ("Copying file", Fcons (file, Fcons (newname, Qnil)),
+                        GetLastError () == 5 ? EACCES : EPERM);
     }
   /* CopyFile retains the timestamp by default.  */
   else if (NILP (keep_time))
@@ -2084,36 +2089,25 @@
 
   if (out_st.st_mode != 0
       && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
-    {
-      errno = 0;
-      report_file_error ("Input and output files are the same",
-                        Fcons (file, Fcons (newname, Qnil)));
-    }
+    report_file_errno ("Input and output files are the same",
+                      Fcons (file, Fcons (newname, Qnil)), 0);
 
   /* We can copy only regular files.  */
   if (!S_ISREG (st.st_mode))
-    {
-      /* Get a better looking error message. */
-      errno = S_ISDIR (st.st_mode) ? EISDIR : EINVAL;
-      report_file_error ("Non-regular file", Fcons (file, Qnil));
-    }
+    report_file_errno ("Non-regular file", Fcons (file, Qnil),
+                      S_ISDIR (st.st_mode) ? EISDIR : EINVAL);
 
-#ifdef MSDOS
-  /* System's default file type was set to binary by _fmode in emacs.c.  */
-  ofd = emacs_open (SDATA (encoded_newname),
-                   O_WRONLY | O_TRUNC | O_CREAT
-                   | (NILP (ok_if_already_exists) ? O_EXCL : 0),
-                   S_IREAD | S_IWRITE);
-#else  /* not MSDOS */
   {
-    mode_t new_mask = !NILP (preserve_uid_gid) ? 0600 : 0666;
-    new_mask &= st.st_mode;
+#ifndef MSDOS
+    int new_mask = st.st_mode & (!NILP (preserve_uid_gid) ? 0600 : 0666);
+#else
+    int new_mask = S_IREAD | S_IWRITE;
+#endif
     ofd = emacs_open (SSDATA (encoded_newname),
                      (O_WRONLY | O_TRUNC | O_CREAT
                       | (NILP (ok_if_already_exists) ? O_EXCL : 0)),
                      new_mask);
   }
-#endif /* not MSDOS */
   if (ofd < 0)
     report_file_error ("Opening output file", Fcons (newname, Qnil));
 
@@ -2609,7 +2603,11 @@
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (absname, Qfile_exists_p);
   if (!NILP (handler))
-    return call2 (handler, Qfile_exists_p, absname);
+    {
+      Lisp_Object result = call2 (handler, Qfile_exists_p, absname);
+      errno = 0;
+      return result;
+    }
 
   absname = ENCODE_FILE (absname);
 
@@ -2706,7 +2704,6 @@
   (Lisp_Object filename, Lisp_Object string)
 {
   Lisp_Object handler, encoded_filename, absname;
-  int fd;
 
   CHECK_STRING (filename);
   absname = Fexpand_file_name (filename, Qnil);
@@ -2721,10 +2718,8 @@
 
   encoded_filename = ENCODE_FILE (absname);
 
-  fd = emacs_open (SSDATA (encoded_filename), O_RDONLY, 0);
-  if (fd < 0)
+  if (faccessat (AT_FDCWD, SSDATA (encoded_filename), R_OK, AT_EACCESS) != 0)
     report_file_error (SSDATA (string), Fcons (filename, Qnil));
-  emacs_close (fd);
 
   return Qnil;
 }
@@ -2833,7 +2828,11 @@
      call the corresponding file handler.  */
   handler = Ffind_file_name_handler (absname, Qfile_accessible_directory_p);
   if (!NILP (handler))
-    return call2 (handler, Qfile_accessible_directory_p, absname);
+    {
+      Lisp_Object r = call2 (handler, Qfile_accessible_directory_p, absname);
+      errno = 0;
+      return r;
+    }
 
   absname = ENCODE_FILE (absname);
   return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil;
@@ -4575,8 +4574,8 @@
       && EMACS_NSECS (current_buffer->modtime) == NONEXISTENT_MODTIME_NSECS)
     {
       /* If visiting nonexistent file, return nil.  */
-      errno = save_errno;
-      report_file_error ("Opening input file", Fcons (orig_filename, Qnil));
+      report_file_errno ("Opening input file", Fcons (orig_filename, Qnil),
+                        save_errno);
     }
 
   if (read_quit)
@@ -4897,13 +4896,13 @@
 
   if (desc < 0)
     {
+      int open_errno = errno;
 #ifdef CLASH_DETECTION
-      save_errno = errno;
       if (!auto_saving) unlock_file (lockname);
-      errno = save_errno;
 #endif /* CLASH_DETECTION */
       UNGCPRO;
-      report_file_error ("Opening output file", Fcons (filename, Qnil));
+      report_file_errno ("Opening output file", Fcons (filename, Qnil),
+                        open_errno);
     }
 
   record_unwind_protect (close_file_unwind, make_number (desc));
@@ -4913,13 +4912,13 @@
       off_t ret = lseek (desc, offset, SEEK_SET);
       if (ret < 0)
        {
+         int lseek_errno = errno;
 #ifdef CLASH_DETECTION
-         save_errno = errno;
          if (!auto_saving) unlock_file (lockname);
-         errno = save_errno;
 #endif /* CLASH_DETECTION */
          UNGCPRO;
-         report_file_error ("Lseek error", Fcons (filename, Qnil));
+         report_file_errno ("Lseek error", Fcons (filename, Qnil),
+                            lseek_errno);
        }
     }
 

=== modified file 'src/image.c'
--- a/src/image.c       2013-07-12 09:02:30 +0000
+++ b/src/image.c       2013-07-12 17:30:48 +0000
@@ -316,7 +316,6 @@
   int xhot, yhot, result;
   ptrdiff_t id;
   Lisp_Object found;
-  int fd;
   char *filename;
 
   /* Look for an existing bitmap with the same name.  */
@@ -332,10 +331,8 @@
     }
 
   /* Search bitmap-file-path for the file, if appropriate.  */
-  fd = openp (Vx_bitmap_file_path, file, Qnil, &found, Qnil);
-  if (fd < 0)
+  if (openp (Vx_bitmap_file_path, file, Qnil, &found, make_number (R_OK)) < 0)
     return -1;
-  emacs_close (fd);
 
   filename = SSDATA (found);
 

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2013-07-10 23:23:57 +0000
+++ b/src/lisp.h        2013-07-12 17:30:48 +0000
@@ -3822,6 +3822,7 @@
 EXFUN (Fread_file_name, 6);     /* Not a normal DEFUN.  */
 extern Lisp_Object close_file_unwind (Lisp_Object);
 extern Lisp_Object restore_point_unwind (Lisp_Object);
+extern _Noreturn void report_file_errno (const char *, Lisp_Object, int);
 extern _Noreturn void report_file_error (const char *, Lisp_Object);
 extern bool internal_delete_file (Lisp_Object);
 extern Lisp_Object emacs_readlinkat (int, const char *);

=== modified file 'src/lread.c'
--- a/src/lread.c       2013-07-12 02:03:47 +0000
+++ b/src/lread.c       2013-07-12 17:30:48 +0000
@@ -1412,7 +1412,7 @@
 {
   Lisp_Object file;
   int fd = openp (path, filename, suffixes, &file, predicate);
-  if (NILP (predicate) && fd > 0)
+  if (NILP (predicate) && fd >= 0)
     emacs_close (fd);
   return file;
 }

=== modified file 'src/process.c'
--- a/src/process.c     2013-07-12 14:31:42 +0000
+++ b/src/process.c     2013-07-12 17:30:48 +0000
@@ -1616,6 +1616,7 @@
 {
   int inchannel, outchannel;
   pid_t pid;
+  int vfork_errno;
   int sv[2];
 #ifndef WINDOWSNT
   int wait_child_setup[2];
@@ -1656,9 +1657,10 @@
       forkout = sv[1];
       if (pipe2 (sv, O_CLOEXEC) != 0)
        {
+         int pipe_errno = errno;
          emacs_close (inchannel);
          emacs_close (forkout);
-         report_file_error ("Creating pipe", Qnil);
+         report_file_errno ("Creating pipe", Qnil, pipe_errno);
        }
       outchannel = sv[1];
       forkin = sv[0];
@@ -1837,6 +1839,7 @@
 
   /* Back in the parent process.  */
 
+  vfork_errno = errno;
   XPROCESS (process)->pid = pid;
   if (pid >= 0)
     XPROCESS (process)->alive = 1;
@@ -1851,6 +1854,7 @@
        emacs_close (forkin);
       if (forkin != forkout && forkout >= 0)
        emacs_close (forkout);
+      report_file_errno ("Doing vfork", Qnil, vfork_errno);
     }
   else
     {
@@ -1896,10 +1900,6 @@
       }
 #endif
     }
-
-  /* Now generate the error if vfork failed.  */
-  if (pid < 0)
-    report_file_error ("Doing vfork", Qnil);
 }
 
 void
@@ -3265,12 +3265,11 @@
 
          len = sizeof xerrno;
          eassert (FD_ISSET (s, &fdset));
-         if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) == -1)
+         if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0)
            report_file_error ("getsockopt failed", Qnil);
          if (xerrno)
-           errno = xerrno, report_file_error ("error during connect", Qnil);
-         else
-           break;
+           report_file_errno ("error during connect", Qnil, xerrno);
+         break;
        }
 #endif /* !WINDOWSNT */
 
@@ -3354,11 +3353,10 @@
       if (is_non_blocking_client)
          return Qnil;
 
-      errno = xerrno;
-      if (is_server)
-       report_file_error ("make server process failed", contact);
-      else
-       report_file_error ("make client process failed", contact);
+      report_file_errno ((is_server
+                         ? "make server process failed"
+                         : "make client process failed"),
+                        contact, xerrno);
     }
 
   inch = s;

=== modified file 'src/unexaix.c'
--- a/src/unexaix.c     2013-07-12 02:03:47 +0000
+++ b/src/unexaix.c     2013-07-12 17:30:48 +0000
@@ -94,13 +94,10 @@
 static _Noreturn void
 report_error (const char *file, int fd)
 {
+  int err = errno;
   if (fd)
-    {
-      int failed_errno = errno;
-      emacs_close (fd);
-      errno = failed_errno;
-    }
-  report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil));
+    emacs_close (fd);
+  report_file_errno ("Cannot unexec", Fcons (build_string (file), Qnil), err);
 }
 
 #define ERROR0(msg) report_error_1 (new, msg)

=== modified file 'src/unexcoff.c'
--- a/src/unexcoff.c    2013-07-12 02:03:47 +0000
+++ b/src/unexcoff.c    2013-07-12 17:30:48 +0000
@@ -127,9 +127,10 @@
 static void
 report_error (const char *file, int fd)
 {
+  int err = errno;
   if (fd)
     emacs_close (fd);
-  report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil));
+  report_file_errno ("Cannot unexec", Fcons (build_string (file), Qnil), err);
 }
 
 #define ERROR0(msg) report_error_1 (new, msg, 0, 0); return -1


reply via email to

[Prev in Thread] Current Thread [Next in Thread]