emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] trunk r113339: Handle errno and exit status a bit more car


From: Paul Eggert
Subject: [Emacs-diffs] trunk r113339: Handle errno and exit status a bit more carefully.
Date: Tue, 09 Jul 2013 07:04:58 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 113339
revision-id: address@hidden
parent: address@hidden
committer: Paul Eggert <address@hidden>
branch nick: trunk
timestamp: Tue 2013-07-09 00:04:48 -0700
message:
  Handle errno and exit status a bit more carefully.
  
  * lib/ignore-value.h: Remove this gnulib-imported file.
  * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
  * admin/merge-gnulib (GNULIB_MODULES): Remove ignore-value.
  * src/callproc.c (child_setup) [!DOS_NT]: Don't try to stuff an error
  number into an exit status.  Instead, use EXIT_CANCELED.
  (child_setup) [!MSDOS]: Avoid possible deadlock with vfork.
  * src/callproc.c (relocate_fd):
  * src/emacs.c (close_output_streams, main):
  * src/process.c (create_process):
  * src/sysdep.c (sys_subshell) [!DOS_NT || !WINDOWSNT]:
  Use emacs_perror for simplicity.
  * src/callproc.c (relocate_fd, main):
  * src/sysdep.c (sys_subshell):
  Exit with EXIT_CANCELED etc., not 1, when exec setup fails.
  (shut_down_emacs): Use emacs_write, not write.
  * src/emacs.c, src/sysdep.c: Don't include <ignore-value.h>.
  * src/fileio.c (Fcopy_file, e_write):
  * src/nsterm.m (ns_select):
  * src/process.c (send_process):
  * src/sound.c (vox_write):
  Use emacs_write_sig, not emacs_write.
  * src/lisp.h (emacs_write_sig, emacs_perror): New decls.
  * src/process.h (EXIT_CANCELED), EXIT_CANNOT_INVOKE, EXIT_ENOENT):
  New constants.
  * src/sysdep.c (emacs_backtrace): Use emacs_write, not ignore_value
  of write.
  (emacs_full_write): New function.
  (emacs_write): Rewrite to use it.
  (emacswrite_sig, emacs_perror): New functions.
  * src/xrdb.c (fatal): Don't invoke perror, since errno might be garbage.
removed:
  lib/ignore-value.h             ignorevalue.h-20110203213725-87ii79ljgr9ngwp2-1
modified:
  ChangeLog                      changelog-20091113204419-o5vbwnq5f7feedwu-1538
  admin/ChangeLog                changelog-20091113204419-o5vbwnq5f7feedwu-2226
  admin/merge-gnulib             mergegnulib-20120521022411-ndnoaiok33j6dn0g-1
  lib/gnulib.mk                  gnulib.mk-20110108211121-3ig4un4ogtyyca3s-7
  m4/gnulib-comp.m4              glcomp.m4-20110127072028-6mkjqxjzdsx0wp15-1
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/callproc.c                 callproc.c-20091113204419-o5vbwnq5f7feedwu-248
  src/emacs.c                    emacs.c-20091113204419-o5vbwnq5f7feedwu-241
  src/fileio.c                   fileio.c-20091113204419-o5vbwnq5f7feedwu-210
  src/lisp.h                     lisp.h-20091113204419-o5vbwnq5f7feedwu-253
  src/nsterm.m                   nsterm.m-20091113204419-o5vbwnq5f7feedwu-8747
  src/process.c                  process.c-20091113204419-o5vbwnq5f7feedwu-462
  src/process.h                  process.h-20091113204419-o5vbwnq5f7feedwu-272
  src/sound.c                    sound.c-20091113204419-o5vbwnq5f7feedwu-1323
  src/sysdep.c                   sysdep.c-20091113204419-o5vbwnq5f7feedwu-448
  src/xrdb.c                     xrdb.c-20091113204419-o5vbwnq5f7feedwu-177
=== modified file 'ChangeLog'
--- a/ChangeLog 2013-07-08 13:26:13 +0000
+++ b/ChangeLog 2013-07-09 07:04:48 +0000
@@ -1,3 +1,9 @@
+2013-07-09  Paul Eggert  <address@hidden>
+
+       Handle errno and exit status a bit more carefully.
+       * lib/ignore-value.h: Remove this gnulib-imported file.
+       * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
+
 2013-07-08  Magnus Henoch <address@hidden> (tiny change)
 
        * configure.ac (HAVE_IMAGEMAGICK): Check on NS also (Bug#14798).

=== modified file 'admin/ChangeLog'
--- a/admin/ChangeLog   2013-07-07 18:00:14 +0000
+++ b/admin/ChangeLog   2013-07-09 07:04:48 +0000
@@ -1,3 +1,8 @@
+2013-07-09  Paul Eggert  <address@hidden>
+
+       Handle error numbers a bit more reliably.
+       * merge-gnulib (GNULIB_MODULES): Remove ignore-value.
+
 2013-07-07  Paul Eggert  <address@hidden>
 
        Make file descriptors close-on-exec when possible (Bug#14803).

=== modified file 'admin/merge-gnulib'
--- a/admin/merge-gnulib        2013-07-07 18:00:14 +0000
+++ b/admin/merge-gnulib        2013-07-09 07:04:48 +0000
@@ -31,7 +31,7 @@
   dtoastr dtotimespec dup2 environ execinfo faccessat
   fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync
   getloadavg getopt-gnu gettime gettimeofday
-  ignore-value intprops largefile lstat
+  intprops largefile lstat
   manywarnings memrchr mktime
   pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat
   sig2str socklen stat-time stdalign stdarg stdbool stdio

=== modified file 'lib/gnulib.mk'
--- a/lib/gnulib.mk     2013-07-07 18:00:14 +0000
+++ b/lib/gnulib.mk     2013-07-09 07:04:48 +0000
@@ -21,7 +21,7 @@
 # the same distribution terms as the rest of that program.
 #
 # Generated by gnulib-tool.
-# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib 
--m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux 
--avoid=binary-io --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat 
--avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open 
--avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd 
--avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib 
--makefile-name=gnulib.mk --conditional-dependencies --no-libtool 
--macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat 
close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr 
dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir 
filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday ignore-value 
intprops largefile lstat manywarnings memrchr mktime pipe2 pselect 
pthread_sigmask putenv qacl readlink readlinkat sig2str socklen stat-time 
stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat 
sys_time time timer-time timespec-add timespec-sub unsetenv utimens warnings
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib 
--m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux 
--avoid=binary-io --avoid=close --avoid=dup --avoid=fchdir --avoid=fstat 
--avoid=malloc-posix --avoid=msvc-inval --avoid=msvc-nothrow --avoid=open 
--avoid=openat-die --avoid=opendir --avoid=raise --avoid=save-cwd 
--avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib 
--makefile-name=gnulib.mk --conditional-dependencies --no-libtool 
--macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat 
close-stream crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr 
dtotimespec dup2 environ execinfo faccessat fcntl fcntl-h fdatasync fdopendir 
filemode fstatat fsync getloadavg getopt-gnu gettime gettimeofday intprops 
largefile lstat manywarnings memrchr mktime pipe2 pselect pthread_sigmask 
putenv qacl readlink readlinkat sig2str socklen stat-time stdalign stdarg 
stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time 
timer-time timespec-add timespec-sub unsetenv utimens warnings
 
 
 MOSTLYCLEANFILES += core *.stackdump
@@ -485,13 +485,6 @@
 
 ## end   gnulib module group-member
 
-## begin gnulib module ignore-value
-
-
-EXTRA_DIST += ignore-value.h
-
-## end   gnulib module ignore-value
-
 ## begin gnulib module intprops
 
 

=== removed file 'lib/ignore-value.h'
--- a/lib/ignore-value.h        2013-07-01 23:43:19 +0000
+++ b/lib/ignore-value.h        1970-01-01 00:00:00 +0000
@@ -1,48 +0,0 @@
-/* ignore a function return without a compiler warning
-
-   Copyright (C) 2008-2013 Free Software Foundation, Inc.
-
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* Written by Jim Meyering, Eric Blake and Pádraig Brady.  */
-
-/* Use "ignore_value" to avoid a warning when using a function declared with
-   gcc's warn_unused_result attribute, but for which you really do want to
-   ignore the result.  Traditionally, people have used a "(void)" cast to
-   indicate that a function's return value is deliberately unused.  However,
-   if the function is declared with __attribute__((warn_unused_result)),
-   gcc issues a warning even with the cast.
-
-   Caution: most of the time, you really should heed gcc's warning, and
-   check the return value.  However, in those exceptional cases in which
-   you're sure you know what you're doing, use this function.
-
-   For the record, here's one of the ignorable warnings:
-   "copy.c:233: warning: ignoring return value of 'fchown',
-   declared with attribute warn_unused_result".  */
-
-#ifndef _GL_IGNORE_VALUE_H
-#define _GL_IGNORE_VALUE_H
-
-/* The __attribute__((__warn_unused_result__)) feature
-   is available in gcc versions 3.4 and newer,
-   while the typeof feature has been available since 2.7 at least.  */
-#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__)
-# define ignore_value(x) \
-    (__extension__ ({ __typeof__ (x) __x = (x); (void) __x; }))
-#else
-# define ignore_value(x) ((void) (x))
-#endif
-
-#endif

=== modified file 'm4/gnulib-comp.m4'
--- a/m4/gnulib-comp.m4 2013-07-07 18:00:14 +0000
+++ b/m4/gnulib-comp.m4 2013-07-09 07:04:48 +0000
@@ -80,7 +80,6 @@
   # Code from module gettime:
   # Code from module gettimeofday:
   # Code from module group-member:
-  # Code from module ignore-value:
   # Code from module include_next:
   # Code from module intprops:
   # Code from module inttypes-incomplete:
@@ -798,7 +797,6 @@
   lib/gettime.c
   lib/gettimeofday.c
   lib/group-member.c
-  lib/ignore-value.h
   lib/intprops.h
   lib/inttypes.in.h
   lib/lstat.c

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-07-08 13:26:13 +0000
+++ b/src/ChangeLog     2013-07-09 07:04:48 +0000
@@ -1,3 +1,34 @@
+2013-07-09  Paul Eggert  <address@hidden>
+
+       Handle errno and exit status a bit more carefully.
+       * callproc.c (child_setup) [!DOS_NT]: Don't try to stuff an error
+       number into an exit status.  Instead, use EXIT_CANCELED.
+       (child_setup) [!MSDOS]: Avoid possible deadlock with vfork.
+       * callproc.c (relocate_fd):
+       * emacs.c (close_output_streams, main):
+       * process.c (create_process):
+       * sysdep.c (sys_subshell) [!DOS_NT || !WINDOWSNT]:
+       Use emacs_perror for simplicity.
+       * callproc.c (relocate_fd, main):
+       * sysdep.c (sys_subshell):
+       Exit with EXIT_CANCELED etc., not 1, when exec setup fails.
+       (shut_down_emacs): Use emacs_write, not write.
+       * emacs.c, sysdep.c: Don't include <ignore-value.h>.
+       * fileio.c (Fcopy_file, e_write):
+       * nsterm.m (ns_select):
+       * process.c (send_process):
+       * sound.c (vox_write):
+       Use emacs_write_sig, not emacs_write.
+       * lisp.h (emacs_write_sig, emacs_perror): New decls.
+       * process.h (EXIT_CANCELED), EXIT_CANNOT_INVOKE, EXIT_ENOENT):
+       New constants.
+       * sysdep.c (emacs_backtrace): Use emacs_write, not ignore_value
+       of write.
+       (emacs_full_write): New function.
+       (emacs_write): Rewrite to use it.
+       (emacswrite_sig, emacs_perror): New functions.
+       * xrdb.c (fatal): Don't invoke perror, since errno might be garbage.
+
 2013-07-08  Magnus Henoch <address@hidden> (tiny change).
 
        * image.c (imagemagick_load_image): Do not use MagickExportImagePixels

=== modified file 'src/callproc.c'
--- a/src/callproc.c    2013-07-07 18:48:16 +0000
+++ b/src/callproc.c    2013-07-09 07:04:48 +0000
@@ -1221,7 +1221,7 @@
        are changed between the check and this chdir, but we should
        at least check.  */
     if (chdir (temp) < 0)
-      _exit (errno);
+      _exit (EXIT_CANCELED);
 #else /* DOS_NT */
     /* Get past the drive letter, so that d:/ is left alone.  */
     if (i > 2 && IS_DEVICE_SEP (temp[1]) && IS_DIRECTORY_SEP (temp[2]))
@@ -1366,10 +1366,12 @@
 
   execve (new_argv[0], new_argv, env);
 
-  emacs_write (1, "Can't exec program: ", 20);
-  emacs_write (1, new_argv[0], strlen (new_argv[0]));
-  emacs_write (1, "\n", 1);
-  _exit (1);
+  /* Don't output the program name here, as it can be arbitrarily long,
+     and a long write from a vforked child to its parent can cause a
+     deadlock.  */
+  emacs_perror ("child process");
+
+  _exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
 
 #else /* MSDOS */
   pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
@@ -1395,13 +1397,8 @@
       int new = fcntl (fd, F_DUPFD_CLOEXEC, minfd);
       if (new == -1)
        {
-         const char *message_1 = "Error while setting up child: ";
-         const char *errmessage = strerror (errno);
-         const char *message_2 = "\n";
-         emacs_write (2, message_1, strlen (message_1));
-         emacs_write (2, errmessage, strlen (errmessage));
-         emacs_write (2, message_2, strlen (message_2));
-         _exit (1);
+         emacs_perror ("while setting up child");
+         _exit (EXIT_CANCELED);
        }
       emacs_close (fd);
       return new;

=== modified file 'src/emacs.c'
--- a/src/emacs.c       2013-07-07 18:48:16 +0000
+++ b/src/emacs.c       2013-07-09 07:04:48 +0000
@@ -28,7 +28,6 @@
 #include <unistd.h>
 
 #include <close-stream.h>
-#include <ignore-value.h>
 
 #include "lisp.h"
 
@@ -646,9 +645,7 @@
 {
   if (close_stream (stdout) != 0)
     {
-      fprintf (stderr, "Write error to standard output: %s\n",
-              strerror (errno));
-      fflush (stderr);
+      emacs_perror ("Write error to standard output");
       _exit (EXIT_FAILURE);
     }
 
@@ -789,7 +786,7 @@
       execvp (argv[0], argv);
 
       /* If the exec fails, try to dump anyway.  */
-      perror ("execvp");
+      emacs_perror (argv[0]);
     }
 #endif /* HAVE_PERSONALITY_LINUX32 */
 
@@ -1020,8 +1017,8 @@
        }
       if (f < 0)
        {
-         fprintf (stderr, "Cannot fork!\n");
-         exit (1);
+         emacs_perror ("fork");
+         exit (EXIT_CANCELED);
        }
 
 #ifdef DAEMON_MUST_EXEC
