aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2016-01-03 15:00:49 -0800
committerPaul Eggert2016-01-03 15:04:07 -0800
commite79b06e6def82fab56a153085bff8223876d5908 (patch)
tree3fa986746456718707c735b0abda48c092945479
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.
-rwxr-xr-xadmin/merge-gnulib2
-rw-r--r--lib/gnulib.mk9
-rw-r--r--lib/ignore-value.h50
-rw-r--r--m4/gnulib-comp.m42
-rw-r--r--src/keyboard.c73
5 files changed, 108 insertions, 28 deletions
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 363bb23d119..40b5b78ee8f 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -32,7 +32,7 @@ GNULIB_MODULES='
32 dtoastr dtotimespec dup2 environ execinfo faccessat 32 dtoastr dtotimespec dup2 environ execinfo faccessat
33 fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync 33 fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync
34 getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog 34 getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog
35 intprops largefile lstat 35 ignore-value intprops largefile lstat
36 manywarnings memrchr mkostemp mktime 36 manywarnings memrchr mkostemp mktime
37 pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat 37 pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat
38 sig2str socklen stat-time stdalign stddef stdio 38 sig2str socklen stat-time stdalign stddef stdio
diff --git a/lib/gnulib.mk b/lib/gnulib.mk
index 97ed5b1f40f..b920cbbc9bb 100644
--- a/lib/gnulib.mk
+++ b/lib/gnulib.mk
@@ -21,7 +21,7 @@
21# the same distribution terms as the rest of that program. 21# the same distribution terms as the rest of that program.
22# 22#
23# Generated by gnulib-tool. 23# Generated by gnulib-tool.
24# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=flexmember --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=setenv --avoid=sigprocmask --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=unsetenv --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-one-bits count-trailing-zeros 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 gitlog-to-changelog intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time stdalign stddef stdio stpcpy strftime strtoimax strtoumax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub unsetenv update-copyright utimens vla warnings 24# Reproduce by: gnulib-tool --import --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=close --avoid=dup --avoid=fchdir --avoid=flexmember --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=setenv --avoid=sigprocmask --avoid=stdarg --avoid=stdbool --avoid=threadlib --avoid=unsetenv --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt binary-io byteswap c-ctype c-strcase careadlinkat close-stream count-one-bits count-trailing-zeros 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 gitlog-to-changelog ignore-value intprops largefile lstat manywarnings memrchr mkostemp mktime pipe2 pselect pthread_sigmask putenv qcopy-acl readlink readlinkat sig2str socklen stat-time stdalign stddef stdio stpcpy strftime strtoimax strtoumax symlink sys_stat sys_time time time_r time_rz timegm timer-time timespec-add timespec-sub unsetenv update-copyright utimens vla warnings
25 25
26 26
27MOSTLYCLEANFILES += core *.stackdump 27MOSTLYCLEANFILES += core *.stackdump
@@ -567,6 +567,13 @@ EXTRA_libgnu_a_SOURCES += group-member.c
567 567
568## end gnulib module group-member 568## end gnulib module group-member
569 569
570## begin gnulib module ignore-value
571
572
573EXTRA_DIST += ignore-value.h
574
575## end gnulib module ignore-value
576
570## begin gnulib module intprops 577## begin gnulib module intprops
571 578
572 579
diff --git a/lib/ignore-value.h b/lib/ignore-value.h
new file mode 100644
index 00000000000..6713d96f84e
--- /dev/null
+++ b/lib/ignore-value.h
@@ -0,0 +1,50 @@
1/* ignore a function return without a compiler warning. -*- coding: utf-8 -*-
2
3 Copyright (C) 2008-2016 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18/* Written by Jim Meyering, Eric Blake and Pádraig Brady. */
19
20/* Use "ignore_value" to avoid a warning when using a function declared with
21 gcc's warn_unused_result attribute, but for which you really do want to
22 ignore the result. Traditionally, people have used a "(void)" cast to
23 indicate that a function's return value is deliberately unused. However,
24 if the function is declared with __attribute__((warn_unused_result)),
25 gcc issues a warning even with the cast.
26
27 Caution: most of the time, you really should heed gcc's warning, and
28 check the return value. However, in those exceptional cases in which
29 you're sure you know what you're doing, use this function.
30
31 For the record, here's one of the ignorable warnings:
32 "copy.c:233: warning: ignoring return value of 'fchown',
33 declared with attribute warn_unused_result". */
34
35#ifndef _GL_IGNORE_VALUE_H
36#define _GL_IGNORE_VALUE_H
37
38/* Normally casting an expression to void discards its value, but GCC
39 versions 3.4 and newer have __attribute__ ((__warn_unused_result__))
40 which may cause unwanted diagnostics in that case. Use __typeof__
41 and __extension__ to work around the problem, if the workaround is
42 known to be needed. */
43#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__)
44# define ignore_value(x) \
45 (__extension__ ({ __typeof__ (x) __x = (x); (void) __x; }))
46#else
47# define ignore_value(x) ((void) (x))
48#endif
49
50#endif
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 69920a84afd..27ca70a0d09 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -91,6 +91,7 @@ AC_DEFUN([gl_EARLY],
91 # Code from module gettimeofday: 91 # Code from module gettimeofday:
92 # Code from module gitlog-to-changelog: 92 # Code from module gitlog-to-changelog:
93 # Code from module group-member: 93 # Code from module group-member:
94 # Code from module ignore-value:
94 # Code from module include_next: 95 # Code from module include_next:
95 # Code from module intprops: 96 # Code from module intprops:
96 # Code from module inttypes-incomplete: 97 # Code from module inttypes-incomplete:
@@ -905,6 +906,7 @@ AC_DEFUN([gl_FILE_LIST], [
905 lib/gettimeofday.c 906 lib/gettimeofday.c
906 lib/gl_openssl.h 907 lib/gl_openssl.h
907 lib/group-member.c 908 lib/group-member.c
909 lib/ignore-value.h
908 lib/intprops.h 910 lib/intprops.h
909 lib/inttypes.in.h 911 lib/inttypes.in.h
910 lib/lstat.c 912 lib/lstat.c
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