aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2016-01-03 15:00:49 -0800
committerPaul Eggert2016-01-03 15:04:07 -0800
commite79b06e6def82fab56a153085bff8223876d5908 (patch)
tree3fa986746456718707c735b0abda48c092945479 /src
parent861022ff5f7b8d6ab53c726e009208eadf4ecd41 (diff)
downloademacs-e79b06e6def82fab56a153085bff8223876d5908.tar.gz
emacs-e79b06e6def82fab56a153085bff8223876d5908.zip
Avoid stdio in SIGINT handler
* admin/merge-gnulib (GNULIB_MODULES): Add ignore-value. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * lib/ignore-value.h: New file, from gnulib. * src/keyboard.c: Include it. (write_stdout, read_stdin): New functions. (handle_interrupt): Use them instead of printf and getchar, and avoid fflush when handling signals.
Diffstat (limited to 'src')
-rw-r--r--src/keyboard.c73
1 files changed, 47 insertions, 26 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index fcafd0bc9a1..6bdfc1aa084 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -64,6 +64,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
64#include <unistd.h> 64#include <unistd.h>
65#include <fcntl.h> 65#include <fcntl.h>
66 66
67#include <ignore-value.h>
68
67#ifdef HAVE_WINDOW_SYSTEM 69#ifdef HAVE_WINDOW_SYSTEM
68#include TERM_HEADER 70#include TERM_HEADER
69#endif /* HAVE_WINDOW_SYSTEM */ 71#endif /* HAVE_WINDOW_SYSTEM */
@@ -10206,6 +10208,21 @@ deliver_interrupt_signal (int sig)
10206 deliver_process_signal (sig, handle_interrupt_signal); 10208 deliver_process_signal (sig, handle_interrupt_signal);
10207} 10209}
10208 10210
10211/* Output MSG directly to standard output, without buffering. Ignore
10212 failures. This is safe in a signal handler. */
10213static void
10214write_stdout (char const *msg)
10215{
10216 ignore_value (write (STDOUT_FILENO, msg, strlen (msg)));
10217}
10218
10219/* Read a byte from stdin, without buffering. Safe in signal handlers. */
10220static int
10221read_stdin (void)
10222{
10223 char c;
10224 return read (STDIN_FILENO, &c, 1) == 1 ? c : EOF;
10225}
10209 10226
10210/* If Emacs is stuck because `inhibit-quit' is true, then keep track 10227/* If Emacs is stuck because `inhibit-quit' is true, then keep track
10211 of the number of times C-g has been requested. If C-g is pressed 10228 of the number of times C-g has been requested. If C-g is pressed
@@ -10242,9 +10259,9 @@ handle_interrupt (bool in_signal_handler)
10242 sigemptyset (&blocked); 10259 sigemptyset (&blocked);
10243 sigaddset (&blocked, SIGINT); 10260 sigaddset (&blocked, SIGINT);
10244 pthread_sigmask (SIG_BLOCK, &blocked, 0); 10261 pthread_sigmask (SIG_BLOCK, &blocked, 0);
10262 fflush (stdout);
10245 } 10263 }
10246 10264
10247 fflush (stdout);
10248 reset_all_sys_modes (); 10265 reset_all_sys_modes ();
10249 10266
10250#ifdef SIGTSTP 10267#ifdef SIGTSTP
@@ -10260,8 +10277,9 @@ handle_interrupt (bool in_signal_handler)
10260 /* Perhaps should really fork an inferior shell? 10277 /* Perhaps should really fork an inferior shell?
10261 But that would not provide any way to get back 10278 But that would not provide any way to get back
10262 to the original shell, ever. */ 10279 to the original shell, ever. */
10263 printf ("No support for stopping a process on this operating system;\n"); 10280 write_stdout ("No support for stopping a process"
10264 printf ("you can continue or abort.\n"); 10281 " on this operating system;\n"
10282 "you can continue or abort.\n");
10265#endif /* not SIGTSTP */ 10283#endif /* not SIGTSTP */
10266#ifdef MSDOS 10284#ifdef MSDOS
10267 /* We must remain inside the screen area when the internal terminal 10285 /* We must remain inside the screen area when the internal terminal
@@ -10272,46 +10290,49 @@ handle_interrupt (bool in_signal_handler)
10272 the code used for auto-saving doesn't cope with the mark bit. */ 10290 the code used for auto-saving doesn't cope with the mark bit. */
10273 if (!gc_in_progress) 10291 if (!gc_in_progress)
10274 { 10292 {
10275 printf ("Auto-save? (y or n) "); 10293 write_stdout ("Auto-save? (y or n) ");
10276 fflush (stdout); 10294 c = read_stdin ();
10277 if (((c = getchar ()) & ~040) == 'Y') 10295 if ((c & 040) == 'Y')
10278 { 10296 {
10279 Fdo_auto_save (Qt, Qnil); 10297 Fdo_auto_save (Qt, Qnil);
10280#ifdef MSDOS 10298#ifdef MSDOS
10281 printf ("\r\nAuto-save done"); 10299 write_stdout ("\r\nAuto-save done");
10282#else /* not MSDOS */ 10300#else
10283 printf ("Auto-save done\n"); 10301 write_stdout ("Auto-save done\n");
10284#endif /* not MSDOS */ 10302#endif
10285 } 10303 }
10286 while (c != '\n') c = getchar (); 10304 while (c != '\n')
10305 c = read_stdin ();
10287 } 10306 }
10288 else 10307 else
10289 { 10308 {
10290 /* During GC, it must be safe to reenable quitting again. */ 10309 /* During GC, it must be safe to reenable quitting again. */
10291 Vinhibit_quit = Qnil; 10310 Vinhibit_quit = Qnil;
10311 write_stdout
10312 (
10292#ifdef MSDOS 10313#ifdef MSDOS
10293 printf ("\r\n"); 10314 "\r\n"
10294#endif /* not MSDOS */ 10315#endif
10295 printf ("Garbage collection in progress; cannot auto-save now\r\n"); 10316 "Garbage collection in progress; cannot auto-save now\r\n"
10296 printf ("but will instead do a real quit after garbage collection ends\r\n"); 10317 "but will instead do a real quit"
10297 fflush (stdout); 10318 " after garbage collection ends\r\n");
10298 } 10319 }
10299 10320
10300#ifdef MSDOS 10321#ifdef MSDOS
10301 printf ("\r\nAbort? (y or n) "); 10322 write_stdout ("\r\nAbort? (y or n) ");
10302#else /* not MSDOS */ 10323#else
10303 printf ("Abort (and dump core)? (y or n) "); 10324 write_stdout ("Abort (and dump core)? (y or n) ");
10304#endif /* not MSDOS */ 10325#endif
10305 fflush (stdout); 10326 c = read_stdin ();
10306 if (((c = getchar ()) & ~040) == 'Y') 10327 if ((c & ~040) == 'Y')
10307 emacs_abort (); 10328 emacs_abort ();
10308 while (c != '\n') c = getchar (); 10329 while (c != '\n')
10330 c = read_stdin ();
10309#ifdef MSDOS 10331#ifdef MSDOS
10310 printf ("\r\nContinuing...\r\n"); 10332 write_stdout ("\r\nContinuing...\r\n");
10311#else /* not MSDOS */ 10333#else /* not MSDOS */
10312 printf ("Continuing...\n"); 10334 write_stdout ("Continuing...\n");
10313#endif /* not MSDOS */ 10335#endif /* not MSDOS */
10314 fflush (stdout);
10315 init_all_sys_modes (); 10336 init_all_sys_modes ();
10316 } 10337 }
10317 else 10338 else