@@ -1038,14 +1035,14 @@
            if (! (0 <= fdStrlen && fdStrlen < sizeof fdStr))
               {
                 fprintf (stderr, "daemon: child name too long\n");
-                exit (1);
+                exit (EXIT_CANNOT_INVOKE);
               }
 
             argv[skip_args] = fdStr;
 
             execvp (argv[0], argv);
-            fprintf (stderr, "emacs daemon: exec failed: %d\n", errno);
-            exit (1);
+           emacs_perror (argv[0]);
+           exit (errno == ENOENT : EXIT_ENOENT : EXIT_CANNOT_INVOKE);
           }
 
         /* In exec'd: parse special dname into pipe and name info. */
@@ -1053,7 +1050,7 @@
             || strlen (dname_arg) < 1 || strlen (dname_arg) > 70)
           {
             fprintf (stderr, "emacs daemon: daemon name absent or too long\n");
-            exit (1);
+            exit (EXIT_CANNOT_INVOKE);
           }
         dname_arg2[0] = '\0';
         sscanf (dname_arg, "\n%d,%d\n%s", &(daemon_pipe[0]), &(daemon_pipe[1]),
@@ -1916,8 +1913,8 @@
            char buf[sizeof format - 2 + INT_STRLEN_BOUND (int)];
            int buflen = sprintf (buf, format, sig);
            char const *sig_desc = safe_strsignal (sig);
-           ignore_value (write (STDERR_FILENO, buf, buflen));
-           ignore_value (write (STDERR_FILENO, sig_desc, strlen (sig_desc)));
+           emacs_write (STDERR_FILENO, buf, buflen);
+           emacs_write (STDERR_FILENO, sig_desc, strlen (sig_desc));
          }
       }
   }

=== modified file 'src/fileio.c'
--- a/src/fileio.c      2013-07-06 02:40:50 +0000
+++ b/src/fileio.c      2013-07-09 07:04:48 +0000
@@ -2122,7 +2122,7 @@
   immediate_quit = 1;
   QUIT;
   while ((n = emacs_read (ifd, buf, sizeof buf)) > 0)
-    if (emacs_write (ofd, buf, n) != n)
+    if (emacs_write_sig (ofd, buf, n) != n)
       report_file_error ("I/O error", Fcons (newname, Qnil));
   immediate_quit = 0;
 
@@ -5317,12 +5317,10 @@
 
       if (coding->produced > 0)
        {
-         coding->produced
-           -= emacs_write (desc,
-                           STRINGP (coding->dst_object)
-                           ? SSDATA (coding->dst_object)
-                           : (char *) BYTE_POS_ADDR (coding->dst_pos_byte),
-                           coding->produced);
+         char *buf = (STRINGP (coding->dst_object)
+                      ? SSDATA (coding->dst_object)
+                      : (char *) BYTE_POS_ADDR (coding->dst_pos_byte));
+         coding->produced -= emacs_write_sig (desc, buf, coding->produced);
 
          if (coding->produced)
            return 0;

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2013-07-09 05:04:45 +0000
+++ b/src/lisp.h        2013-07-09 07:04:48 +0000
@@ -3998,6 +3998,7 @@
 extern void syms_of_process (void);
 extern void setup_process_coding_systems (Lisp_Object);
 
+/* Defined in callproc.c.  */
 #ifndef DOS_NT
  _Noreturn
 #endif
@@ -4090,6 +4091,8 @@
 extern int emacs_close (int);
 extern ptrdiff_t emacs_read (int, char *, ptrdiff_t);
 extern ptrdiff_t emacs_write (int, const char *, ptrdiff_t);
+extern ptrdiff_t emacs_write_sig (int, char const *, ptrdiff_t);
+extern void emacs_perror (char const *);
 
 extern void unlock_all_files (void);
 extern void lock_file (Lisp_Object);

=== modified file 'src/nsterm.m'
--- a/src/nsterm.m      2013-07-07 18:00:14 +0000
+++ b/src/nsterm.m      2013-07-09 07:04:48 +0000
@@ -3603,7 +3603,7 @@
 
       /* Inform fd_handler that select should be called */
       c = 'g';
-      emacs_write (selfds[1], &c, 1);
+      emacs_write_sig (selfds[1], &c, 1);
     }
   else if (nr == 0 && timeout)
     {
@@ -3636,7 +3636,7 @@
   if (nr > 0 && readfds)
     {
       c = 's';
-      emacs_write (selfds[1], &c, 1);
+      emacs_write_sig (selfds[1], &c, 1);
     }
   unblock_input ();
 

=== modified file 'src/process.c'
--- a/src/process.c     2013-07-07 23:22:43 +0000
+++ b/src/process.c     2013-07-09 07:04:48 +0000
@@ -1752,7 +1752,7 @@
          tcgetattr (xforkin, &t);
          t.c_lflag = LDISC1;
          if (tcsetattr (xforkin, TCSANOW, &t) < 0)
-           emacs_write (1, "create_process/tcsetattr LDISC1 failed\n", 39);
+           emacs_perror ("create_process/tcsetattr LDISC1");
        }
 #else
 #if defined (NTTYDISC) && defined (TIOCSETD)
