mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-02-03 22:20:52 -08:00
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.
This commit is contained in:
parent
584ee3fc72
commit
4ebbdd6712
17 changed files with 151 additions and 125 deletions
|
|
@ -1,3 +1,9 @@
|
|||
2013-07-09 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
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 <magnus.henoch@gmail.com> (tiny change)
|
||||
|
||||
* configure.ac (HAVE_IMAGEMAGICK): Check on NS also (Bug#14798).
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
2013-07-09 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Handle error numbers a bit more reliably.
|
||||
* merge-gnulib (GNULIB_MODULES): Remove ignore-value.
|
||||
|
||||
2013-07-07 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Make file descriptors close-on-exec when possible (Bug#14803).
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ GNULIB_MODULES='
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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 @@ EXTRA_libgnu_a_SOURCES += group-member.c
|
|||
|
||||
## end gnulib module group-member
|
||||
|
||||
## begin gnulib module ignore-value
|
||||
|
||||
|
||||
EXTRA_DIST += ignore-value.h
|
||||
|
||||
## end gnulib module ignore-value
|
||||
|
||||
## begin gnulib module intprops
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -80,7 +80,6 @@ AC_DEFUN([gl_EARLY],
|
|||
# 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 @@ AC_DEFUN([gl_FILE_LIST], [
|
|||
lib/gettime.c
|
||||
lib/gettimeofday.c
|
||||
lib/group-member.c
|
||||
lib/ignore-value.h
|
||||
lib/intprops.h
|
||||
lib/inttypes.in.h
|
||||
lib/lstat.c
|
||||
|
|
|
|||
|
|
@ -1,3 +1,34 @@
|
|||
2013-07-09 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
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 <magnus.henoch@gmail.com> (tiny change).
|
||||
|
||||
* image.c (imagemagick_load_image): Do not use MagickExportImagePixels
|
||||
|
|
|
|||
|
|
@ -1221,7 +1221,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
|
|||
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 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
|
|||
|
||||
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 @@ relocate_fd (int fd, int minfd)
|
|||
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;
|
||||
|
|
|
|||
23
src/emacs.c
23
src/emacs.c
|
|
@ -28,7 +28,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include <unistd.h>
|
||||
|
||||
#include <close-stream.h>
|
||||
#include <ignore-value.h>
|
||||
|
||||
#include "lisp.h"
|
||||
|
||||
|
|
@ -646,9 +645,7 @@ close_output_streams (void)
|
|||
{
|
||||
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 @@ main (int argc, char **argv)
|
|||
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 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
}
|
||||
if (f < 0)
|
||||
{
|
||||
fprintf (stderr, "Cannot fork!\n");
|
||||
exit (1);
|
||||
emacs_perror ("fork");
|
||||
exit (EXIT_CANCELED);
|
||||
}
|
||||
|
||||
#ifdef DAEMON_MUST_EXEC
|
||||
|
|
@ -1038,14 +1035,14 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
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 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
|| 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 @@ shut_down_emacs (int sig, Lisp_Object stuff)
|
|||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/fileio.c
12
src/fileio.c
|
|
@ -2122,7 +2122,7 @@ entries (depending on how Emacs was built). */)
|
|||
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 @@ e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end,
|
|||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -3998,6 +3998,7 @@ extern void init_process_emacs (void);
|
|||
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_open (const char *, int, int);
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -3603,7 +3603,7 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
|
|||
|
||||
/* 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 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
|
|||
if (nr > 0 && readfds)
|
||||
{
|
||||
c = 's';
|
||||
emacs_write (selfds[1], &c, 1);
|
||||
emacs_write_sig (selfds[1], &c, 1);
|
||||
}
|
||||
unblock_input ();
|
||||
|
||||
|
|
|
|||
|
|
@ -1752,7 +1752,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
|
|||
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 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
|
|||
|
||||
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 @@ send_process (Lisp_Object proc, const char *buf, ptrdiff_t len,
|
|||
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
|
||||
|
|
|
|||
|
|
@ -198,6 +198,14 @@ extern Lisp_Object QCspeed;
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -879,7 +879,7 @@ vox_init (struct sound_device *sd)
|
|||
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");
|
||||
}
|
||||
|
||||
|
|
|
|||
85
src/sysdep.c
85
src/sysdep.c
|
|
@ -31,7 +31,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include <unistd.h>
|
||||
|
||||
#include <c-ctype.h>
|
||||
#include <ignore-value.h>
|
||||
#include <utimens.h>
|
||||
|
||||
#include "lisp.h"
|
||||
|
|
@ -538,8 +537,8 @@ sys_subshell (void)
|
|||
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 @@ sys_subshell (void)
|
|||
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 @@ emacs_backtrace (int backtrace_limit)
|
|||
|
||||
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 @@ emacs_read (int fildes, char *buf, ptrdiff_t nbyte)
|
|||
}
|
||||
|
||||
/* 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 @@ emacs_write (int fildes, const char *buf, ptrdiff_t nbyte)
|
|||
break;
|
||||
}
|
||||
|
||||
buf += rtnval;
|
||||
nbyte -= rtnval;
|
||||
bytes_written += rtnval;
|
||||
buf += n;
|
||||
nbyte -= n;
|
||||
bytes_written += n;
|
||||
}
|
||||
|
||||
return (bytes_written);
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -634,10 +634,7 @@ member (char *elt, List list)
|
|||
static void
|
||||
fatal (char *msg, char *prog)
|
||||
{
|
||||
if (errno)
|
||||
perror (prog);
|
||||
|
||||
(void) fprintf (stderr, msg, prog);
|
||||
fprintf (stderr, msg, prog);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue