diff options
| author | Paul Eggert | 2013-07-09 00:04:48 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-07-09 00:04:48 -0700 |
| commit | 4ebbdd6712c1966406b40d2673464949775cbd7a (patch) | |
| tree | 08667dd241629ca55c2c30ce19777bd7ec107cfa /src/sysdep.c | |
| parent | 584ee3fc72260acb3cc83f4d1a047b733a08ca17 (diff) | |
| download | emacs-4ebbdd6712c1966406b40d2673464949775cbd7a.tar.gz emacs-4ebbdd6712c1966406b40d2673464949775cbd7a.zip | |
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.
Diffstat (limited to 'src/sysdep.c')
| -rw-r--r-- | src/sysdep.c | 85 |
1 files changed, 64 insertions, 21 deletions
diff --git a/src/sysdep.c b/src/sysdep.c index faca7fae461..6346b0bbfcd 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -31,7 +31,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 31 | #include <unistd.h> | 31 | #include <unistd.h> |
| 32 | 32 | ||
| 33 | #include <c-ctype.h> | 33 | #include <c-ctype.h> |
| 34 | #include <ignore-value.h> | ||
| 35 | #include <utimens.h> | 34 | #include <utimens.h> |
| 36 | 35 | ||
| 37 | #include "lisp.h" | 36 | #include "lisp.h" |
| @@ -538,8 +537,8 @@ sys_subshell (void) | |||
| 538 | if (str && chdir ((char *) str) != 0) | 537 | if (str && chdir ((char *) str) != 0) |
| 539 | { | 538 | { |
| 540 | #ifndef DOS_NT | 539 | #ifndef DOS_NT |
| 541 | ignore_value (write (1, "Can't chdir\n", 12)); | 540 | emacs_perror ((char *) str); |
| 542 | _exit (1); | 541 | _exit (EXIT_CANCELED); |
| 543 | #endif | 542 | #endif |
| 544 | } | 543 | } |
| 545 | 544 | ||
| @@ -570,8 +569,8 @@ sys_subshell (void) | |||
| 570 | write (1, "Can't execute subshell", 22); | 569 | write (1, "Can't execute subshell", 22); |
| 571 | #else /* not WINDOWSNT */ | 570 | #else /* not WINDOWSNT */ |
| 572 | execlp (sh, sh, (char *) 0); | 571 | execlp (sh, sh, (char *) 0); |
| 573 | ignore_value (write (1, "Can't execute subshell", 22)); | 572 | emacs_perror (sh); |
| 574 | _exit (1); | 573 | _exit (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE); |
| 575 | #endif /* not WINDOWSNT */ | 574 | #endif /* not WINDOWSNT */ |
| 576 | #endif /* not MSDOS */ | 575 | #endif /* not MSDOS */ |
| 577 | } | 576 | } |
| @@ -2134,10 +2133,10 @@ emacs_backtrace (int backtrace_limit) | |||
| 2134 | 2133 | ||
| 2135 | if (npointers) | 2134 | if (npointers) |
| 2136 | { | 2135 | { |
| 2137 | ignore_value (write (STDERR_FILENO, "\nBacktrace:\n", 12)); | 2136 | emacs_write (STDERR_FILENO, "\nBacktrace:\n", 12); |
| 2138 | backtrace_symbols_fd (buffer, npointers, STDERR_FILENO); | 2137 | backtrace_symbols_fd (buffer, npointers, STDERR_FILENO); |
| 2139 | if (bounded_limit < npointers) | 2138 | if (bounded_limit < npointers) |
| 2140 | ignore_value (write (STDERR_FILENO, "...\n", 4)); | 2139 | emacs_write (STDERR_FILENO, "...\n", 4); |
| 2141 | } | 2140 | } |
| 2142 | } | 2141 | } |
| 2143 | 2142 | ||
| @@ -2246,27 +2245,26 @@ emacs_read (int fildes, char *buf, ptrdiff_t nbyte) | |||
| 2246 | } | 2245 | } |
| 2247 | 2246 | ||
| 2248 | /* Write to FILEDES from a buffer BUF with size NBYTE, retrying if interrupted | 2247 | /* Write to FILEDES from a buffer BUF with size NBYTE, retrying if interrupted |
| 2249 | or if a partial write occurs. Return the number of bytes written, setting | 2248 | or if a partial write occurs. If interrupted, process pending |
| 2249 | signals if PROCESS SIGNALS. Return the number of bytes written, setting | ||
| 2250 | errno if this is less than NBYTE. */ | 2250 | errno if this is less than NBYTE. */ |
| 2251 | ptrdiff_t | 2251 | static ptrdiff_t |
| 2252 | emacs_write (int fildes, const char *buf, ptrdiff_t nbyte) | 2252 | emacs_full_write (int fildes, char const *buf, ptrdiff_t nbyte, |
| 2253 | bool process_signals) | ||
| 2253 | { | 2254 | { |
| 2254 | ssize_t rtnval; | 2255 | ptrdiff_t bytes_written = 0; |
| 2255 | ptrdiff_t bytes_written; | ||
| 2256 | |||
| 2257 | bytes_written = 0; | ||
| 2258 | 2256 | ||
| 2259 | while (nbyte > 0) | 2257 | while (nbyte > 0) |
| 2260 | { | 2258 | { |
| 2261 | rtnval = write (fildes, buf, min (nbyte, MAX_RW_COUNT)); | 2259 | ssize_t n = write (fildes, buf, min (nbyte, MAX_RW_COUNT)); |
| 2262 | 2260 | ||
| 2263 | if (rtnval < 0) | 2261 | if (n < 0) |
| 2264 | { | 2262 | { |
| 2265 | if (errno == EINTR) | 2263 | if (errno == EINTR) |
| 2266 | { | 2264 | { |
| 2267 | /* I originally used `QUIT' but that might causes files to | 2265 | /* I originally used `QUIT' but that might causes files to |
| 2268 | be truncated if you hit C-g in the middle of it. --Stef */ | 2266 | be truncated if you hit C-g in the middle of it. --Stef */ |
| 2269 | if (pending_signals) | 2267 | if (process_signals && pending_signals) |
| 2270 | process_pending_signals (); | 2268 | process_pending_signals (); |
| 2271 | continue; | 2269 | continue; |
| 2272 | } | 2270 | } |
| @@ -2274,12 +2272,57 @@ emacs_write (int fildes, const char *buf, ptrdiff_t nbyte) | |||
| 2274 | break; | 2272 | break; |
| 2275 | } | 2273 | } |
| 2276 | 2274 | ||
| 2277 | buf += rtnval; | 2275 | buf += n; |
| 2278 | nbyte -= rtnval; | 2276 | nbyte -= n; |
| 2279 | bytes_written += rtnval; | 2277 | bytes_written += n; |
| 2280 | } | 2278 | } |
| 2281 | 2279 | ||
| 2282 | return (bytes_written); | 2280 | return bytes_written; |
| 2281 | } | ||
| 2282 | |||
| 2283 | /* Write to FILEDES from a buffer BUF with size NBYTE, retrying if | ||
| 2284 | interrupted or if a partial write occurs. Return the number of | ||
| 2285 | bytes written, setting errno if this is less than NBYTE. */ | ||
| 2286 | ptrdiff_t | ||
| 2287 | emacs_write (int fildes, char const *buf, ptrdiff_t nbyte) | ||
| 2288 | { | ||
| 2289 | return emacs_full_write (fildes, buf, nbyte, 0); | ||
| 2290 | } | ||
| 2291 | |||
| 2292 | /* Like emacs_write, but also process pending signals if interrupted. */ | ||
| 2293 | ptrdiff_t | ||
| 2294 | emacs_write_sig (int fildes, char const *buf, ptrdiff_t nbyte) | ||
| 2295 | { | ||
| 2296 | return emacs_full_write (fildes, buf, nbyte, 1); | ||
| 2297 | } | ||
| 2298 | |||
| 2299 | /* Write a diagnostic to standard error that contains MESSAGE and a | ||
| 2300 | string derived from errno. Preserve errno. Do not buffer stderr. | ||
| 2301 | Do not process pending signals if interrupted. */ | ||
| 2302 | void | ||
| 2303 | emacs_perror (char const *message) | ||
| 2304 | { | ||
| 2305 | int err = errno; | ||
| 2306 | char const *error_string = strerror (err); | ||
| 2307 | char const *command = (initial_argv && initial_argv[0] | ||
| 2308 | ? initial_argv[0] : "emacs"); | ||
| 2309 | /* Write it out all at once, if it's short; this is less likely to | ||
| 2310 | be interleaved with other output. */ | ||
| 2311 | char buf[BUFSIZ]; | ||
| 2312 | int nbytes = snprintf (buf, sizeof buf, "%s: %s: %s\n", | ||
| 2313 | command, message, error_string); | ||
| 2314 | if (0 <= nbytes && nbytes < BUFSIZ) | ||
| 2315 | emacs_write (STDERR_FILENO, buf, nbytes); | ||
| 2316 | else | ||
| 2317 | { | ||
| 2318 | emacs_write (STDERR_FILENO, command, strlen (command)); | ||
| 2319 | emacs_write (STDERR_FILENO, ": ", 2); | ||
| 2320 | emacs_write (STDERR_FILENO, message, strlen (message)); | ||
| 2321 | emacs_write (STDERR_FILENO, ": ", 2); | ||
| 2322 | emacs_write (STDERR_FILENO, error_string, strlen (error_string)); | ||
| 2323 | emacs_write (STDERR_FILENO, "\n", 1); | ||
| 2324 | } | ||
| 2325 | errno = err; | ||
| 2283 | } | 2326 | } |
| 2284 | 2327 | ||
| 2285 | /* Return a struct timeval that is roughly equivalent to T. | 2328 | /* Return a struct timeval that is roughly equivalent to T. |