@@ -1799,10 +1799,8 @@
 
          if (xforkin < 0)
            {
-             emacs_write (1, "Couldn't open the pty terminal ", 31);
-             emacs_write (1, pty_name, strlen (pty_name));
-             emacs_write (1, "\n", 1);
-             _exit (1);
+             emacs_perror (pty_name);
+             _exit (EXIT_CANCELED);
            }
 
        }
@@ -5503,7 +5501,7 @@
                written = emacs_gnutls_write (p, cur_buf, cur_len);
              else
 #endif
-               written = emacs_write (outfd, cur_buf, cur_len);
+               written = emacs_write_sig (outfd, cur_buf, cur_len);
              rv = (written ? 0 : -1);
 #ifdef ADAPTIVE_READ_BUFFERING
              if (p->read_output_delay > 0

=== modified file 'src/process.h'
--- a/src/process.h     2013-06-27 14:47:52 +0000
+++ b/src/process.h     2013-07-09 07:04:48 +0000
@@ -198,6 +198,14 @@
 extern Lisp_Object QCbytesize, QCstopbits, QCparity, Qodd, Qeven;
 extern Lisp_Object QCflowcontrol, Qhw, Qsw, QCsummary;
 
+/* Exit statuses for GNU programs that exec other programs.  */
+enum
+{
+  EXIT_CANCELED = 125, /* Internal error prior to exec attempt.  */
+  EXIT_CANNOT_INVOKE = 126, /* Program located, but not usable.  */
+  EXIT_ENOENT = 127 /* Could not find program to exec.  */
+};
+
 /* Defined in callproc.c.  */
 
 extern void block_child_signal (void);

=== modified file 'src/sound.c'
--- a/src/sound.c       2013-06-19 14:20:26 +0000
+++ b/src/sound.c       2013-07-09 07:04:48 +0000
@@ -879,7 +879,7 @@
 static void
 vox_write (struct sound_device *sd, const char *buffer, ptrdiff_t nbytes)
 {
-  if (emacs_write (sd->fd, buffer, nbytes) != nbytes)
+  if (emacs_write_sig (sd->fd, buffer, nbytes) != nbytes)
     sound_perror ("Error writing to sound device");
 }
 

=== modified file 'src/sysdep.c'
--- a/src/sysdep.c      2013-07-07 18:00:14 +0000
+++ b/src/sysdep.c      2013-07-09 07:04:48 +0000
@@ -31,7 +31,6 @@
 #include <unistd.h>
 
 #include <c-ctype.h>
-#include <ignore-value.h>
 #include <utimens.h>
 
 #include "lisp.h"
@@ -538,8 +537,8 @@
       if (str && chdir ((char *) str) != 0)
        {
 #ifndef DOS_NT
-         ignore_value (write (1, "Can't chdir\n", 12));
-         _exit (1);
+         emacs_perror ((char *) str);
+         _exit (EXIT_CANCELED);
 #endif
        }
 
@@ -570,8 +569,8 @@
        write (1, "Can't execute subshell", 22);
 #else   /* not WINDOWSNT */
       execlp (sh, sh, (char *) 0);
-      ignore_value (write (1, "Can't execute subshell", 22));
-      _exit (1);
+      emacs_perror (sh);
+      _exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
 #endif  /* not WINDOWSNT */
 #endif /* not MSDOS */
     }
