125 lines
3.8 KiB
C
125 lines
3.8 KiB
C
$NetBSD: patch-src_keyboard.c,v 1.1 2016/03/05 15:31:45 gson Exp $
|
|
|
|
Don't call printf from a signal handler. Fixes emacs bug#22790.
|
|
Changes back-ported from emacs-25.0.92.
|
|
|
|
--- src/keyboard.c.orig 2015-04-02 07:23:06.000000000 +0000
|
|
+++ src/keyboard.c
|
|
@@ -10295,6 +10295,21 @@ deliver_interrupt_signal (int sig)
|
|
deliver_process_signal (sig, handle_interrupt_signal);
|
|
}
|
|
|
|
+/* Output MSG directly to standard output, without buffering. Ignore
|
|
+ failures. This is safe in a signal handler. */
|
|
+static void
|
|
+write_stdout (char const *msg)
|
|
+{
|
|
+ (void) (write (STDOUT_FILENO, msg, strlen (msg)));
|
|
+}
|
|
+
|
|
+/* Read a byte from stdin, without buffering. Safe in signal handlers. */
|
|
+static int
|
|
+read_stdin (void)
|
|
+{
|
|
+ char c;
|
|
+ return read (STDIN_FILENO, &c, 1) == 1 ? c : EOF;
|
|
+}
|
|
|
|
/* If Emacs is stuck because `inhibit-quit' is true, then keep track
|
|
of the number of times C-g has been requested. If C-g is pressed
|
|
@@ -10331,9 +10346,9 @@ handle_interrupt (bool in_signal_handler
|
|
sigemptyset (&blocked);
|
|
sigaddset (&blocked, SIGINT);
|
|
pthread_sigmask (SIG_BLOCK, &blocked, 0);
|
|
+ fflush (stdout);
|
|
}
|
|
|
|
- fflush (stdout);
|
|
reset_all_sys_modes ();
|
|
|
|
#ifdef SIGTSTP
|
|
@@ -10349,8 +10364,9 @@ handle_interrupt (bool in_signal_handler
|
|
/* Perhaps should really fork an inferior shell?
|
|
But that would not provide any way to get back
|
|
to the original shell, ever. */
|
|
- printf ("No support for stopping a process on this operating system;\n");
|
|
- printf ("you can continue or abort.\n");
|
|
+ write_stdout ("No support for stopping a process"
|
|
+ " on this operating system;\n"
|
|
+ "you can continue or abort.\n");
|
|
#endif /* not SIGTSTP */
|
|
#ifdef MSDOS
|
|
/* We must remain inside the screen area when the internal terminal
|
|
@@ -10361,46 +10377,49 @@ handle_interrupt (bool in_signal_handler
|
|
the code used for auto-saving doesn't cope with the mark bit. */
|
|
if (!gc_in_progress)
|
|
{
|
|
- printf ("Auto-save? (y or n) ");
|
|
- fflush (stdout);
|
|
- if (((c = getchar ()) & ~040) == 'Y')
|
|
+ write_stdout ("Auto-save? (y or n) ");
|
|
+ c = read_stdin ();
|
|
+ if (c == 'y' || c == 'Y')
|
|
{
|
|
Fdo_auto_save (Qt, Qnil);
|
|
#ifdef MSDOS
|
|
- printf ("\r\nAuto-save done");
|
|
-#else /* not MSDOS */
|
|
- printf ("Auto-save done\n");
|
|
-#endif /* not MSDOS */
|
|
+ write_stdout ("\r\nAuto-save done");
|
|
+#else
|
|
+ write_stdout ("Auto-save done\n");
|
|
+#endif
|
|
}
|
|
- while (c != '\n') c = getchar ();
|
|
+ while (c != '\n')
|
|
+ c = read_stdin ();
|
|
}
|
|
else
|
|
{
|
|
/* During GC, it must be safe to reenable quitting again. */
|
|
Vinhibit_quit = Qnil;
|
|
+ write_stdout
|
|
+ (
|
|
#ifdef MSDOS
|
|
- printf ("\r\n");
|
|
-#endif /* not MSDOS */
|
|
- printf ("Garbage collection in progress; cannot auto-save now\r\n");
|
|
- printf ("but will instead do a real quit after garbage collection ends\r\n");
|
|
- fflush (stdout);
|
|
+ "\r\n"
|
|
+#endif
|
|
+ "Garbage collection in progress; cannot auto-save now\r\n"
|
|
+ "but will instead do a real quit"
|
|
+ " after garbage collection ends\r\n");
|
|
}
|
|
|
|
#ifdef MSDOS
|
|
- printf ("\r\nAbort? (y or n) ");
|
|
-#else /* not MSDOS */
|
|
- printf ("Abort (and dump core)? (y or n) ");
|
|
-#endif /* not MSDOS */
|
|
- fflush (stdout);
|
|
- if (((c = getchar ()) & ~040) == 'Y')
|
|
+ write_stdout ("\r\nAbort? (y or n) ");
|
|
+#else
|
|
+ write_stdout ("Abort (and dump core)? (y or n) ");
|
|
+#endif
|
|
+ c = read_stdin ();
|
|
+ if (c == 'y' || c == 'Y')
|
|
emacs_abort ();
|
|
- while (c != '\n') c = getchar ();
|
|
+ while (c != '\n')
|
|
+ c = read_stdin ();
|
|
#ifdef MSDOS
|
|
- printf ("\r\nContinuing...\r\n");
|
|
+ write_stdout ("\r\nContinuing...\r\n");
|
|
#else /* not MSDOS */
|
|
- printf ("Continuing...\n");
|
|
+ write_stdout ("Continuing...\n");
|
|
#endif /* not MSDOS */
|
|
- fflush (stdout);
|
|
init_all_sys_modes ();
|
|
}
|
|
else
|