diff options
| author | Paul Eggert | 2012-11-03 11:54:17 -0700 |
|---|---|---|
| committer | Paul Eggert | 2012-11-03 11:54:17 -0700 |
| commit | 7ccfb720b477df05042729e0e300bae5922f5120 (patch) | |
| tree | d5bfded71b48dfefbc4e3334c0ae586de29ab7bc /src | |
| parent | 376a8e83bb3438f77dadf2d9910ef7baabcc82c2 (diff) | |
| download | emacs-7ccfb720b477df05042729e0e300bae5922f5120.tar.gz emacs-7ccfb720b477df05042729e0e300bae5922f5120.zip | |
Fix data-loss with --batch.
* admin/merge-gnulib (GNULIB_MODULES): Add close-stream.
* lib/close-stream.c, lib/close-stream.h, lib/fpending.c
* lib/fpending.h, m4/close-stream.m4, m4/fpending.m4:
New files, from gnulib.
* lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate.
* src/emacs.c: Include <close-stream.h>.
(close_output_streams): New function.
(main): Pass it to atexit, so that Emacs closes stdout and stderr
and handles errors appropriately.
(Fkill_emacs): Don't worry about flushing, as close_output_stream
does that now.
Fixes: debbugs:9574
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/emacs.c | 21 |
2 files changed, 27 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 2f040accd9a..be10016fc33 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,13 @@ | |||
| 1 | 2012-11-03 Paul Eggert <eggert@cs.ucla.edu> | 1 | 2012-11-03 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 2 | ||
| 3 | Fix data-loss with --batch (Bug#9574). | ||
| 4 | * emacs.c: Include <close-stream.h>. | ||
| 5 | (close_output_streams): New function. | ||
| 6 | (main): Pass it to atexit, so that Emacs closes stdout and stderr | ||
| 7 | and handles errors appropriately. | ||
| 8 | (Fkill_emacs): Don't worry about flushing, as close_output_stream | ||
| 9 | does that now. | ||
| 10 | |||
| 3 | Fix a race condition that causes Emacs to mess up glib (Bug#8855). | 11 | Fix a race condition that causes Emacs to mess up glib (Bug#8855). |
| 4 | The symptom is a diagnostic "GLib-WARNING **: In call to | 12 | The symptom is a diagnostic "GLib-WARNING **: In call to |
| 5 | g_spawn_sync(), exit status of a child process was requested but | 13 | g_spawn_sync(), exit status of a child process was requested but |
diff --git a/src/emacs.c b/src/emacs.c index 98e3f11f0cb..6588bcd78b1 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -27,6 +27,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 27 | #include <sys/file.h> | 27 | #include <sys/file.h> |
| 28 | #include <unistd.h> | 28 | #include <unistd.h> |
| 29 | 29 | ||
| 30 | #include <close-stream.h> | ||
| 30 | #include <ignore-value.h> | 31 | #include <ignore-value.h> |
| 31 | 32 | ||
| 32 | #include "lisp.h" | 33 | #include "lisp.h" |
| @@ -675,6 +676,22 @@ void (*__malloc_initialize_hook) (void) EXTERNALLY_VISIBLE = malloc_initialize_h | |||
| 675 | 676 | ||
| 676 | #endif /* DOUG_LEA_MALLOC */ | 677 | #endif /* DOUG_LEA_MALLOC */ |
| 677 | 678 | ||
| 679 | /* Close standard output and standard error, reporting any write | ||
| 680 | errors as best we can. This is intended for use with atexit. */ | ||
| 681 | static void | ||
| 682 | close_output_streams (void) | ||
| 683 | { | ||
| 684 | if (close_stream (stdout) != 0) | ||
| 685 | { | ||
| 686 | fprintf (stderr, "Write error to standard output: %s\n", | ||
| 687 | emacs_strerror (errno)); | ||
| 688 | fflush (stderr); | ||
| 689 | _exit (EXIT_FAILURE); | ||
| 690 | } | ||
| 691 | |||
| 692 | if (close_stream (stderr) != 0) | ||
| 693 | _exit (EXIT_FAILURE); | ||
| 694 | } | ||
| 678 | 695 | ||
| 679 | /* ARGSUSED */ | 696 | /* ARGSUSED */ |
| 680 | int | 697 | int |
| @@ -890,6 +907,8 @@ main (int argc, char **argv) | |||
| 890 | if (do_initial_setlocale) | 907 | if (do_initial_setlocale) |
| 891 | setlocale (LC_ALL, ""); | 908 | setlocale (LC_ALL, ""); |
| 892 | 909 | ||
| 910 | atexit (close_output_streams); | ||
| 911 | |||
| 893 | inhibit_window_system = 0; | 912 | inhibit_window_system = 0; |
| 894 | 913 | ||
| 895 | /* Handle the -t switch, which specifies filename to use as terminal. */ | 914 | /* Handle the -t switch, which specifies filename to use as terminal. */ |
| @@ -1867,8 +1886,6 @@ all of which are called before Emacs is actually killed. */) | |||
| 1867 | exit_code = (XINT (arg) < 0 | 1886 | exit_code = (XINT (arg) < 0 |
| 1868 | ? XINT (arg) | INT_MIN | 1887 | ? XINT (arg) | INT_MIN |
| 1869 | : XINT (arg) & INT_MAX); | 1888 | : XINT (arg) & INT_MAX); |
| 1870 | else if (noninteractive && (fflush (stdout) || ferror (stdout))) | ||
| 1871 | exit_code = EXIT_FAILURE; | ||
| 1872 | else | 1889 | else |
| 1873 | exit_code = EXIT_SUCCESS; | 1890 | exit_code = EXIT_SUCCESS; |
| 1874 | exit (exit_code); | 1891 | exit (exit_code); |