@@ -2134,10 +2133,10 @@
 
   if (npointers)
     {
-      ignore_value (write (STDERR_FILENO, "\nBacktrace:\n", 12));
+      emacs_write (STDERR_FILENO, "\nBacktrace:\n", 12);
       backtrace_symbols_fd (buffer, npointers, STDERR_FILENO);
       if (bounded_limit < npointers)
-       ignore_value (write (STDERR_FILENO, "...\n", 4));
+       emacs_write (STDERR_FILENO, "...\n", 4);
     }
 }
 
@@ -2246,27 +2245,26 @@
 }
 
 /* Write to FILEDES from a buffer BUF with size NBYTE, retrying if interrupted
-   or if a partial write occurs.  Return the number of bytes written, setting
+   or if a partial write occurs.  If interrupted, process pending
+   signals if PROCESS SIGNALS.  Return the number of bytes written, setting
    errno if this is less than NBYTE.  */
-ptrdiff_t
-emacs_write (int fildes, const char *buf, ptrdiff_t nbyte)
+static ptrdiff_t
+emacs_full_write (int fildes, char const *buf, ptrdiff_t nbyte,
+                 bool process_signals)
 {
-  ssize_t rtnval;
-  ptrdiff_t bytes_written;
-
-  bytes_written = 0;
+  ptrdiff_t bytes_written = 0;
 
   while (nbyte > 0)
     {
-      rtnval = write (fildes, buf, min (nbyte, MAX_RW_COUNT));
+      ssize_t n = write (fildes, buf, min (nbyte, MAX_RW_COUNT));
 
-      if (rtnval < 0)
+      if (n < 0)
        {
          if (errno == EINTR)
            {
              /* I originally used `QUIT' but that might causes files to
                 be truncated if you hit C-g in the middle of it.  --Stef  */
-             if (pending_signals)
+             if (process_signals && pending_signals)
                process_pending_signals ();
              continue;
            }
@@ -2274,12 +2272,57 @@
            break;
        }
 
-      buf += rtnval;
-      nbyte -= rtnval;
-      bytes_written += rtnval;
-    }
-
-  return (bytes_written);
+      buf += n;
+      nbyte -= n;
+      bytes_written += n;
+    }
+
+  return bytes_written;
+}
+
+/* Write to FILEDES from a buffer BUF with size NBYTE, retrying if
+   interrupted or if a partial write occurs.  Return the number of
+   bytes written, setting errno if this is less than NBYTE.  */
+ptrdiff_t
+emacs_write (int fildes, char const *buf, ptrdiff_t nbyte)
+{
+  return emacs_full_write (fildes, buf, nbyte, 0);
+}
+
+/* Like emacs_write, but also process pending signals if interrupted.  */
+ptrdiff_t
+emacs_write_sig (int fildes, char const *buf, ptrdiff_t nbyte)
+{
+  return emacs_full_write (fildes, buf, nbyte, 1);
+}
+
+/* Write a diagnostic to standard error that contains MESSAGE and a
+   string derived from errno.  Preserve errno.  Do not buffer stderr.
+   Do not process pending signals if interrupted.  */
+void
+emacs_perror (char const *message)
+{
+  int err = errno;
+  char const *error_string = strerror (err);
+  char const *command = (initial_argv && initial_argv[0]
+                        ? initial_argv[0] : "emacs");
+  /* Write it out all at once, if it's short; this is less likely to
+     be interleaved with other output.  */
+  char buf[BUFSIZ];
+  int nbytes = snprintf (buf, sizeof buf, "%s: %s: %s\n",
+                        command, message, error_string);
+  if (0 <= nbytes && nbytes < BUFSIZ)
+    emacs_write (STDERR_FILENO, buf, nbytes);
+  else
+    {
+      emacs_write (STDERR_FILENO, command, strlen (command));
+      emacs_write (STDERR_FILENO, ": ", 2);
+      emacs_write (STDERR_FILENO, message, strlen (message));
+      emacs_write (STDERR_FILENO, ": ", 2);
+      emacs_write (STDERR_FILENO, error_string, strlen (error_string));
+      emacs_write (STDERR_FILENO, "\n", 1);
+    }
+  errno = err;
 }
 
 /* Return a struct timeval that is roughly equivalent to T.

=== modified file 'src/xrdb.c'
--- a/src/xrdb.c        2013-01-02 16:13:04 +0000
+++ b/src/xrdb.c        2013-07-09 07:04:48 +0000
@@ -634,10 +634,7 @@
 static void
 fatal (char *msg, char *prog)
 {
-  if (errno)
-    perror (prog);
-
-  (void) fprintf (stderr, msg, prog);
+  fprintf (stderr, msg, prog);
   exit (1);
 }
 


reply via email to

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