aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2012-09-06 10:49:15 +0900
committerKenichi Handa2012-09-06 10:49:15 +0900
commitfca81a8d405cd4c825e144099c54dd163636aa3b (patch)
treeee09be4b0e079b9c8863c8b570496a169227b218 /src
parentf41d6f9db69ce77fe9b3a637de407e8b589e0dc4 (diff)
parent067b39d4296765e83f9530eca456168f6cda95fc (diff)
downloademacs-fca81a8d405cd4c825e144099c54dd163636aa3b.tar.gz
emacs-fca81a8d405cd4c825e144099c54dd163636aa3b.zip
merge trunk
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog101
-rw-r--r--src/alloc.c72
-rw-r--r--src/atimer.c24
-rw-r--r--src/conf_post.h2
-rw-r--r--src/data.c17
-rw-r--r--src/dispnew.c20
-rw-r--r--src/editfns.c4
-rw-r--r--src/emacs.c98
-rw-r--r--src/fileio.c199
-rw-r--r--src/filelock.c24
-rw-r--r--src/floatfns.c39
-rw-r--r--src/fns.c70
-rw-r--r--src/frame.h3
-rw-r--r--src/keyboard.c54
-rw-r--r--src/lisp.h47
-rw-r--r--src/process.c256
-rw-r--r--src/sysdep.c38
-rw-r--r--src/syssignal.h23
-rw-r--r--src/window.c8
-rw-r--r--src/window.h4
-rw-r--r--src/xdisp.c12
21 files changed, 585 insertions, 530 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 7922a92d0fc..24d290e163d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,104 @@
12012-09-05 Paul Eggert <eggert@cs.ucla.edu>
2
3 Fix race conditions with signal handlers and errno.
4 Be more systematic about preserving errno whenever a signal
5 handler returns, even if it's not in the main thread. Do this by
6 renaming signal handlers to distinguish between signal delivery
7 and signal handling. All uses changed.
8 * atimer.c (deliver_alarm_signal): Rename from alarm_signal_handler.
9 * data.c (deliver_arith_signal): Rename from arith_error.
10 * dispnew.c (deliver_window_change_signal): Rename from
11 window_change_signal.
12 * emacs.c (deliver_error_signal): Rename from fatal_error_signal.
13 (deliver_danger_signal) [SIGDANGER]: Rename from memory_warning_signal.
14 * keyboard.c (deliver_input_available_signal): Rename from
15 input_available_signal.
16 (deliver_user_signal): Rename from handle_user_signal.
17 (deliver_interrupt_signal): Rename from interrupt_signal.
18 * process.c (deliver_pipe_signal): Rename from send_process_trap.
19 (deliver_child_signal): Rename from sigchld_handler.
20 * atimer.c (handle_alarm_signal):
21 * data.c (handle_arith_signal):
22 * dispnew.c (handle_window_change_signal):
23 * emacs.c (handle_fatal_signal, handle_danger_signal):
24 * keyboard.c (handle_input_available_signal):
25 * keyboard.c (handle_user_signal, handle_interrupt_signal):
26 * process.c (handle_pipe_signal, handle_child_signal):
27 New functions, with the actual signal-handling code taken from the
28 original respective signal handlers, sans the sporadic attempts to
29 preserve errno, since that's now done by handle_on_main_thread.
30 * atimer.c (alarm_signal_handler): Remove unnecessary decl.
31 * emacs.c, floatfns.c, lisp.h: Remove unused FLOAT_CATCH_SIGKILL cruft.
32 * emacs.c (main_thread) [FORWARD_SIGNAL_TO_MAIN_THREAD]:
33 Move to sysdep.c.
34 (main) [FORWARD_SIGNAL_TO_MAIN_THREAD]:
35 Move initialization of main_thread to sysdep.c's init_signals.
36 * process.c (waitpid) [!WNOHANG]: #define to wait; that's good enough for
37 our usage, and simplifies the mainline code.
38 (record_child_status_change): New static function, as a helper
39 for handle_child_signal, and with most of the old child handler's
40 contents.
41 (CAN_HANDLE_MULTIPLE_CHILDREN): New constant.
42 (handle_child_signal): Use the above.
43 * sysdep.c (main_thread) [FORWARD_SIGNAL_TO_MAIN_THREAD]:
44 Moved here from emacs.c.
45 (init_signals) [FORWARD_SIGNAL_TO_MAIN_THREAD]: Initialize it;
46 code moved here from emacs.c's main function.
47 * sysdep.c, syssignal.h (handle_on_main_thread): New function,
48 replacing the old SIGNAL_THREAD_CHECK. All uses changed. This
49 lets callers save and restore errno properly.
50
512012-09-05 Dmitry Antipov <dmantipov@yandex.ru>
52
53 Remove redundant or unused things here and there.
54 * lisp.h (CYCLE_CHECK, CHAR_TABLE_TRANSLATE): Remove.
55 * conf_post.h (RE_TRANSLATE): Use char_table_translate.
56 * editfns.c (Fcompare_buffer_substrings): Likewise.
57 * frame.h (struct terminal, struct font_driver_list):
58 Remove redundant declarations.
59 * window.h (Qleft, Qright): Likewise.
60
612012-09-05 Dmitry Antipov <dmantipov@yandex.ru>
62
63 Do not mark objects from deleted buffers, windows and frames.
64 * alloc.c (mark_buffer): Mark just the buffer if it is dead.
65 (mark_object): Likewise for windows and frames.
66
672012-09-05 Dmitry Antipov <dmantipov@yandex.ru>
68
69 * alloc.c (valid_lisp_object_p): Treat killed buffers,
70 buffer_defaults and buffer_local_symbols as valid objects.
71 Return special value to denote them.
72
732012-09-05 Paul Eggert <eggert@cs.ucla.edu>
74
75 * fileio.c, filelock.c, floatfns.c, fns.c: Use bool for boolean.
76 * fileio.c (auto_saving, auto_save_error_occurred, make_temp_name)
77 (Fexpand_file_name, barf_or_query_if_file_exists, Fcopy_file)
78 (file_name_absolute_p, Fsubstitute_in_file_name):
79 (check_executable, check_writable, Ffile_accessible_directory_p)
80 (Fset_file_selinux_context, Fdefault_file_modes)
81 (Finsert_file_contents, choose_write_coding_system)
82 (Fwrite_region, build_annotations, a_write, e_write)
83 (Fdo_auto_save):
84 * filelock.c (boot_time_initialized, get_boot_time)
85 (get_boot_time_1, lock_file_1, within_one_second):
86 * floatfns.c (in_float):
87 * fns.c (concat, internal_equal, Frequire, base64_encode_1)
88 (base64_decode_1, cmpfn_eql, cmpfn_user_defined)
89 (sweep_weak_table, sweep_weak_hash_tables, secure_hash):
90 * lisp.h (struct Lisp_Hash_Table.cmpfn):
91 * window.c (compare_window_configurations):
92 Use bool for booleans.
93 * fileio.c (auto_saving_dir_umask, auto_saving_mode_bits)
94 (Fdefault_file_modes): Now mode_t, not int, for modes.
95 (Fdo_auto_save): Set a boolean to 1 rather than using ++.
96 (internal_delete_file): Now returns void, not a (boolean) int,
97 since nobody was looking at the return value.
98 * lisp.h, window.h: Adjust to above API changes.
99
100 * xdisp.c (set_message): Simplify and reindent last change.
101
12012-09-05 Juanma Barranquero <lekktu@gmail.com> 1022012-09-05 Juanma Barranquero <lekktu@gmail.com>
2 103
3 * makefile.w32-in ($(BLD)/sysdep.$(O)): Update dependencies. 104 * makefile.w32-in ($(BLD)/sysdep.$(O)): Update dependencies.
diff --git a/src/alloc.c b/src/alloc.c
index 157d3a1d799..e90cca637df 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -4981,7 +4981,8 @@ valid_pointer_p (void *p)
4981#endif 4981#endif
4982} 4982}
4983 4983
4984/* Return 1 if OBJ is a valid lisp object. 4984/* Return 2 if OBJ is a killed or special buffer object.
4985 Return 1 if OBJ is a valid lisp object.
4985 Return 0 if OBJ is NOT a valid lisp object. 4986 Return 0 if OBJ is NOT a valid lisp object.
4986 Return -1 if we cannot validate OBJ. 4987 Return -1 if we cannot validate OBJ.
4987 This function can be quite slow, 4988 This function can be quite slow,
@@ -5002,6 +5003,9 @@ valid_lisp_object_p (Lisp_Object obj)
5002 if (PURE_POINTER_P (p)) 5003 if (PURE_POINTER_P (p))
5003 return 1; 5004 return 1;
5004 5005
5006 if (p == &buffer_defaults || p == &buffer_local_symbols)
5007 return 2;
5008
5005#if !GC_MARK_STACK 5009#if !GC_MARK_STACK
5006 return valid_pointer_p (p); 5010 return valid_pointer_p (p);
5007#else 5011#else
@@ -5027,7 +5031,7 @@ valid_lisp_object_p (Lisp_Object obj)
5027 return 0; 5031 return 0;
5028 5032
5029 case MEM_TYPE_BUFFER: 5033 case MEM_TYPE_BUFFER:
5030 return live_buffer_p (m, p); 5034 return live_buffer_p (m, p) ? 1 : 2;
5031 5035
5032 case MEM_TYPE_CONS: 5036 case MEM_TYPE_CONS:
5033 return live_cons_p (m, p); 5037 return live_cons_p (m, p);
@@ -5834,23 +5838,29 @@ mark_overlay (struct Lisp_Overlay *ptr)
5834static void 5838static void
5835mark_buffer (struct buffer *buffer) 5839mark_buffer (struct buffer *buffer)
5836{ 5840{
5837 /* This is handled much like other pseudovectors... */ 5841 if (NILP (BVAR (buffer, name)))
5838 mark_vectorlike ((struct Lisp_Vector *) buffer); 5842 /* If the buffer is killed, mark just the buffer itself. */
5843 VECTOR_MARK (buffer);
5844 else
5845 {
5846 /* This is handled much like other pseudovectors... */
5847 mark_vectorlike ((struct Lisp_Vector *) buffer);
5839 5848
5840 /* ...but there are some buffer-specific things. */ 5849 /* ...but there are some buffer-specific things. */
5841 5850
5842 MARK_INTERVAL_TREE (buffer_intervals (buffer)); 5851 MARK_INTERVAL_TREE (buffer_intervals (buffer));
5843 5852
5844 /* For now, we just don't mark the undo_list. It's done later in 5853 /* For now, we just don't mark the undo_list. It's done later in
5845 a special way just before the sweep phase, and after stripping 5854 a special way just before the sweep phase, and after stripping
5846 some of its elements that are not needed any more. */ 5855 some of its elements that are not needed any more. */
5847 5856
5848 mark_overlay (buffer->overlays_before); 5857 mark_overlay (buffer->overlays_before);
5849 mark_overlay (buffer->overlays_after); 5858 mark_overlay (buffer->overlays_after);
5850 5859
5851 /* If this is an indirect buffer, mark its base buffer. */ 5860 /* If this is an indirect buffer, mark its base buffer. */
5852 if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer)) 5861 if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer))
5853 mark_buffer (buffer->base_buffer); 5862 mark_buffer (buffer->base_buffer);
5863 }
5854} 5864}
5855 5865
5856/* Determine type of generic Lisp_Object and mark it accordingly. */ 5866/* Determine type of generic Lisp_Object and mark it accordingly. */
@@ -5993,24 +6003,38 @@ mark_object (Lisp_Object arg)
5993 6003
5994 case PVEC_FRAME: 6004 case PVEC_FRAME:
5995 { 6005 {
5996 mark_vectorlike (ptr); 6006 struct frame *f = (struct frame *) ptr;
5997 mark_face_cache (((struct frame *) ptr)->face_cache); 6007
6008 if (FRAME_LIVE_P (f))
6009 {
6010 mark_vectorlike (ptr);
6011 mark_face_cache (f->face_cache);
6012 }
6013 else
6014 /* If the frame is deleted, mark just the frame itself. */
6015 VECTOR_MARK (ptr);
5998 } 6016 }
5999 break; 6017 break;
6000 6018
6001 case PVEC_WINDOW: 6019 case PVEC_WINDOW:
6002 { 6020 {
6003 struct window *w = (struct window *) ptr; 6021 struct window *w = (struct window *) ptr;
6022 bool leaf = NILP (w->hchild) && NILP (w->vchild);
6004 6023
6005 mark_vectorlike (ptr); 6024 if (leaf && NILP (w->buffer))
6006 /* Mark glyphs for leaf windows. Marking window 6025 /* If the window is deleted, mark just the window itself. */
6007 matrices is sufficient because frame matrices 6026 VECTOR_MARK (ptr);
6008 use the same glyph memory. */ 6027 else
6009 if (NILP (w->hchild) && NILP (w->vchild)
6010 && w->current_matrix)
6011 { 6028 {
6012 mark_glyph_matrix (w->current_matrix); 6029 mark_vectorlike (ptr);
6013 mark_glyph_matrix (w->desired_matrix); 6030 /* Mark glyphs for leaf windows. Marking window
6031 matrices is sufficient because frame matrices
6032 use the same glyph memory. */
6033 if (leaf && w->current_matrix)
6034 {
6035 mark_glyph_matrix (w->current_matrix);
6036 mark_glyph_matrix (w->desired_matrix);
6037 }
6014 } 6038 }
6015 } 6039 }
6016 break; 6040 break;
diff --git a/src/atimer.c b/src/atimer.c
index eb3136ae55d..060dead9b17 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -41,7 +41,7 @@ static struct atimer *stopped_atimers;
41 41
42static struct atimer *atimers; 42static struct atimer *atimers;
43 43
44/* Non-zero means alarm_signal_handler has found ripe timers but 44/* Non-zero means alarm signal handler has found ripe timers but
45 interrupt_input_blocked was non-zero. In this case, timer 45 interrupt_input_blocked was non-zero. In this case, timer
46 functions are not called until the next UNBLOCK_INPUT because timer 46 functions are not called until the next UNBLOCK_INPUT because timer
47 functions are expected to call X, and X cannot be assumed to be 47 functions are expected to call X, and X cannot be assumed to be
@@ -60,8 +60,6 @@ static void set_alarm (void);
60static void schedule_atimer (struct atimer *); 60static void schedule_atimer (struct atimer *);
61static struct atimer *append_atimer_lists (struct atimer *, 61static struct atimer *append_atimer_lists (struct atimer *,
62 struct atimer *); 62 struct atimer *);
63static void alarm_signal_handler (int signo);
64
65 63
66/* Start a new atimer of type TYPE. TIME specifies when the timer is 64/* Start a new atimer of type TYPE. TIME specifies when the timer is
67 ripe. FN is the function to call when the timer fires. 65 ripe. FN is the function to call when the timer fires.
@@ -374,13 +372,9 @@ run_timers (void)
374/* Signal handler for SIGALRM. SIGNO is the signal number, i.e. 372/* Signal handler for SIGALRM. SIGNO is the signal number, i.e.
375 SIGALRM. */ 373 SIGALRM. */
376 374
377void 375static void
378alarm_signal_handler (int signo) 376handle_alarm_signal (int sig)
379{ 377{
380#ifndef SYNC_INPUT
381 SIGNAL_THREAD_CHECK (signo);
382#endif
383
384 pending_atimers = 1; 378 pending_atimers = 1;
385#ifdef SYNC_INPUT 379#ifdef SYNC_INPUT
386 pending_signals = 1; 380 pending_signals = 1;
@@ -389,8 +383,14 @@ alarm_signal_handler (int signo)
389#endif 383#endif
390} 384}
391 385
386static void
387deliver_alarm_signal (int sig)
388{
389 handle_on_main_thread (sig, handle_alarm_signal);
390}
391
392 392
393/* Call alarm_signal_handler for pending timers. */ 393/* Call alarm signal handler for pending timers. */
394 394
395void 395void
396do_pending_atimers (void) 396do_pending_atimers (void)
@@ -412,7 +412,7 @@ turn_on_atimers (bool on)
412{ 412{
413 if (on) 413 if (on)
414 { 414 {
415 signal (SIGALRM, alarm_signal_handler); 415 signal (SIGALRM, deliver_alarm_signal);
416 set_alarm (); 416 set_alarm ();
417 } 417 }
418 else 418 else
@@ -426,5 +426,5 @@ init_atimer (void)
426 free_atimers = stopped_atimers = atimers = NULL; 426 free_atimers = stopped_atimers = atimers = NULL;
427 pending_atimers = 0; 427 pending_atimers = 0;
428 /* pending_signals is initialized in init_keyboard.*/ 428 /* pending_signals is initialized in init_keyboard.*/
429 signal (SIGALRM, alarm_signal_handler); 429 signal (SIGALRM, deliver_alarm_signal);
430} 430}
diff --git a/src/conf_post.h b/src/conf_post.h
index ead7298e98d..cef55863752 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -167,7 +167,7 @@ You lose; /* Emacs for DOS must be compiled with DJGPP */
167#ifdef emacs /* Don't do this for lib-src. */ 167#ifdef emacs /* Don't do this for lib-src. */
168/* Tell regex.c to use a type compatible with Emacs. */ 168/* Tell regex.c to use a type compatible with Emacs. */
169#define RE_TRANSLATE_TYPE Lisp_Object 169#define RE_TRANSLATE_TYPE Lisp_Object
170#define RE_TRANSLATE(TBL, C) CHAR_TABLE_TRANSLATE (TBL, C) 170#define RE_TRANSLATE(TBL, C) char_table_translate (TBL, C)
171#ifdef make_number 171#ifdef make_number
172/* If make_number is a macro, use it. */ 172/* If make_number is a macro, use it. */
173#define RE_TRANSLATE_P(TBL) (!EQ (TBL, make_number (0))) 173#define RE_TRANSLATE_P(TBL) (!EQ (TBL, make_number (0)))
diff --git a/src/data.c b/src/data.c
index 415a8962350..6151d815b29 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3207,18 +3207,19 @@ syms_of_data (void)
3207 XSYMBOL (intern_c_string ("most-negative-fixnum"))->constant = 1; 3207 XSYMBOL (intern_c_string ("most-negative-fixnum"))->constant = 1;
3208} 3208}
3209 3209
3210#ifndef FORWARD_SIGNAL_TO_MAIN_THREAD 3210static _Noreturn void
3211_Noreturn 3211handle_arith_signal (int sig)
3212#endif
3213static void
3214arith_error (int signo)
3215{ 3212{
3216 sigsetmask (SIGEMPTYMASK); 3213 sigsetmask (SIGEMPTYMASK);
3217
3218 SIGNAL_THREAD_CHECK (signo);
3219 xsignal0 (Qarith_error); 3214 xsignal0 (Qarith_error);
3220} 3215}
3221 3216
3217static void
3218deliver_arith_signal (int sig)
3219{
3220 handle_on_main_thread (sig, handle_arith_signal);
3221}
3222
3222void 3223void
3223init_data (void) 3224init_data (void)
3224{ 3225{
@@ -3230,5 +3231,5 @@ init_data (void)
3230 if (!initialized) 3231 if (!initialized)
3231 return; 3232 return;
3232#endif /* CANNOT_DUMP */ 3233#endif /* CANNOT_DUMP */
3233 signal (SIGFPE, arith_error); 3234 signal (SIGFPE, deliver_arith_signal);
3234} 3235}
diff --git a/src/dispnew.c b/src/dispnew.c
index 17e6c85ac75..e02b33000d8 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -5552,17 +5552,15 @@ marginal_area_string (struct window *w, enum window_part part,
5552 5552
5553#ifdef SIGWINCH 5553#ifdef SIGWINCH
5554 5554
5555static void deliver_window_change_signal (int);
5556
5555static void 5557static void
5556window_change_signal (int signalnum) /* If we don't have an argument, */ 5558handle_window_change_signal (int sig)
5557 /* some compilers complain in signal calls. */
5558{ 5559{
5559 int width, height; 5560 int width, height;
5560 int old_errno = errno;
5561
5562 struct tty_display_info *tty; 5561 struct tty_display_info *tty;
5563 5562
5564 signal (SIGWINCH, window_change_signal); 5563 signal (SIGWINCH, deliver_window_change_signal);
5565 SIGNAL_THREAD_CHECK (signalnum);
5566 5564
5567 /* The frame size change obviously applies to a single 5565 /* The frame size change obviously applies to a single
5568 termcap-controlled terminal, but we can't decide which. 5566 termcap-controlled terminal, but we can't decide which.
@@ -5591,8 +5589,12 @@ window_change_signal (int signalnum) /* If we don't have an argument, */
5591 change_frame_size (XFRAME (frame), height, width, 0, 1, 0); 5589 change_frame_size (XFRAME (frame), height, width, 0, 1, 0);
5592 } 5590 }
5593 } 5591 }
5592}
5594 5593
5595 errno = old_errno; 5594static void
5595deliver_window_change_signal (int sig)
5596{
5597 handle_on_main_thread (sig, handle_window_change_signal);
5596} 5598}
5597#endif /* SIGWINCH */ 5599#endif /* SIGWINCH */
5598 5600
@@ -5604,7 +5606,7 @@ window_change_signal (int signalnum) /* If we don't have an argument, */
5604void 5606void
5605do_pending_window_change (bool safe) 5607do_pending_window_change (bool safe)
5606{ 5608{
5607 /* If window_change_signal should have run before, run it now. */ 5609 /* If window change signal handler should have run before, run it now. */
5608 if (redisplaying_p && !safe) 5610 if (redisplaying_p && !safe)
5609 return; 5611 return;
5610 5612
@@ -6173,7 +6175,7 @@ init_display (void)
6173#ifndef CANNOT_DUMP 6175#ifndef CANNOT_DUMP
6174 if (initialized) 6176 if (initialized)
6175#endif /* CANNOT_DUMP */ 6177#endif /* CANNOT_DUMP */
6176 signal (SIGWINCH, window_change_signal); 6178 signal (SIGWINCH, deliver_window_change_signal);
6177#endif /* SIGWINCH */ 6179#endif /* SIGWINCH */
6178 6180
6179 /* If running as a daemon, no need to initialize any frames/terminal. */ 6181 /* If running as a daemon, no need to initialize any frames/terminal. */
diff --git a/src/editfns.c b/src/editfns.c
index 2d1a3cbfa0c..65baaf4e3f8 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -2783,8 +2783,8 @@ determines whether case is significant or ignored. */)
2783 2783
2784 if (!NILP (trt)) 2784 if (!NILP (trt))
2785 { 2785 {
2786 c1 = CHAR_TABLE_TRANSLATE (trt, c1); 2786 c1 = char_table_translate (trt, c1);
2787 c2 = CHAR_TABLE_TRANSLATE (trt, c2); 2787 c2 = char_table_translate (trt, c2);
2788 } 2788 }
2789 if (c1 < c2) 2789 if (c1 < c2)
2790 return make_number (- 1 - chars); 2790 return make_number (- 1 - chars);
diff --git a/src/emacs.c b/src/emacs.c
index 18f249dc899..fc92b30af26 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -275,14 +275,6 @@ static int fatal_error_code;
275/* True if handling a fatal error already. */ 275/* True if handling a fatal error already. */
276bool fatal_error_in_progress; 276bool fatal_error_in_progress;
277 277
278#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
279/* When compiled with GTK and running under Gnome,
280 multiple threads may be created. Keep track of our main
281 thread to make sure signals are delivered to it (see syssignal.h). */
282
283pthread_t main_thread;
284#endif
285
286#ifdef HAVE_NS 278#ifdef HAVE_NS
287/* NS autrelease pool, for memory management. */ 279/* NS autrelease pool, for memory management. */
288static void *ns_pool; 280static void *ns_pool;
@@ -291,16 +283,18 @@ static void *ns_pool;
291 283
292 284
293/* Handle bus errors, invalid instruction, etc. */ 285/* Handle bus errors, invalid instruction, etc. */
294#ifndef FLOAT_CATCH_SIGILL 286static void
295static 287handle_fatal_signal (int sig)
296#endif
297void
298fatal_error_signal (int sig)
299{ 288{
300 SIGNAL_THREAD_CHECK (sig);
301 fatal_error_backtrace (sig, 10); 289 fatal_error_backtrace (sig, 10);
302} 290}
303 291
292static void
293deliver_fatal_signal (int sig)
294{
295 handle_on_main_thread (sig, handle_fatal_signal);
296}
297
304/* Report a fatal error due to signal SIG, output a backtrace of at 298/* Report a fatal error due to signal SIG, output a backtrace of at
305 most BACKTRACE_LIMIT lines, and exit. */ 299 most BACKTRACE_LIMIT lines, and exit. */
306_Noreturn void 300_Noreturn void
@@ -340,17 +334,23 @@ fatal_error_backtrace (int sig, int backtrace_limit)
340#ifdef SIGDANGER 334#ifdef SIGDANGER
341 335
342/* Handler for SIGDANGER. */ 336/* Handler for SIGDANGER. */
343void 337static void deliver_danger_signal (int);
344memory_warning_signal (int sig)
345{
346 signal (sig, memory_warning_signal);
347 SIGNAL_THREAD_CHECK (sig);
348 338
339static void
340handle_danger_signal (int sig)
341{
342 signal (sig, deliver_danger_signal);
349 malloc_warning ("Operating system warns that virtual memory is running low.\n"); 343 malloc_warning ("Operating system warns that virtual memory is running low.\n");
350 344
351 /* It might be unsafe to call do_auto_save now. */ 345 /* It might be unsafe to call do_auto_save now. */
352 force_auto_save_soon (); 346 force_auto_save_soon ();
353} 347}
348
349static void
350deliver_danger_signal (int sig)
351{
352 handle_on_main_thread (sig, handle_danger_signal);
353}
354#endif 354#endif
355 355
356/* Code for dealing with Lisp access to the Unix command line. */ 356/* Code for dealing with Lisp access to the Unix command line. */
@@ -851,10 +851,6 @@ main (int argc, char **argv)
851# endif /* not SYNC_INPUT */ 851# endif /* not SYNC_INPUT */
852#endif /* not SYSTEM_MALLOC */ 852#endif /* not SYSTEM_MALLOC */
853 853
854#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
855 main_thread = pthread_self ();
856#endif /* FORWARD_SIGNAL_TO_MAIN_THREAD */
857
858#if defined (MSDOS) || defined (WINDOWSNT) 854#if defined (MSDOS) || defined (WINDOWSNT)
859 /* We do all file input/output as binary files. When we need to translate 855 /* We do all file input/output as binary files. When we need to translate
860 newlines, we do that manually. */ 856 newlines, we do that manually. */
@@ -1120,7 +1116,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1120 That makes nohup work. */ 1116 That makes nohup work. */
1121 if (! noninteractive 1117 if (! noninteractive
1122 || signal (SIGHUP, SIG_IGN) != SIG_IGN) 1118 || signal (SIGHUP, SIG_IGN) != SIG_IGN)
1123 signal (SIGHUP, fatal_error_signal); 1119 signal (SIGHUP, deliver_fatal_signal);
1124 sigunblock (sigmask (SIGHUP)); 1120 sigunblock (sigmask (SIGHUP));
1125 } 1121 }
1126 1122
@@ -1135,9 +1131,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1135 /* Don't catch these signals in batch mode if dumping. 1131 /* Don't catch these signals in batch mode if dumping.
1136 On some machines, this sets static data that would make 1132 On some machines, this sets static data that would make
1137 signal fail to work right when the dumped Emacs is run. */ 1133 signal fail to work right when the dumped Emacs is run. */
1138 signal (SIGQUIT, fatal_error_signal); 1134 signal (SIGQUIT, deliver_fatal_signal);
1139 signal (SIGILL, fatal_error_signal); 1135 signal (SIGILL, deliver_fatal_signal);
1140 signal (SIGTRAP, fatal_error_signal); 1136 signal (SIGTRAP, deliver_fatal_signal);
1141#ifdef SIGUSR1 1137#ifdef SIGUSR1
1142 add_user_signal (SIGUSR1, "sigusr1"); 1138 add_user_signal (SIGUSR1, "sigusr1");
1143#endif 1139#endif
@@ -1145,68 +1141,68 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
1145 add_user_signal (SIGUSR2, "sigusr2"); 1141 add_user_signal (SIGUSR2, "sigusr2");
1146#endif 1142#endif
1147#ifdef SIGABRT 1143#ifdef SIGABRT
1148 signal (SIGABRT, fatal_error_signal); 1144 signal (SIGABRT, deliver_fatal_signal);
1149#endif 1145#endif
1150#ifdef SIGHWE 1146#ifdef SIGHWE
1151 signal (SIGHWE, fatal_error_signal); 1147 signal (SIGHWE, deliver_fatal_signal);
1152#endif 1148#endif
1153#ifdef SIGPRE 1149#ifdef SIGPRE
1154 signal (SIGPRE, fatal_error_signal); 1150 signal (SIGPRE, deliver_fatal_signal);
1155#endif 1151#endif
1156#ifdef SIGORE 1152#ifdef SIGORE
1157 signal (SIGORE, fatal_error_signal); 1153 signal (SIGORE, deliver_fatal_signal);
1158#endif 1154#endif
1159#ifdef SIGUME 1155#ifdef SIGUME
1160 signal (SIGUME, fatal_error_signal); 1156 signal (SIGUME, deliver_fatal_signal);
1161#endif 1157#endif
1162#ifdef SIGDLK 1158#ifdef SIGDLK
1163 signal (SIGDLK, fatal_error_signal); 1159 signal (SIGDLK, deliver_fatal_signal);
1164#endif 1160#endif
1165#ifdef SIGCPULIM 1161#ifdef SIGCPULIM
1166 signal (SIGCPULIM, fatal_error_signal); 1162 signal (SIGCPULIM, deliver_fatal_signal);
1167#endif 1163#endif
1168#ifdef SIGIOT 1164#ifdef SIGIOT
1169 /* This is missing on some systems - OS/2, for example. */ 1165 /* This is missing on some systems - OS/2, for example. */
1170 signal (SIGIOT, fatal_error_signal); 1166 signal (SIGIOT, deliver_fatal_signal);
1171#endif 1167#endif
1172#ifdef SIGEMT 1168#ifdef SIGEMT
1173 signal (SIGEMT, fatal_error_signal); 1169 signal (SIGEMT, deliver_fatal_signal);
1174#endif 1170#endif
1175 signal (SIGFPE, fatal_error_signal); 1171 signal (SIGFPE, deliver_fatal_signal);
1176#ifdef SIGBUS 1172#ifdef SIGBUS
1177 signal (SIGBUS, fatal_error_signal); 1173 signal (SIGBUS, deliver_fatal_signal);
1178#endif 1174#endif
1179 signal (SIGSEGV, fatal_error_signal); 1175 signal (SIGSEGV, deliver_fatal_signal);
1180#ifdef SIGSYS 1176#ifdef SIGSYS
1181 signal (SIGSYS, fatal_error_signal); 1177 signal (SIGSYS, deliver_fatal_signal);
1182#endif 1178#endif
1183 /* May need special treatment on MS-Windows. See 1179 /* May need special treatment on MS-Windows. See
1184 http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html 1180 http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html
1185 Please update the doc of kill-emacs, kill-emacs-hook, and 1181 Please update the doc of kill-emacs, kill-emacs-hook, and
1186 NEWS if you change this. 1182 NEWS if you change this.
1187 */ 1183 */
1188 if (noninteractive) signal (SIGINT, fatal_error_signal); 1184 if (noninteractive) signal (SIGINT, deliver_fatal_signal);
1189 signal (SIGTERM, fatal_error_signal); 1185 signal (SIGTERM, deliver_fatal_signal);
1190#ifdef SIGXCPU 1186#ifdef SIGXCPU
1191 signal (SIGXCPU, fatal_error_signal); 1187 signal (SIGXCPU, deliver_fatal_signal);
1192#endif 1188#endif
1193#ifdef SIGXFSZ 1189#ifdef SIGXFSZ
1194 signal (SIGXFSZ, fatal_error_signal); 1190 signal (SIGXFSZ, deliver_fatal_signal);
1195#endif /* SIGXFSZ */ 1191#endif /* SIGXFSZ */
1196 1192
1197#ifdef SIGDANGER 1193#ifdef SIGDANGER
1198 /* This just means available memory is getting low. */ 1194 /* This just means available memory is getting low. */
1199 signal (SIGDANGER, memory_warning_signal); 1195 signal (SIGDANGER, deliver_danger_signal);
1200#endif 1196#endif
1201 1197
1202#ifdef AIX 1198#ifdef AIX
1203/* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */ 1199/* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
1204 signal (SIGXCPU, fatal_error_signal); 1200 signal (SIGXCPU, deliver_fatal_signal);
1205 signal (SIGIOINT, fatal_error_signal); 1201 signal (SIGIOINT, deliver_fatal_signal);
1206 signal (SIGGRANT, fatal_error_signal); 1202 signal (SIGGRANT, deliver_fatal_signal);
1207 signal (SIGRETRACT, fatal_error_signal); 1203 signal (SIGRETRACT, deliver_fatal_signal);
1208 signal (SIGSOUND, fatal_error_signal); 1204 signal (SIGSOUND, deliver_fatal_signal);
1209 signal (SIGMSG, fatal_error_signal); 1205 signal (SIGMSG, deliver_fatal_signal);
1210#endif /* AIX */ 1206#endif /* AIX */
1211 } 1207 }
1212 1208
diff --git a/src/fileio.c b/src/fileio.c
index d193d2ed19f..f0b3f0cc2fd 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -85,18 +85,18 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
85 85
86#include "commands.h" 86#include "commands.h"
87 87
88/* Nonzero during writing of auto-save files. */ 88/* True during writing of auto-save files. */
89static int auto_saving; 89static bool auto_saving;
90 90
91/* Nonzero umask during creation of auto-save directories. */ 91/* Nonzero umask during creation of auto-save directories. */
92static int auto_saving_dir_umask; 92static mode_t auto_saving_dir_umask;
93 93
94/* Set by auto_save_1 to mode of original file so Fwrite_region will create 94/* Set by auto_save_1 to mode of original file so Fwrite_region will create
95 a new file with the same mode as the original. */ 95 a new file with the same mode as the original. */
96static int auto_save_mode_bits; 96static mode_t auto_save_mode_bits;
97 97
98/* Set by auto_save_1 if an error occurred during the last auto-save. */ 98/* Set by auto_save_1 if an error occurred during the last auto-save. */
99static int auto_save_error_occurred; 99static bool auto_save_error_occurred;
100 100
101/* The symbol bound to coding-system-for-read when 101/* The symbol bound to coding-system-for-read when
102 insert-file-contents is called for recovering a file. This is not 102 insert-file-contents is called for recovering a file. This is not
@@ -145,10 +145,10 @@ Lisp_Object Qfile_name_history;
145 145
146static Lisp_Object Qcar_less_than_car; 146static Lisp_Object Qcar_less_than_car;
147 147
148static int a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, 148static bool a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
149 Lisp_Object *, struct coding_system *); 149 Lisp_Object *, struct coding_system *);
150static int e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, 150static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t,
151 struct coding_system *); 151 struct coding_system *);
152 152
153 153
154void 154void
@@ -595,7 +595,7 @@ static unsigned make_temp_name_count, make_temp_name_count_initialized_p;
595 which has no existing file. To make this work, PREFIX should be 595 which has no existing file. To make this work, PREFIX should be
596 an absolute file name. 596 an absolute file name.
597 597
598 BASE64_P non-zero means add the pid as 3 characters in base64 598 BASE64_P means add the pid as 3 characters in base64
599 encoding. In this case, 6 characters will be added to PREFIX to 599 encoding. In this case, 6 characters will be added to PREFIX to
600 form the file name. Otherwise, if Emacs is running on a system 600 form the file name. Otherwise, if Emacs is running on a system
601 with long file names, add the pid as a decimal number. 601 with long file names, add the pid as a decimal number.
@@ -604,7 +604,7 @@ static unsigned make_temp_name_count, make_temp_name_count_initialized_p;
604 generated. */ 604 generated. */
605 605
606Lisp_Object 606Lisp_Object
607make_temp_name (Lisp_Object prefix, int base64_p) 607make_temp_name (Lisp_Object prefix, bool base64_p)
608{ 608{
609 Lisp_Object val; 609 Lisp_Object val;
610 int len, clen; 610 int len, clen;
@@ -761,8 +761,8 @@ filesystem tree, not (expand-file-name ".." dirname). */)
761 struct passwd *pw; 761 struct passwd *pw;
762#ifdef DOS_NT 762#ifdef DOS_NT
763 int drive = 0; 763 int drive = 0;
764 int collapse_newdir = 1; 764 bool collapse_newdir = 1;
765 int is_escaped = 0; 765 bool is_escaped = 0;
766#endif /* DOS_NT */ 766#endif /* DOS_NT */
767 ptrdiff_t length; 767 ptrdiff_t length;
768 Lisp_Object handler, result, handled_name; 768 Lisp_Object handler, result, handled_name;
@@ -920,10 +920,9 @@ filesystem tree, not (expand-file-name ".." dirname). */)
920 /* If it turns out that the filename we want to return is just a 920 /* If it turns out that the filename we want to return is just a
921 suffix of FILENAME, we don't need to go through and edit 921 suffix of FILENAME, we don't need to go through and edit
922 things; we just need to construct a new string using data 922 things; we just need to construct a new string using data
923 starting at the middle of FILENAME. If we set lose to a 923 starting at the middle of FILENAME. If we set LOSE, that
924 non-zero value, that means we've discovered that we can't do 924 means we've discovered that we can't do that cool trick. */
925 that cool trick. */ 925 bool lose = 0;
926 int lose = 0;
927 char *p = nm; 926 char *p = nm;
928 927
929 while (*p) 928 while (*p)
@@ -1360,7 +1359,6 @@ See also the function `substitute-in-file-name'.")
1360 ptrdiff_t tlen; 1359 ptrdiff_t tlen;
1361 unsigned char *target; 1360 unsigned char *target;
1362 struct passwd *pw; 1361 struct passwd *pw;
1363 int lose;
1364 1362
1365 CHECK_STRING (name); 1363 CHECK_STRING (name);
1366 nm = SDATA (name); 1364 nm = SDATA (name);
@@ -1369,8 +1367,8 @@ See also the function `substitute-in-file-name'.")
1369 If no /./ or /../ we can return right away. */ 1367 If no /./ or /../ we can return right away. */
1370 if (nm[0] == '/') 1368 if (nm[0] == '/')
1371 { 1369 {
1370 bool lose = 0;
1372 p = nm; 1371 p = nm;
1373 lose = 0;
1374 while (*p) 1372 while (*p)
1375 { 1373 {
1376 if (p[0] == '/' && p[1] == '/' 1374 if (p[0] == '/' && p[1] == '/'
@@ -1494,7 +1492,7 @@ See also the function `substitute-in-file-name'.")
1494#endif 1492#endif
1495 1493
1496/* If /~ or // appears, discard everything through first slash. */ 1494/* If /~ or // appears, discard everything through first slash. */
1497static int 1495static bool
1498file_name_absolute_p (const char *filename) 1496file_name_absolute_p (const char *filename)
1499{ 1497{
1500 return 1498 return
@@ -1560,12 +1558,10 @@ If `//' appears, everything up to and including the first of
1560those `/' is discarded. */) 1558those `/' is discarded. */)
1561 (Lisp_Object filename) 1559 (Lisp_Object filename)
1562{ 1560{
1563 char *nm; 1561 char *nm, *s, *p, *o, *x, *endp;
1564
1565 register char *s, *p, *o, *x, *endp;
1566 char *target = NULL; 1562 char *target = NULL;
1567 int total = 0; 1563 int total = 0;
1568 int substituted = 0; 1564 bool substituted = 0;
1569 bool multibyte; 1565 bool multibyte;
1570 char *xnm; 1566 char *xnm;
1571 Lisp_Object handler; 1567 Lisp_Object handler;
@@ -1780,7 +1776,7 @@ expand_and_dir_to_file (Lisp_Object filename, Lisp_Object defdir)
1780} 1776}
1781 1777
1782/* Signal an error if the file ABSNAME already exists. 1778/* Signal an error if the file ABSNAME already exists.
1783 If INTERACTIVE is nonzero, ask the user whether to proceed, 1779 If INTERACTIVE, ask the user whether to proceed,
1784 and bypass the error if the user says to go ahead. 1780 and bypass the error if the user says to go ahead.
1785 QUERYSTRING is a name for the action that is being considered 1781 QUERYSTRING is a name for the action that is being considered
1786 to alter the file. 1782 to alter the file.
@@ -1789,13 +1785,14 @@ expand_and_dir_to_file (Lisp_Object filename, Lisp_Object defdir)
1789 If the file does not exist, STATPTR->st_mode is set to 0. 1785 If the file does not exist, STATPTR->st_mode is set to 0.
1790 If STATPTR is null, we don't store into it. 1786 If STATPTR is null, we don't store into it.
1791 1787
1792 If QUICK is nonzero, we ask for y or n, not yes or no. */ 1788 If QUICK, ask for y or n, not yes or no. */
1793 1789
1794static void 1790static void
1795barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring, 1791barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring,
1796 int interactive, struct stat *statptr, int quick) 1792 bool interactive, struct stat *statptr,
1793 bool quick)
1797{ 1794{
1798 register Lisp_Object tem, encoded_filename; 1795 Lisp_Object tem, encoded_filename;
1799 struct stat statbuf; 1796 struct stat statbuf;
1800 struct gcpro gcpro1; 1797 struct gcpro gcpro1;
1801 1798
@@ -1869,11 +1866,11 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */)
1869 Lisp_Object handler; 1866 Lisp_Object handler;
1870 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 1867 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1871 ptrdiff_t count = SPECPDL_INDEX (); 1868 ptrdiff_t count = SPECPDL_INDEX ();
1872 int input_file_statable_p; 1869 bool input_file_statable_p;
1873 Lisp_Object encoded_file, encoded_newname; 1870 Lisp_Object encoded_file, encoded_newname;
1874#if HAVE_LIBSELINUX 1871#if HAVE_LIBSELINUX
1875 security_context_t con; 1872 security_context_t con;
1876 int fail, conlength = 0; 1873 int conlength = 0;
1877#endif 1874#endif
1878 1875
1879 encoded_file = encoded_newname = Qnil; 1876 encoded_file = encoded_newname = Qnil;
@@ -1988,7 +1985,7 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */)
1988 S_IREAD | S_IWRITE); 1985 S_IREAD | S_IWRITE);
1989#else /* not MSDOS */ 1986#else /* not MSDOS */
1990 { 1987 {
1991 int new_mask = 0666; 1988 mode_t new_mask = 0666;
1992 if (input_file_statable_p) 1989 if (input_file_statable_p)
1993 { 1990 {
1994 if (!NILP (preserve_uid_gid)) 1991 if (!NILP (preserve_uid_gid))
@@ -2018,7 +2015,7 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */)
2018 owner and group. */ 2015 owner and group. */
2019 if (input_file_statable_p) 2016 if (input_file_statable_p)
2020 { 2017 {
2021 int mode_mask = 07777; 2018 mode_t mode_mask = 07777;
2022 if (!NILP (preserve_uid_gid)) 2019 if (!NILP (preserve_uid_gid))
2023 { 2020 {
2024 /* Attempt to change owner and group. If that doesn't work 2021 /* Attempt to change owner and group. If that doesn't work
@@ -2041,7 +2038,7 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */)
2041 if (conlength > 0) 2038 if (conlength > 0)
2042 { 2039 {
2043 /* Set the modified context back to the file. */ 2040 /* Set the modified context back to the file. */
2044 fail = fsetfilecon (ofd, con); 2041 bool fail = fsetfilecon (ofd, con) != 0;
2045 /* See http://debbugs.gnu.org/11245 for ENOTSUP. */ 2042 /* See http://debbugs.gnu.org/11245 for ENOTSUP. */
2046 if (fail && errno != ENOTSUP) 2043 if (fail && errno != ENOTSUP)
2047 report_file_error ("Doing fsetfilecon", Fcons (newname, Qnil)); 2044 report_file_error ("Doing fsetfilecon", Fcons (newname, Qnil));
@@ -2184,17 +2181,14 @@ internal_delete_file_1 (Lisp_Object ignore)
2184 return Qt; 2181 return Qt;
2185} 2182}
2186 2183
2187/* Delete file FILENAME, returning 1 if successful and 0 if failed. 2184/* Delete file FILENAME.
2188 This ignores `delete-by-moving-to-trash'. */ 2185 This ignores `delete-by-moving-to-trash'. */
2189 2186
2190int 2187void
2191internal_delete_file (Lisp_Object filename) 2188internal_delete_file (Lisp_Object filename)
2192{ 2189{
2193 Lisp_Object tem; 2190 internal_condition_case_2 (Fdelete_file, filename, Qnil,
2194 2191 Qt, internal_delete_file_1);
2195 tem = internal_condition_case_2 (Fdelete_file, filename, Qnil,
2196 Qt, internal_delete_file_1);
2197 return NILP (tem);
2198} 2192}
2199 2193
2200DEFUN ("rename-file", Frename_file, Srename_file, 2, 3, 2194DEFUN ("rename-file", Frename_file, Srename_file, 2, 3,
@@ -2430,9 +2424,9 @@ On Unix, this is a name starting with a `/' or a `~'. */)
2430 return file_name_absolute_p (SSDATA (filename)) ? Qt : Qnil; 2424 return file_name_absolute_p (SSDATA (filename)) ? Qt : Qnil;
2431} 2425}
2432 2426
2433/* Return nonzero if file FILENAME exists and can be executed. */ 2427/* Return true if file FILENAME exists and can be executed. */
2434 2428
2435static int 2429static bool
2436check_executable (char *filename) 2430check_executable (char *filename)
2437{ 2431{
2438#ifdef DOS_NT 2432#ifdef DOS_NT
@@ -2452,9 +2446,9 @@ check_executable (char *filename)
2452#endif /* not DOS_NT */ 2446#endif /* not DOS_NT */
2453} 2447}
2454 2448
2455/* Return nonzero if file FILENAME exists and can be written. */ 2449/* Return true if file FILENAME exists and can be written. */
2456 2450
2457static int 2451static bool
2458check_writable (const char *filename) 2452check_writable (const char *filename)
2459{ 2453{
2460#ifdef MSDOS 2454#ifdef MSDOS
@@ -2464,7 +2458,7 @@ check_writable (const char *filename)
2464 return (st.st_mode & S_IWRITE || S_ISDIR (st.st_mode)); 2458 return (st.st_mode & S_IWRITE || S_ISDIR (st.st_mode));
2465#else /* not MSDOS */ 2459#else /* not MSDOS */
2466#ifdef HAVE_EUIDACCESS 2460#ifdef HAVE_EUIDACCESS
2467 int res = (euidaccess (filename, 2) >= 0); 2461 bool res = (euidaccess (filename, 2) >= 0);
2468#ifdef CYGWIN 2462#ifdef CYGWIN
2469 /* euidaccess may have returned failure because Cygwin couldn't 2463 /* euidaccess may have returned failure because Cygwin couldn't
2470 determine the file's UID or GID; if so, we return success. */ 2464 determine the file's UID or GID; if so, we return success. */
@@ -2732,7 +2726,7 @@ searchable directory. */)
2732 (Lisp_Object filename) 2726 (Lisp_Object filename)
2733{ 2727{
2734 Lisp_Object handler; 2728 Lisp_Object handler;
2735 int tem; 2729 bool tem;
2736 struct gcpro gcpro1; 2730 struct gcpro gcpro1;
2737 2731
2738 /* If the file name has special constructs in it, 2732 /* If the file name has special constructs in it,
@@ -2868,7 +2862,8 @@ compiled with SELinux support. */)
2868 Lisp_Object type = CAR_SAFE (CDR_SAFE (CDR_SAFE (context))); 2862 Lisp_Object type = CAR_SAFE (CDR_SAFE (CDR_SAFE (context)));
2869 Lisp_Object range = CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (context)))); 2863 Lisp_Object range = CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (context))));
2870 security_context_t con; 2864 security_context_t con;
2871 int fail, conlength; 2865 bool fail;
2866 int conlength;
2872 context_t parsed_con; 2867 context_t parsed_con;
2873#endif 2868#endif
2874 2869
@@ -2912,8 +2907,9 @@ compiled with SELinux support. */)
2912 } 2907 }
2913 2908
2914 /* Set the modified context back to the file. */ 2909 /* Set the modified context back to the file. */
2915 fail = lsetfilecon (SSDATA (encoded_absname), 2910 fail = (lsetfilecon (SSDATA (encoded_absname),
2916 context_str (parsed_con)); 2911 context_str (parsed_con))
2912 != 0);
2917 /* See http://debbugs.gnu.org/11245 for ENOTSUP. */ 2913 /* See http://debbugs.gnu.org/11245 for ENOTSUP. */
2918 if (fail && errno != ENOTSUP) 2914 if (fail && errno != ENOTSUP)
2919 report_file_error ("Doing lsetfilecon", Fcons (absname, Qnil)); 2915 report_file_error ("Doing lsetfilecon", Fcons (absname, Qnil));
@@ -3004,7 +3000,7 @@ DEFUN ("default-file-modes", Fdefault_file_modes, Sdefault_file_modes, 0, 0, 0,
3004The value is an integer. */) 3000The value is an integer. */)
3005 (void) 3001 (void)
3006{ 3002{
3007 int realmask; 3003 mode_t realmask;
3008 Lisp_Object value; 3004 Lisp_Object value;
3009 3005
3010 BLOCK_INPUT; 3006 BLOCK_INPUT;
@@ -3246,29 +3242,29 @@ variable `last-coding-system-used' to the coding system actually used. */)
3246 struct stat st; 3242 struct stat st;
3247 int file_status; 3243 int file_status;
3248 EMACS_TIME mtime; 3244 EMACS_TIME mtime;
3249 register int fd; 3245 int fd;
3250 ptrdiff_t inserted = 0; 3246 ptrdiff_t inserted = 0;
3251 int nochange = 0; 3247 bool nochange = 0;
3252 register ptrdiff_t how_much; 3248 ptrdiff_t how_much;
3253 off_t beg_offset, end_offset; 3249 off_t beg_offset, end_offset;
3254 register int unprocessed; 3250 int unprocessed;
3255 ptrdiff_t count = SPECPDL_INDEX (); 3251 ptrdiff_t count = SPECPDL_INDEX ();
3256 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 3252 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3257 Lisp_Object handler, val, insval, orig_filename, old_undo; 3253 Lisp_Object handler, val, insval, orig_filename, old_undo;
3258 Lisp_Object p; 3254 Lisp_Object p;
3259 ptrdiff_t total = 0; 3255 ptrdiff_t total = 0;
3260 int not_regular = 0; 3256 bool not_regular = 0;
3261 int save_errno = 0; 3257 int save_errno = 0;
3262 char read_buf[READ_BUF_SIZE]; 3258 char read_buf[READ_BUF_SIZE];
3263 struct coding_system coding; 3259 struct coding_system coding;
3264 char buffer[1 << 14]; 3260 char buffer[1 << 14];
3265 int replace_handled = 0; 3261 bool replace_handled = 0;
3266 int set_coding_system = 0; 3262 bool set_coding_system = 0;
3267 Lisp_Object coding_system; 3263 Lisp_Object coding_system;
3268 int read_quit = 0; 3264 bool read_quit = 0;
3269 Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark; 3265 Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark;
3270 int we_locked_file = 0; 3266 bool we_locked_file = 0;
3271 int deferred_remove_unwind_protect = 0; 3267 bool deferred_remove_unwind_protect = 0;
3272 3268
3273 if (current_buffer->base_buffer && ! NILP (visit)) 3269 if (current_buffer->base_buffer && ! NILP (visit))
3274 error ("Cannot do file visiting in an indirect buffer"); 3270 error ("Cannot do file visiting in an indirect buffer");
@@ -3569,9 +3565,9 @@ variable `last-coding-system-used' to the coding system actually used. */)
3569 ptrdiff_t same_at_end = ZV_BYTE; 3565 ptrdiff_t same_at_end = ZV_BYTE;
3570 ptrdiff_t overlap; 3566 ptrdiff_t overlap;
3571 /* There is still a possibility we will find the need to do code 3567 /* There is still a possibility we will find the need to do code
3572 conversion. If that happens, we set this variable to 1 to 3568 conversion. If that happens, set this variable to
3573 give up on handling REPLACE in the optimized way. */ 3569 give up on handling REPLACE in the optimized way. */
3574 int giveup_match_end = 0; 3570 bool giveup_match_end = 0;
3575 3571
3576 if (beg_offset != 0) 3572 if (beg_offset != 0)
3577 { 3573 {
@@ -4427,8 +4423,8 @@ choose_write_coding_system (Lisp_Object start, Lisp_Object end, Lisp_Object file
4427 If it is not set locally, we anyway have to convert EOL 4423 If it is not set locally, we anyway have to convert EOL
4428 format if the default value of `buffer-file-coding-system' 4424 format if the default value of `buffer-file-coding-system'
4429 tells that it is not Unix-like (LF only) format. */ 4425 tells that it is not Unix-like (LF only) format. */
4430 int using_default_coding = 0; 4426 bool using_default_coding = 0;
4431 int force_raw_text = 0; 4427 bool force_raw_text = 0;
4432 4428
4433 val = BVAR (current_buffer, buffer_file_coding_system); 4429 val = BVAR (current_buffer, buffer_file_coding_system);
4434 if (NILP (val) 4430 if (NILP (val)
@@ -4537,8 +4533,8 @@ This calls `write-region-annotate-functions' at the start, and
4537`write-region-post-annotation-function' at the end. */) 4533`write-region-post-annotation-function' at the end. */)
4538 (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) 4534 (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew)
4539{ 4535{
4540 register int desc; 4536 int desc;
4541 int failure; 4537 bool ok;
4542 int save_errno = 0; 4538 int save_errno = 0;
4543 const char *fn; 4539 const char *fn;
4544 struct stat st; 4540 struct stat st;
@@ -4548,8 +4544,8 @@ This calls `write-region-annotate-functions' at the start, and
4548 Lisp_Object visit_file; 4544 Lisp_Object visit_file;
4549 Lisp_Object annotations; 4545 Lisp_Object annotations;
4550 Lisp_Object encoded_filename; 4546 Lisp_Object encoded_filename;
4551 int visiting = (EQ (visit, Qt) || STRINGP (visit)); 4547 bool visiting = (EQ (visit, Qt) || STRINGP (visit));
4552 int quietly = !NILP (visit); 4548 bool quietly = !NILP (visit);
4553 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 4549 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
4554 struct buffer *given_buffer; 4550 struct buffer *given_buffer;
4555 struct coding_system coding; 4551 struct coding_system coding;
@@ -4713,37 +4709,27 @@ This calls `write-region-annotate-functions' at the start, and
4713 4709
4714 UNGCPRO; 4710 UNGCPRO;
4715 4711
4716 failure = 0;
4717 immediate_quit = 1; 4712 immediate_quit = 1;
4718 4713
4719 if (STRINGP (start)) 4714 if (STRINGP (start))
4720 { 4715 ok = a_write (desc, start, 0, SCHARS (start), &annotations, &coding);
4721 failure = 0 > a_write (desc, start, 0, SCHARS (start),
4722 &annotations, &coding);
4723 save_errno = errno;
4724 }
4725 else if (XINT (start) != XINT (end)) 4716 else if (XINT (start) != XINT (end))
4726 { 4717 ok = a_write (desc, Qnil, XINT (start), XINT (end) - XINT (start),
4727 failure = 0 > a_write (desc, Qnil, 4718 &annotations, &coding);
4728 XINT (start), XINT (end) - XINT (start),
4729 &annotations, &coding);
4730 save_errno = errno;
4731 }
4732 else 4719 else
4733 { 4720 {
4734 /* If file was empty, still need to write the annotations */ 4721 /* If file was empty, still need to write the annotations. */
4735 coding.mode |= CODING_MODE_LAST_BLOCK; 4722 coding.mode |= CODING_MODE_LAST_BLOCK;
4736 failure = 0 > a_write (desc, Qnil, XINT (end), 0, &annotations, &coding); 4723 ok = a_write (desc, Qnil, XINT (end), 0, &annotations, &coding);
4737 save_errno = errno;
4738 } 4724 }
4725 save_errno = errno;
4739 4726
4740 if (CODING_REQUIRE_FLUSHING (&coding) 4727 if (ok && CODING_REQUIRE_FLUSHING (&coding)
4741 && !(coding.mode & CODING_MODE_LAST_BLOCK) 4728 && !(coding.mode & CODING_MODE_LAST_BLOCK))
4742 && ! failure)
4743 { 4729 {
4744 /* We have to flush out a data. */ 4730 /* We have to flush out a data. */
4745 coding.mode |= CODING_MODE_LAST_BLOCK; 4731 coding.mode |= CODING_MODE_LAST_BLOCK;
4746 failure = 0 > e_write (desc, Qnil, 1, 1, &coding); 4732 ok = e_write (desc, Qnil, 1, 1, &coding);
4747 save_errno = errno; 4733 save_errno = errno;
4748 } 4734 }
4749 4735
@@ -4760,13 +4746,13 @@ This calls `write-region-annotate-functions' at the start, and
4760 ignore EINVAL which happens when fsync is not supported on this 4746 ignore EINVAL which happens when fsync is not supported on this
4761 file. */ 4747 file. */
4762 if (errno != EINTR && errno != EINVAL) 4748 if (errno != EINTR && errno != EINVAL)
4763 failure = 1, save_errno = errno; 4749 ok = 0, save_errno = errno;
4764 } 4750 }
4765#endif 4751#endif
4766 4752
4767 /* NFS can report a write failure now. */ 4753 /* NFS can report a write failure now. */
4768 if (emacs_close (desc) < 0) 4754 if (emacs_close (desc) < 0)
4769 failure = 1, save_errno = errno; 4755 ok = 0, save_errno = errno;
4770 4756
4771 stat (fn, &st); 4757 stat (fn, &st);
4772 4758
@@ -4803,7 +4789,7 @@ This calls `write-region-annotate-functions' at the start, and
4803 current_buffer->modtime_size = st.st_size; 4789 current_buffer->modtime_size = st.st_size;
4804 } 4790 }
4805 4791
4806 if (failure) 4792 if (! ok)
4807 error ("IO error writing %s: %s", SDATA (filename), 4793 error ("IO error writing %s: %s", SDATA (filename),
4808 emacs_strerror (save_errno)); 4794 emacs_strerror (save_errno));
4809 4795
@@ -4859,7 +4845,8 @@ build_annotations (Lisp_Object start, Lisp_Object end)
4859 Lisp_Object p, res; 4845 Lisp_Object p, res;
4860 struct gcpro gcpro1, gcpro2; 4846 struct gcpro gcpro1, gcpro2;
4861 Lisp_Object original_buffer; 4847 Lisp_Object original_buffer;
4862 int i, used_global = 0; 4848 int i;
4849 bool used_global = 0;
4863 4850
4864 XSETBUFFER (original_buffer, current_buffer); 4851 XSETBUFFER (original_buffer, current_buffer);
4865 4852
@@ -4939,11 +4926,11 @@ build_annotations (Lisp_Object start, Lisp_Object end)
4939 4926
4940 We modify *ANNOT by discarding elements as we use them up. 4927 We modify *ANNOT by discarding elements as we use them up.
4941 4928
4942 The return value is negative in case of system call failure. */ 4929 Return true if successful. */
4943 4930
4944static int 4931static bool
4945a_write (int desc, Lisp_Object string, ptrdiff_t pos, 4932a_write (int desc, Lisp_Object string, ptrdiff_t pos,
4946 register ptrdiff_t nchars, Lisp_Object *annot, 4933 ptrdiff_t nchars, Lisp_Object *annot,
4947 struct coding_system *coding) 4934 struct coding_system *coding)
4948{ 4935{
4949 Lisp_Object tem; 4936 Lisp_Object tem;
@@ -4965,29 +4952,29 @@ a_write (int desc, Lisp_Object string, ptrdiff_t pos,
4965 /* Output buffer text up to the next annotation's position. */ 4952 /* Output buffer text up to the next annotation's position. */
4966 if (nextpos > pos) 4953 if (nextpos > pos)
4967 { 4954 {
4968 if (0 > e_write (desc, string, pos, nextpos, coding)) 4955 if (!e_write (desc, string, pos, nextpos, coding))
4969 return -1; 4956 return 0;
4970 pos = nextpos; 4957 pos = nextpos;
4971 } 4958 }
4972 /* Output the annotation. */ 4959 /* Output the annotation. */
4973 tem = Fcdr (Fcar (*annot)); 4960 tem = Fcdr (Fcar (*annot));
4974 if (STRINGP (tem)) 4961 if (STRINGP (tem))
4975 { 4962 {
4976 if (0 > e_write (desc, tem, 0, SCHARS (tem), coding)) 4963 if (!e_write (desc, tem, 0, SCHARS (tem), coding))
4977 return -1; 4964 return 0;
4978 } 4965 }
4979 *annot = Fcdr (*annot); 4966 *annot = Fcdr (*annot);
4980 } 4967 }
4981 return 0; 4968 return 1;
4982} 4969}
4983 4970
4984 4971
4985/* Write text in the range START and END into descriptor DESC, 4972/* Write text in the range START and END into descriptor DESC,
4986 encoding them with coding system CODING. If STRING is nil, START 4973 encoding them with coding system CODING. If STRING is nil, START
4987 and END are character positions of the current buffer, else they 4974 and END are character positions of the current buffer, else they
4988 are indexes to the string STRING. */ 4975 are indexes to the string STRING. Return true if successful. */
4989 4976
4990static int 4977static bool
4991e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end, 4978e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end,
4992 struct coding_system *coding) 4979 struct coding_system *coding)
4993{ 4980{
@@ -5056,12 +5043,12 @@ e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end,
5056 coding->produced); 5043 coding->produced);
5057 5044
5058 if (coding->produced) 5045 if (coding->produced)
5059 return -1; 5046 return 0;
5060 } 5047 }
5061 start += coding->consumed_char; 5048 start += coding->consumed_char;
5062 } 5049 }
5063 5050
5064 return 0; 5051 return 1;
5065} 5052}
5066 5053
5067DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, 5054DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime,
@@ -5300,12 +5287,12 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5300{ 5287{
5301 struct buffer *old = current_buffer, *b; 5288 struct buffer *old = current_buffer, *b;
5302 Lisp_Object tail, buf, hook; 5289 Lisp_Object tail, buf, hook;
5303 int auto_saved = 0; 5290 bool auto_saved = 0;
5304 int do_handled_files; 5291 int do_handled_files;
5305 Lisp_Object oquit; 5292 Lisp_Object oquit;
5306 FILE *stream = NULL; 5293 FILE *stream = NULL;
5307 ptrdiff_t count = SPECPDL_INDEX (); 5294 ptrdiff_t count = SPECPDL_INDEX ();
5308 int orig_minibuffer_auto_raise = minibuffer_auto_raise; 5295 bool orig_minibuffer_auto_raise = minibuffer_auto_raise;
5309 bool old_message_p = 0; 5296 bool old_message_p = 0;
5310 struct gcpro gcpro1, gcpro2; 5297 struct gcpro gcpro1, gcpro2;
5311 5298
@@ -5452,7 +5439,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */)
5452 if (!auto_saved && NILP (no_message)) 5439 if (!auto_saved && NILP (no_message))
5453 message1 ("Auto-saving..."); 5440 message1 ("Auto-saving...");
5454 internal_condition_case (auto_save_1, Qt, auto_save_error); 5441 internal_condition_case (auto_save_1, Qt, auto_save_error);
5455 auto_saved++; 5442 auto_saved = 1;
5456 BUF_AUTOSAVE_MODIFF (b) = BUF_MODIFF (b); 5443 BUF_AUTOSAVE_MODIFF (b) = BUF_MODIFF (b);
5457 XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG); 5444 XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG);
5458 set_buffer_internal (old); 5445 set_buffer_internal (old);
diff --git a/src/filelock.c b/src/filelock.c
index d21d8e7ba02..1f599c68912 100644
--- a/src/filelock.c
+++ b/src/filelock.c
@@ -100,10 +100,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
100/* Return the time of the last system boot. */ 100/* Return the time of the last system boot. */
101 101
102static time_t boot_time; 102static time_t boot_time;
103static int boot_time_initialized; 103static bool boot_time_initialized;
104 104
105#ifdef BOOT_TIME 105#ifdef BOOT_TIME
106static void get_boot_time_1 (const char *, int); 106static void get_boot_time_1 (const char *, bool);
107#endif 107#endif
108 108
109static time_t 109static time_t
@@ -170,7 +170,7 @@ get_boot_time (void)
170 { 170 {
171 char cmd_string[sizeof WTMP_FILE ".19.gz"]; 171 char cmd_string[sizeof WTMP_FILE ".19.gz"];
172 Lisp_Object tempname, filename; 172 Lisp_Object tempname, filename;
173 int delete_flag = 0; 173 bool delete_flag = 0;
174 174
175 filename = Qnil; 175 filename = Qnil;
176 176
@@ -225,13 +225,13 @@ get_boot_time (void)
225 225
226 If FILENAME is zero, use the same file as before; 226 If FILENAME is zero, use the same file as before;
227 if no FILENAME has ever been specified, this is the utmp file. 227 if no FILENAME has ever been specified, this is the utmp file.
228 Use the newest reboot record if NEWEST is nonzero, 228 Use the newest reboot record if NEWEST,
229 the first reboot record otherwise. 229 the first reboot record otherwise.
230 Ignore all reboot records on or before BOOT_TIME. 230 Ignore all reboot records on or before BOOT_TIME.
231 Success is indicated by setting BOOT_TIME to a larger value. */ 231 Success is indicated by setting BOOT_TIME to a larger value. */
232 232
233void 233void
234get_boot_time_1 (const char *filename, int newest) 234get_boot_time_1 (const char *filename, bool newest)
235{ 235{
236 struct utmp ut, *utp; 236 struct utmp ut, *utp;
237 int desc; 237 int desc;
@@ -331,11 +331,11 @@ fill_in_lock_file_name (register char *lockfile, register Lisp_Object fn)
331} 331}
332 332
333/* Lock the lock file named LFNAME. 333/* Lock the lock file named LFNAME.
334 If FORCE is nonzero, we do so even if it is already locked. 334 If FORCE, do so even if it is already locked.
335 Return 1 if successful, 0 if not. */ 335 Return true if successful. */
336 336
337static int 337static bool
338lock_file_1 (char *lfname, int force) 338lock_file_1 (char *lfname, bool force)
339{ 339{
340 int err; 340 int err;
341 int symlink_errno; 341 int symlink_errno;
@@ -370,9 +370,9 @@ lock_file_1 (char *lfname, int force)
370 return err == 0; 370 return err == 0;
371} 371}
372 372
373/* Return 1 if times A and B are no more than one second apart. */ 373/* Return true if times A and B are no more than one second apart. */
374 374
375static int 375static bool
376within_one_second (time_t a, time_t b) 376within_one_second (time_t a, time_t b)
377{ 377{
378 return (a - b >= -1 && a - b <= 1); 378 return (a - b >= -1 && a - b <= 1);
@@ -491,7 +491,7 @@ current_lock_owner (lock_info_type *owner, char *lfname)
491static int 491static int
492lock_if_free (lock_info_type *clasher, register char *lfname) 492lock_if_free (lock_info_type *clasher, register char *lfname)
493{ 493{
494 while (lock_file_1 (lfname, 0) == 0) 494 while (! lock_file_1 (lfname, 0))
495 { 495 {
496 int locker; 496 int locker;
497 497
diff --git a/src/floatfns.c b/src/floatfns.c
index cad071f1e15..f59cf58228a 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -37,9 +37,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
37 Define FLOAT_CHECK_ERRNO if the float library routines set errno. 37 Define FLOAT_CHECK_ERRNO if the float library routines set errno.
38 This has no effect if HAVE_MATHERR is defined. 38 This has no effect if HAVE_MATHERR is defined.
39 39
40 Define FLOAT_CATCH_SIGILL if the float library routines signal SIGILL.
41 (What systems actually do this? Please let us know.)
42
43 Define FLOAT_CHECK_DOMAIN if the float library doesn't handle errors by 40 Define FLOAT_CHECK_DOMAIN if the float library doesn't handle errors by
44 either setting errno, or signaling SIGFPE/SIGILL. Otherwise, domain and 41 either setting errno, or signaling SIGFPE/SIGILL. Otherwise, domain and
45 range checking will happen before calling the float routines. This has 42 range checking will happen before calling the float routines. This has
@@ -99,14 +96,10 @@ extern double logb (double);
99# include <errno.h> 96# include <errno.h>
100#endif 97#endif
101 98
102#ifdef FLOAT_CATCH_SIGILL 99/* True while executing in floating point.
103static void float_error ();
104#endif
105
106/* Nonzero while executing in floating point.
107 This tells float_error what to do. */ 100 This tells float_error what to do. */
108 101
109static int in_float; 102static bool in_float;
110 103
111/* If an argument is out of range for a mathematical function, 104/* If an argument is out of range for a mathematical function,
112 here is the actual argument value to use in the error message. 105 here is the actual argument value to use in the error message.
@@ -947,31 +940,6 @@ Rounds the value toward zero. */)
947 return make_float (d); 940 return make_float (d);
948} 941}
949 942
950#ifdef FLOAT_CATCH_SIGILL
951static void
952float_error (int signo)
953{
954 if (! in_float)
955 fatal_error_signal (signo);
956
957#ifdef BSD_SYSTEM
958 sigsetmask (SIGEMPTYMASK);
959#else
960 /* Must reestablish handler each time it is called. */
961 signal (SIGILL, float_error);
962#endif /* BSD_SYSTEM */
963
964 SIGNAL_THREAD_CHECK (signo);
965 in_float = 0;
966
967 xsignal1 (Qarith_error, float_error_arg);
968}
969
970/* Another idea was to replace the library function `infnan'
971 where SIGILL is signaled. */
972
973#endif /* FLOAT_CATCH_SIGILL */
974
975#ifdef HAVE_MATHERR 943#ifdef HAVE_MATHERR
976int 944int
977matherr (struct exception *x) 945matherr (struct exception *x)
@@ -1006,9 +974,6 @@ matherr (struct exception *x)
1006void 974void
1007init_floatfns (void) 975init_floatfns (void)
1008{ 976{
1009#ifdef FLOAT_CATCH_SIGILL
1010 signal (SIGILL, float_error);
1011#endif
1012 in_float = 0; 977 in_float = 0;
1013} 978}
1014 979
diff --git a/src/fns.c b/src/fns.c
index fc0044106cd..20770af67d4 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -51,7 +51,7 @@ static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper;
51 51
52static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; 52static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512;
53 53
54static int internal_equal (Lisp_Object , Lisp_Object, int, int); 54static bool internal_equal (Lisp_Object, Lisp_Object, int, bool);
55 55
56DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, 56DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
57 doc: /* Return the argument unchanged. */) 57 doc: /* Return the argument unchanged. */)
@@ -352,7 +352,7 @@ Symbols are also allowed; their print names are used instead. */)
352} 352}
353 353
354static Lisp_Object concat (ptrdiff_t nargs, Lisp_Object *args, 354static Lisp_Object concat (ptrdiff_t nargs, Lisp_Object *args,
355 enum Lisp_Type target_type, int last_special); 355 enum Lisp_Type target_type, bool last_special);
356 356
357/* ARGSUSED */ 357/* ARGSUSED */
358Lisp_Object 358Lisp_Object
@@ -450,19 +450,19 @@ struct textprop_rec
450 450
451static Lisp_Object 451static Lisp_Object
452concat (ptrdiff_t nargs, Lisp_Object *args, 452concat (ptrdiff_t nargs, Lisp_Object *args,
453 enum Lisp_Type target_type, int last_special) 453 enum Lisp_Type target_type, bool last_special)
454{ 454{
455 Lisp_Object val; 455 Lisp_Object val;
456 register Lisp_Object tail; 456 Lisp_Object tail;
457 register Lisp_Object this; 457 Lisp_Object this;
458 ptrdiff_t toindex; 458 ptrdiff_t toindex;
459 ptrdiff_t toindex_byte = 0; 459 ptrdiff_t toindex_byte = 0;
460 register EMACS_INT result_len; 460 EMACS_INT result_len;
461 register EMACS_INT result_len_byte; 461 EMACS_INT result_len_byte;
462 ptrdiff_t argnum; 462 ptrdiff_t argnum;
463 Lisp_Object last_tail; 463 Lisp_Object last_tail;
464 Lisp_Object prev; 464 Lisp_Object prev;
465 int some_multibyte; 465 bool some_multibyte;
466 /* When we make a multibyte string, we can't copy text properties 466 /* When we make a multibyte string, we can't copy text properties
467 while concatenating each string because the length of resulting 467 while concatenating each string because the length of resulting
468 string can't be decided until we finish the whole concatenation. 468 string can't be decided until we finish the whole concatenation.
@@ -1988,10 +1988,10 @@ of strings. (`equal' ignores text properties.) */)
1988 1988
1989/* DEPTH is current depth of recursion. Signal an error if it 1989/* DEPTH is current depth of recursion. Signal an error if it
1990 gets too deep. 1990 gets too deep.
1991 PROPS, if non-nil, means compare string text properties too. */ 1991 PROPS means compare string text properties too. */
1992 1992
1993static int 1993static bool
1994internal_equal (register Lisp_Object o1, register Lisp_Object o2, int depth, int props) 1994internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props)
1995{ 1995{
1996 if (depth > 200) 1996 if (depth > 200)
1997 error ("Stack overflow in equal"); 1997 error ("Stack overflow in equal");
@@ -2589,9 +2589,9 @@ Normally the return value is FEATURE.
2589The normal messages at start and end of loading FILENAME are suppressed. */) 2589The normal messages at start and end of loading FILENAME are suppressed. */)
2590 (Lisp_Object feature, Lisp_Object filename, Lisp_Object noerror) 2590 (Lisp_Object feature, Lisp_Object filename, Lisp_Object noerror)
2591{ 2591{
2592 register Lisp_Object tem; 2592 Lisp_Object tem;
2593 struct gcpro gcpro1, gcpro2; 2593 struct gcpro gcpro1, gcpro2;
2594 int from_file = load_in_progress; 2594 bool from_file = load_in_progress;
2595 2595
2596 CHECK_SYMBOL (feature); 2596 CHECK_SYMBOL (feature);
2597 2597
@@ -2917,8 +2917,8 @@ static const short base64_char_to_value[128] =
2917 base64 characters. */ 2917 base64 characters. */
2918 2918
2919 2919
2920static ptrdiff_t base64_encode_1 (const char *, char *, ptrdiff_t, int, int); 2920static ptrdiff_t base64_encode_1 (const char *, char *, ptrdiff_t, bool, bool);
2921static ptrdiff_t base64_decode_1 (const char *, char *, ptrdiff_t, int, 2921static ptrdiff_t base64_decode_1 (const char *, char *, ptrdiff_t, bool,
2922 ptrdiff_t *); 2922 ptrdiff_t *);
2923 2923
2924DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region, 2924DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region,
@@ -3026,7 +3026,7 @@ into shorter lines. */)
3026 3026
3027static ptrdiff_t 3027static ptrdiff_t
3028base64_encode_1 (const char *from, char *to, ptrdiff_t length, 3028base64_encode_1 (const char *from, char *to, ptrdiff_t length,
3029 int line_break, int multibyte) 3029 bool line_break, bool multibyte)
3030{ 3030{
3031 int counter = 0; 3031 int counter = 0;
3032 ptrdiff_t i = 0; 3032 ptrdiff_t i = 0;
@@ -3133,7 +3133,7 @@ If the region can't be decoded, signal an error and don't modify the buffer. */
3133 ptrdiff_t old_pos = PT; 3133 ptrdiff_t old_pos = PT;
3134 ptrdiff_t decoded_length; 3134 ptrdiff_t decoded_length;
3135 ptrdiff_t inserted_chars; 3135 ptrdiff_t inserted_chars;
3136 int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); 3136 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
3137 USE_SAFE_ALLOCA; 3137 USE_SAFE_ALLOCA;
3138 3138
3139 validate_region (&beg, &end); 3139 validate_region (&beg, &end);
@@ -3218,13 +3218,13 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string,
3218} 3218}
3219 3219
3220/* Base64-decode the data at FROM of LENGTH bytes into TO. If 3220/* Base64-decode the data at FROM of LENGTH bytes into TO. If
3221 MULTIBYTE is nonzero, the decoded result should be in multibyte 3221 MULTIBYTE, the decoded result should be in multibyte
3222 form. If NCHARS_RETURN is not NULL, store the number of produced 3222 form. If NCHARS_RETURN is not NULL, store the number of produced
3223 characters in *NCHARS_RETURN. */ 3223 characters in *NCHARS_RETURN. */
3224 3224
3225static ptrdiff_t 3225static ptrdiff_t
3226base64_decode_1 (const char *from, char *to, ptrdiff_t length, 3226base64_decode_1 (const char *from, char *to, ptrdiff_t length,
3227 int multibyte, ptrdiff_t *nchars_return) 3227 bool multibyte, ptrdiff_t *nchars_return)
3228{ 3228{
3229 ptrdiff_t i = 0; /* Used inside READ_QUADRUPLET_BYTE */ 3229 ptrdiff_t i = 0; /* Used inside READ_QUADRUPLET_BYTE */
3230 char *e = to; 3230 char *e = to;
@@ -3340,7 +3340,7 @@ static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value;
3340static struct Lisp_Hash_Table *check_hash_table (Lisp_Object); 3340static struct Lisp_Hash_Table *check_hash_table (Lisp_Object);
3341static ptrdiff_t get_key_arg (Lisp_Object, ptrdiff_t, Lisp_Object *, char *); 3341static ptrdiff_t get_key_arg (Lisp_Object, ptrdiff_t, Lisp_Object *, char *);
3342static void maybe_resize_hash_table (struct Lisp_Hash_Table *); 3342static void maybe_resize_hash_table (struct Lisp_Hash_Table *);
3343static int sweep_weak_table (struct Lisp_Hash_Table *, int); 3343static bool sweep_weak_table (struct Lisp_Hash_Table *, bool);
3344 3344
3345 3345
3346 3346
@@ -3432,10 +3432,10 @@ larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
3432 ***********************************************************************/ 3432 ***********************************************************************/
3433 3433
3434/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code 3434/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code
3435 HASH2 in hash table H using `eql'. Value is non-zero if KEY1 and 3435 HASH2 in hash table H using `eql'. Value is true if KEY1 and
3436 KEY2 are the same. */ 3436 KEY2 are the same. */
3437 3437
3438static int 3438static bool
3439cmpfn_eql (struct Lisp_Hash_Table *h, 3439cmpfn_eql (struct Lisp_Hash_Table *h,
3440 Lisp_Object key1, EMACS_UINT hash1, 3440 Lisp_Object key1, EMACS_UINT hash1,
3441 Lisp_Object key2, EMACS_UINT hash2) 3441 Lisp_Object key2, EMACS_UINT hash2)
@@ -3447,10 +3447,10 @@ cmpfn_eql (struct Lisp_Hash_Table *h,
3447 3447
3448 3448
3449/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code 3449/* Compare KEY1 which has hash code HASH1 and KEY2 with hash code
3450 HASH2 in hash table H using `equal'. Value is non-zero if KEY1 and 3450 HASH2 in hash table H using `equal'. Value is true if KEY1 and
3451 KEY2 are the same. */ 3451 KEY2 are the same. */
3452 3452
3453static int 3453static bool
3454cmpfn_equal (struct Lisp_Hash_Table *h, 3454cmpfn_equal (struct Lisp_Hash_Table *h,
3455 Lisp_Object key1, EMACS_UINT hash1, 3455 Lisp_Object key1, EMACS_UINT hash1,
3456 Lisp_Object key2, EMACS_UINT hash2) 3456 Lisp_Object key2, EMACS_UINT hash2)
@@ -3460,10 +3460,10 @@ cmpfn_equal (struct Lisp_Hash_Table *h,
3460 3460
3461 3461
3462/* Compare KEY1 which has hash code HASH1, and KEY2 with hash code 3462/* Compare KEY1 which has hash code HASH1, and KEY2 with hash code
3463 HASH2 in hash table H using H->user_cmp_function. Value is non-zero 3463 HASH2 in hash table H using H->user_cmp_function. Value is true
3464 if KEY1 and KEY2 are the same. */ 3464 if KEY1 and KEY2 are the same. */
3465 3465
3466static int 3466static bool
3467cmpfn_user_defined (struct Lisp_Hash_Table *h, 3467cmpfn_user_defined (struct Lisp_Hash_Table *h,
3468 Lisp_Object key1, EMACS_UINT hash1, 3468 Lisp_Object key1, EMACS_UINT hash1,
3469 Lisp_Object key2, EMACS_UINT hash2) 3469 Lisp_Object key2, EMACS_UINT hash2)
@@ -3923,16 +3923,16 @@ hash_clear (struct Lisp_Hash_Table *h)
3923 Weak Hash Tables 3923 Weak Hash Tables
3924 ************************************************************************/ 3924 ************************************************************************/
3925 3925
3926/* Sweep weak hash table H. REMOVE_ENTRIES_P non-zero means remove 3926/* Sweep weak hash table H. REMOVE_ENTRIES_P means remove
3927 entries from the table that don't survive the current GC. 3927 entries from the table that don't survive the current GC.
3928 REMOVE_ENTRIES_P zero means mark entries that are in use. Value is 3928 !REMOVE_ENTRIES_P means mark entries that are in use. Value is
3929 non-zero if anything was marked. */ 3929 true if anything was marked. */
3930 3930
3931static int 3931static bool
3932sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p) 3932sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p)
3933{ 3933{
3934 ptrdiff_t bucket, n; 3934 ptrdiff_t bucket, n;
3935 int marked; 3935 bool marked;
3936 3936
3937 n = ASIZE (h->index) & ~ARRAY_MARK_FLAG; 3937 n = ASIZE (h->index) & ~ARRAY_MARK_FLAG;
3938 marked = 0; 3938 marked = 0;
@@ -3949,7 +3949,7 @@ sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p)
3949 ptrdiff_t i = XFASTINT (idx); 3949 ptrdiff_t i = XFASTINT (idx);
3950 bool key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i)); 3950 bool key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i));
3951 bool value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i)); 3951 bool value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i));
3952 int remove_p; 3952 bool remove_p;
3953 3953
3954 if (EQ (h->weak, Qkey)) 3954 if (EQ (h->weak, Qkey))
3955 remove_p = !key_known_to_survive_p; 3955 remove_p = !key_known_to_survive_p;
@@ -4022,7 +4022,7 @@ void
4022sweep_weak_hash_tables (void) 4022sweep_weak_hash_tables (void)
4023{ 4023{
4024 struct Lisp_Hash_Table *h, *used, *next; 4024 struct Lisp_Hash_Table *h, *used, *next;
4025 int marked; 4025 bool marked;
4026 4026
4027 /* Mark all keys and values that are in use. Keep on marking until 4027 /* Mark all keys and values that are in use. Keep on marking until
4028 there is no more change. This is necessary for cases like 4028 there is no more change. This is necessary for cases like
@@ -4674,7 +4674,7 @@ secure_hash (Lisp_Object algorithm, Lisp_Object object, Lisp_Object start, Lisp_
4674 coding_system = Vcoding_system_for_write; 4674 coding_system = Vcoding_system_for_write;
4675 else 4675 else
4676 { 4676 {
4677 int force_raw_text = 0; 4677 bool force_raw_text = 0;
4678 4678
4679 coding_system = BVAR (XBUFFER (object), buffer_file_coding_system); 4679 coding_system = BVAR (XBUFFER (object), buffer_file_coding_system);
4680 if (NILP (coding_system) 4680 if (NILP (coding_system)
diff --git a/src/frame.h b/src/frame.h
index 94498e9efcf..661ea2ea67c 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -81,9 +81,6 @@ enum fullscreen_type
81#define FRAME_FOREGROUND_PIXEL(f) ((f)->foreground_pixel) 81#define FRAME_FOREGROUND_PIXEL(f) ((f)->foreground_pixel)
82#define FRAME_BACKGROUND_PIXEL(f) ((f)->background_pixel) 82#define FRAME_BACKGROUND_PIXEL(f) ((f)->background_pixel)
83 83
84struct terminal;
85
86struct font_driver_list;
87 84
88struct frame 85struct frame
89{ 86{
diff --git a/src/keyboard.c b/src/keyboard.c
index fe5372e008c..128f9280911 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -449,9 +449,8 @@ static void restore_getcjmp (jmp_buf);
449static Lisp_Object apply_modifiers (int, Lisp_Object); 449static Lisp_Object apply_modifiers (int, Lisp_Object);
450static void clear_event (struct input_event *); 450static void clear_event (struct input_event *);
451static Lisp_Object restore_kboard_configuration (Lisp_Object); 451static Lisp_Object restore_kboard_configuration (Lisp_Object);
452static void interrupt_signal (int signalnum);
453#ifdef SIGIO 452#ifdef SIGIO
454static void input_available_signal (int signo); 453static void deliver_input_available_signal (int signo);
455#endif 454#endif
456static void handle_interrupt (void); 455static void handle_interrupt (void);
457static _Noreturn void quit_throw_to_read_char (int); 456static _Noreturn void quit_throw_to_read_char (int);
@@ -459,7 +458,7 @@ static void process_special_events (void);
459static void timer_start_idle (void); 458static void timer_start_idle (void);
460static void timer_stop_idle (void); 459static void timer_stop_idle (void);
461static void timer_resume_idle (void); 460static void timer_resume_idle (void);
462static void handle_user_signal (int); 461static void deliver_user_signal (int);
463static char *find_user_signal_name (int); 462static char *find_user_signal_name (int);
464static int store_user_signal_events (void); 463static int store_user_signal_events (void);
465 464
@@ -3833,7 +3832,7 @@ kbd_buffer_get_event (KBOARD **kbp,
3833 unhold_keyboard_input (); 3832 unhold_keyboard_input ();
3834#ifdef SIGIO 3833#ifdef SIGIO
3835 if (!noninteractive) 3834 if (!noninteractive)
3836 signal (SIGIO, input_available_signal); 3835 signal (SIGIO, deliver_input_available_signal);
3837#endif /* SIGIO */ 3836#endif /* SIGIO */
3838 start_polling (); 3837 start_polling ();
3839 } 3838 }
@@ -7236,12 +7235,8 @@ process_pending_signals (void)
7236/* Note SIGIO has been undef'd if FIONREAD is missing. */ 7235/* Note SIGIO has been undef'd if FIONREAD is missing. */
7237 7236
7238static void 7237static void
7239input_available_signal (int signo) 7238handle_input_available_signal (int sig)
7240{ 7239{
7241 /* Must preserve main program's value of errno. */
7242 int old_errno = errno;
7243 SIGNAL_THREAD_CHECK (signo);
7244
7245#ifdef SYNC_INPUT 7240#ifdef SYNC_INPUT
7246 interrupt_input_pending = 1; 7241 interrupt_input_pending = 1;
7247 pending_signals = 1; 7242 pending_signals = 1;
@@ -7253,8 +7248,12 @@ input_available_signal (int signo)
7253#ifndef SYNC_INPUT 7248#ifndef SYNC_INPUT
7254 handle_async_input (); 7249 handle_async_input ();
7255#endif 7250#endif
7251}
7256 7252
7257 errno = old_errno; 7253static void
7254deliver_input_available_signal (int sig)
7255{
7256 handle_on_main_thread (sig, handle_input_available_signal);
7258} 7257}
7259#endif /* SIGIO */ 7258#endif /* SIGIO */
7260 7259
@@ -7310,18 +7309,15 @@ add_user_signal (int sig, const char *name)
7310 p->next = user_signals; 7309 p->next = user_signals;
7311 user_signals = p; 7310 user_signals = p;
7312 7311
7313 signal (sig, handle_user_signal); 7312 signal (sig, deliver_user_signal);
7314} 7313}
7315 7314
7316static void 7315static void
7317handle_user_signal (int sig) 7316handle_user_signal (int sig)
7318{ 7317{
7319 int old_errno = errno;
7320 struct user_signal_info *p; 7318 struct user_signal_info *p;
7321 const char *special_event_name = NULL; 7319 const char *special_event_name = NULL;
7322 7320
7323 SIGNAL_THREAD_CHECK (sig);
7324
7325 if (SYMBOLP (Vdebug_on_event)) 7321 if (SYMBOLP (Vdebug_on_event))
7326 special_event_name = SSDATA (SYMBOL_NAME (Vdebug_on_event)); 7322 special_event_name = SSDATA (SYMBOL_NAME (Vdebug_on_event));
7327 7323
@@ -7355,8 +7351,12 @@ handle_user_signal (int sig)
7355 } 7351 }
7356 break; 7352 break;
7357 } 7353 }
7354}
7358 7355
7359 errno = old_errno; 7356static void
7357deliver_user_signal (int sig)
7358{
7359 handle_on_main_thread (sig, handle_user_signal);
7360} 7360}
7361 7361
7362static char * 7362static char *
@@ -10776,17 +10776,10 @@ clear_waiting_for_input (void)
10776 Otherwise, tell QUIT to kill Emacs. */ 10776 Otherwise, tell QUIT to kill Emacs. */
10777 10777
10778static void 10778static void
10779interrupt_signal (int signalnum) /* If we don't have an argument, some */ 10779handle_interrupt_signal (int sig)
10780 /* compilers complain in signal calls. */
10781{ 10780{
10782 /* Must preserve main program's value of errno. */
10783 int old_errno = errno;
10784 struct terminal *terminal;
10785
10786 SIGNAL_THREAD_CHECK (signalnum);
10787
10788 /* See if we have an active terminal on our controlling tty. */ 10781 /* See if we have an active terminal on our controlling tty. */
10789 terminal = get_named_tty ("/dev/tty"); 10782 struct terminal *terminal = get_named_tty ("/dev/tty");
10790 if (!terminal) 10783 if (!terminal)
10791 { 10784 {
10792 /* If there are no frames there, let's pretend that we are a 10785 /* If there are no frames there, let's pretend that we are a
@@ -10807,10 +10800,15 @@ interrupt_signal (int signalnum) /* If we don't have an argument, some */
10807 10800
10808 handle_interrupt (); 10801 handle_interrupt ();
10809 } 10802 }
10803}
10810 10804
10811 errno = old_errno; 10805static void
10806deliver_interrupt_signal (int sig)
10807{
10808 handle_on_main_thread (sig, handle_interrupt_signal);
10812} 10809}
10813 10810
10811
10814/* If Emacs is stuck because `inhibit-quit' is true, then keep track 10812/* If Emacs is stuck because `inhibit-quit' is true, then keep track
10815 of the number of times C-g has been requested. If C-g is pressed 10813 of the number of times C-g has been requested. If C-g is pressed
10816 enough times, then quit anyway. See bug#6585. */ 10814 enough times, then quit anyway. See bug#6585. */
@@ -11404,17 +11402,17 @@ init_keyboard (void)
11404 SIGINT. There is special code in interrupt_signal to exit 11402 SIGINT. There is special code in interrupt_signal to exit
11405 Emacs on SIGINT when there are no termcap frames on the 11403 Emacs on SIGINT when there are no termcap frames on the
11406 controlling terminal. */ 11404 controlling terminal. */
11407 signal (SIGINT, interrupt_signal); 11405 signal (SIGINT, deliver_interrupt_signal);
11408#ifndef DOS_NT 11406#ifndef DOS_NT
11409 /* For systems with SysV TERMIO, C-g is set up for both SIGINT and 11407 /* For systems with SysV TERMIO, C-g is set up for both SIGINT and
11410 SIGQUIT and we can't tell which one it will give us. */ 11408 SIGQUIT and we can't tell which one it will give us. */
11411 signal (SIGQUIT, interrupt_signal); 11409 signal (SIGQUIT, deliver_interrupt_signal);
11412#endif /* not DOS_NT */ 11410#endif /* not DOS_NT */
11413 } 11411 }
11414/* Note SIGIO has been undef'd if FIONREAD is missing. */ 11412/* Note SIGIO has been undef'd if FIONREAD is missing. */
11415#ifdef SIGIO 11413#ifdef SIGIO
11416 if (!noninteractive) 11414 if (!noninteractive)
11417 signal (SIGIO, input_available_signal); 11415 signal (SIGIO, deliver_input_available_signal);
11418#endif /* SIGIO */ 11416#endif /* SIGIO */
11419 11417
11420/* Use interrupt input by default, if it works and noninterrupt input 11418/* Use interrupt input by default, if it works and noninterrupt input
diff --git a/src/lisp.h b/src/lisp.h
index 78c418f3051..28e8c1cd1e8 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -909,14 +909,6 @@ enum
909 (ASCII_CHAR_P (IDX) ? CHAR_TABLE_REF_ASCII ((CT), (IDX)) \ 909 (ASCII_CHAR_P (IDX) ? CHAR_TABLE_REF_ASCII ((CT), (IDX)) \
910 : char_table_ref ((CT), (IDX))) 910 : char_table_ref ((CT), (IDX)))
911 911
912/* Almost equivalent to Faref (CT, IDX). However, if the result is
913 not a character, return IDX.
914
915 For these characters, do not check validity of CT
916 and do not follow parent. */
917#define CHAR_TABLE_TRANSLATE(CT, IDX) \
918 char_table_translate (CT, IDX)
919
920/* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and 912/* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and
921 8-bit European characters. Do not check validity of CT. */ 913 8-bit European characters. Do not check validity of CT. */
922#define CHAR_TABLE_SET(CT, IDX, VAL) \ 914#define CHAR_TABLE_SET(CT, IDX, VAL) \
@@ -1205,9 +1197,9 @@ struct Lisp_Hash_Table
1205 struct Lisp_Hash_Table *next_weak; 1197 struct Lisp_Hash_Table *next_weak;
1206 1198
1207 /* C function to compare two keys. */ 1199 /* C function to compare two keys. */
1208 int (*cmpfn) (struct Lisp_Hash_Table *, 1200 bool (*cmpfn) (struct Lisp_Hash_Table *,
1209 Lisp_Object, EMACS_UINT, 1201 Lisp_Object, EMACS_UINT,
1210 Lisp_Object, EMACS_UINT); 1202 Lisp_Object, EMACS_UINT);
1211 1203
1212 /* C function to compute hash code. */ 1204 /* C function to compute hash code. */
1213 EMACS_UINT (*hashfn) (struct Lisp_Hash_Table *, Lisp_Object); 1205 EMACS_UINT (*hashfn) (struct Lisp_Hash_Table *, Lisp_Object);
@@ -3151,9 +3143,9 @@ EXFUN (Fread_file_name, 6); /* not a normal DEFUN */
3151extern Lisp_Object close_file_unwind (Lisp_Object); 3143extern Lisp_Object close_file_unwind (Lisp_Object);
3152extern Lisp_Object restore_point_unwind (Lisp_Object); 3144extern Lisp_Object restore_point_unwind (Lisp_Object);
3153extern _Noreturn void report_file_error (const char *, Lisp_Object); 3145extern _Noreturn void report_file_error (const char *, Lisp_Object);
3154extern int internal_delete_file (Lisp_Object); 3146extern void internal_delete_file (Lisp_Object);
3155extern void syms_of_fileio (void); 3147extern void syms_of_fileio (void);
3156extern Lisp_Object make_temp_name (Lisp_Object, int); 3148extern Lisp_Object make_temp_name (Lisp_Object, bool);
3157extern Lisp_Object Qdelete_file; 3149extern Lisp_Object Qdelete_file;
3158 3150
3159/* Defined in search.c */ 3151/* Defined in search.c */
@@ -3264,9 +3256,6 @@ extern bool display_arg;
3264extern Lisp_Object decode_env_path (const char *, const char *); 3256extern Lisp_Object decode_env_path (const char *, const char *);
3265extern Lisp_Object empty_unibyte_string, empty_multibyte_string; 3257extern Lisp_Object empty_unibyte_string, empty_multibyte_string;
3266extern Lisp_Object Qfile_name_handler_alist; 3258extern Lisp_Object Qfile_name_handler_alist;
3267#ifdef FLOAT_CATCH_SIGILL
3268extern void fatal_error_signal (int);
3269#endif
3270extern _Noreturn void fatal_error_backtrace (int, int); 3259extern _Noreturn void fatal_error_backtrace (int, int);
3271extern Lisp_Object Qkill_emacs; 3260extern Lisp_Object Qkill_emacs;
3272#if HAVE_SETLOCALE 3261#if HAVE_SETLOCALE
@@ -3556,32 +3545,6 @@ extern void init_system_name (void);
3556#define make_fixnum_or_float(val) \ 3545#define make_fixnum_or_float(val) \
3557 (FIXNUM_OVERFLOW_P (val) ? make_float (val) : make_number (val)) 3546 (FIXNUM_OVERFLOW_P (val) ? make_float (val) : make_number (val))
3558 3547
3559
3560/* Checks the `cycle check' variable CHECK to see if it indicates that
3561 EL is part of a cycle; CHECK must be either Qnil or a value returned
3562 by an earlier use of CYCLE_CHECK. SUSPICIOUS is the number of
3563 elements after which a cycle might be suspected; after that many
3564 elements, this macro begins consing in order to keep more precise
3565 track of elements.
3566
3567 Returns nil if a cycle was detected, otherwise a new value for CHECK
3568 that includes EL.
3569
3570 CHECK is evaluated multiple times, EL and SUSPICIOUS 0 or 1 times, so
3571 the caller should make sure that's ok. */
3572
3573#define CYCLE_CHECK(check, el, suspicious) \
3574 (NILP (check) \
3575 ? make_number (0) \
3576 : (INTEGERP (check) \
3577 ? (XFASTINT (check) < (suspicious) \
3578 ? make_number (XFASTINT (check) + 1) \
3579 : Fcons (el, Qnil)) \
3580 : (!NILP (Fmemq ((el), (check))) \
3581 ? Qnil \
3582 : Fcons ((el), (check)))))
3583
3584
3585/* SAFE_ALLOCA normally allocates memory on the stack, but if size is 3548/* SAFE_ALLOCA normally allocates memory on the stack, but if size is
3586 larger than MAX_ALLOCA, use xmalloc to avoid overflowing the stack. */ 3549 larger than MAX_ALLOCA, use xmalloc to avoid overflowing the stack. */
3587 3550
diff --git a/src/process.c b/src/process.c
index 5677da36881..3a6615fb505 100644
--- a/src/process.c
+++ b/src/process.c
@@ -124,6 +124,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
124#include "xgselect.h" 124#include "xgselect.h"
125#endif 125#endif
126 126
127#ifndef WNOHANG
128# undef waitpid
129# define waitpid(pid, status, options) wait (status)
130#endif
131#ifndef WUNTRACED
132# define WUNTRACED 0
133#endif
134
127/* Work around GCC 4.7.0 bug with strict overflow checking; see 135/* Work around GCC 4.7.0 bug with strict overflow checking; see
128 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>. 136 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>.
129 These lines can be removed once the GCC bug is fixed. */ 137 These lines can be removed once the GCC bug is fixed. */
@@ -801,7 +809,7 @@ get_process (register Lisp_Object name)
801#ifdef SIGCHLD 809#ifdef SIGCHLD
802/* Fdelete_process promises to immediately forget about the process, but in 810/* Fdelete_process promises to immediately forget about the process, but in
803 reality, Emacs needs to remember those processes until they have been 811 reality, Emacs needs to remember those processes until they have been
804 treated by sigchld_handler; otherwise this handler would consider the 812 treated by the SIGCHLD handler; otherwise this handler would consider the
805 process as being synchronous and say that the synchronous process is 813 process as being synchronous and say that the synchronous process is
806 dead. */ 814 dead. */
807static Lisp_Object deleted_pid_list; 815static Lisp_Object deleted_pid_list;
@@ -849,7 +857,8 @@ nil, indicating the current buffer's process. */)
849#endif 857#endif
850 { 858 {
851 Fkill_process (process, Qnil); 859 Fkill_process (process, Qnil);
852 /* Do this now, since remove_process will make sigchld_handler do nothing. */ 860 /* Do this now, since remove_process will make the
861 SIGCHLD handler do nothing. */
853 pset_status (p, Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil))); 862 pset_status (p, Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil)));
854 p->tick = ++process_tick; 863 p->tick = ++process_tick;
855 status_notify (p); 864 status_notify (p);
@@ -1728,7 +1737,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1728 if (inchannel > max_process_desc) 1737 if (inchannel > max_process_desc)
1729 max_process_desc = inchannel; 1738 max_process_desc = inchannel;
1730 1739
1731 /* Until we store the proper pid, enable sigchld_handler 1740 /* Until we store the proper pid, enable the SIGCHLD handler
1732 to recognize an unknown pid as standing for this process. 1741 to recognize an unknown pid as standing for this process.
1733 It is very important not to let this `marker' value stay 1742 It is very important not to let this `marker' value stay
1734 in the table after this function has returned; if it does 1743 in the table after this function has returned; if it does
@@ -4956,8 +4965,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4956 4965
4957 if (p->pid == -2) 4966 if (p->pid == -2)
4958 { 4967 {
4959 /* If the EIO occurs on a pty, sigchld_handler's 4968 /* If the EIO occurs on a pty, the SIGCHLD handler's
4960 waitpid() will not find the process object to 4969 waitpid call will not find the process object to
4961 delete. Do it here. */ 4970 delete. Do it here. */
4962 p->tick = ++process_tick; 4971 p->tick = ++process_tick;
4963 pset_status (p, Qfailed); 4972 pset_status (p, Qfailed);
@@ -5422,18 +5431,19 @@ read_process_output (Lisp_Object proc, register int channel)
5422static jmp_buf send_process_frame; 5431static jmp_buf send_process_frame;
5423static Lisp_Object process_sent_to; 5432static Lisp_Object process_sent_to;
5424 5433
5425#ifndef FORWARD_SIGNAL_TO_MAIN_THREAD 5434static _Noreturn void
5426static _Noreturn void send_process_trap (int); 5435handle_pipe_signal (int sig)
5427#endif
5428
5429static void
5430send_process_trap (int ignore)
5431{ 5436{
5432 SIGNAL_THREAD_CHECK (SIGPIPE);
5433 sigunblock (sigmask (SIGPIPE)); 5437 sigunblock (sigmask (SIGPIPE));
5434 _longjmp (send_process_frame, 1); 5438 _longjmp (send_process_frame, 1);
5435} 5439}
5436 5440
5441static void
5442deliver_pipe_signal (int sig)
5443{
5444 handle_on_main_thread (sig, handle_pipe_signal);
5445}
5446
5437/* In send_process, when a write fails temporarily, 5447/* In send_process, when a write fails temporarily,
5438 wait_reading_process_output is called. It may execute user code, 5448 wait_reading_process_output is called. It may execute user code,
5439 e.g. timers, that attempts to write new data to the same process. 5449 e.g. timers, that attempts to write new data to the same process.
@@ -5663,7 +5673,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
5663 /* Send this batch, using one or more write calls. */ 5673 /* Send this batch, using one or more write calls. */
5664 ptrdiff_t written = 0; 5674 ptrdiff_t written = 0;
5665 int outfd = p->outfd; 5675 int outfd = p->outfd;
5666 old_sigpipe = (void (*) (int)) signal (SIGPIPE, send_process_trap); 5676 old_sigpipe = signal (SIGPIPE, deliver_pipe_signal);
5667#ifdef DATAGRAM_SOCKETS 5677#ifdef DATAGRAM_SOCKETS
5668 if (DATAGRAM_CHAN_P (outfd)) 5678 if (DATAGRAM_CHAN_P (outfd))
5669 { 5679 {
@@ -6397,143 +6407,135 @@ process has been transmitted to the serial port. */)
6397 indirectly; if it does, that is a bug */ 6407 indirectly; if it does, that is a bug */
6398 6408
6399#ifdef SIGCHLD 6409#ifdef SIGCHLD
6400static void 6410
6401sigchld_handler (int signo) 6411/* Record one child's changed status. Return true if a child was found. */
6412static bool
6413record_child_status_change (void)
6402{ 6414{
6403 int old_errno = errno;
6404 Lisp_Object proc; 6415 Lisp_Object proc;
6405 struct Lisp_Process *p; 6416 struct Lisp_Process *p;
6417 pid_t pid;
6418 int w;
6419 Lisp_Object tail;
6406 6420
6407 SIGNAL_THREAD_CHECK (signo); 6421 do
6408 6422 pid = waitpid (-1, &w, WNOHANG | WUNTRACED);
6409 while (1) 6423 while (pid < 0 && errno == EINTR);
6410 {
6411 pid_t pid;
6412 int w;
6413 Lisp_Object tail;
6414
6415#ifdef WNOHANG
6416#ifndef WUNTRACED
6417#define WUNTRACED 0
6418#endif /* no WUNTRACED */
6419 /* Keep trying to get a status until we get a definitive result. */
6420 do
6421 {
6422 errno = 0;
6423 pid = waitpid (-1, &w, WNOHANG | WUNTRACED);
6424 }
6425 while (pid < 0 && errno == EINTR);
6426
6427 if (pid <= 0)
6428 {
6429 /* PID == 0 means no processes found, PID == -1 means a real
6430 failure. We have done all our job, so return. */
6431 6424
6432 errno = old_errno; 6425 /* PID == 0 means no processes found, PID == -1 means a real failure.
6433 return; 6426 Either way, we have done all our job. */
6434 } 6427 if (pid <= 0)
6435#else 6428 return false;
6436 pid = wait (&w);
6437#endif /* no WNOHANG */
6438 6429
6439 /* Find the process that signaled us, and record its status. */ 6430 /* Find the process that signaled us, and record its status. */
6440 6431
6441 /* The process can have been deleted by Fdelete_process. */ 6432 /* The process can have been deleted by Fdelete_process. */
6442 for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) 6433 for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail))
6434 {
6435 Lisp_Object xpid = XCAR (tail);
6436 if ((INTEGERP (xpid) && pid == XINT (xpid))
6437 || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid)))
6443 { 6438 {
6444 Lisp_Object xpid = XCAR (tail); 6439 XSETCAR (tail, Qnil);
6445 if ((INTEGERP (xpid) && pid == XINT (xpid)) 6440 return true;
6446 || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid)))
6447 {
6448 XSETCAR (tail, Qnil);
6449 goto sigchld_end_of_loop;
6450 }
6451 } 6441 }
6442 }
6452 6443
6453 /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ 6444 /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */
6445 p = 0;
6446 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
6447 {
6448 proc = XCDR (XCAR (tail));
6449 p = XPROCESS (proc);
6450 if (EQ (p->type, Qreal) && p->pid == pid)
6451 break;
6454 p = 0; 6452 p = 0;
6455 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) 6453 }
6456 {
6457 proc = XCDR (XCAR (tail));
6458 p = XPROCESS (proc);
6459 if (EQ (p->type, Qreal) && p->pid == pid)
6460 break;
6461 p = 0;
6462 }
6463
6464 /* Look for an asynchronous process whose pid hasn't been filled
6465 in yet. */
6466 if (p == 0)
6467 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
6468 {
6469 proc = XCDR (XCAR (tail));
6470 p = XPROCESS (proc);
6471 if (p->pid == -1)
6472 break;
6473 p = 0;
6474 }
6475
6476 /* Change the status of the process that was found. */
6477 if (p != 0)
6478 {
6479 int clear_desc_flag = 0;
6480 6454
6481 p->tick = ++process_tick; 6455 /* Look for an asynchronous process whose pid hasn't been filled
6482 p->raw_status = w; 6456 in yet. */
6483 p->raw_status_new = 1; 6457 if (! p)
6458 for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
6459 {
6460 proc = XCDR (XCAR (tail));
6461 p = XPROCESS (proc);
6462 if (p->pid == -1)
6463 break;
6464 p = 0;
6465 }
6484 6466
6485 /* If process has terminated, stop waiting for its output. */ 6467 /* Change the status of the process that was found. */
6486 if ((WIFSIGNALED (w) || WIFEXITED (w)) 6468 if (p)
6487 && p->infd >= 0) 6469 {
6488 clear_desc_flag = 1; 6470 int clear_desc_flag = 0;
6489 6471
6490 /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ 6472 p->tick = ++process_tick;
6491 if (clear_desc_flag) 6473 p->raw_status = w;
6492 { 6474 p->raw_status_new = 1;
6493 FD_CLR (p->infd, &input_wait_mask);
6494 FD_CLR (p->infd, &non_keyboard_wait_mask);
6495 }
6496 6475
6497 /* Tell wait_reading_process_output that it needs to wake up and 6476 /* If process has terminated, stop waiting for its output. */
6498 look around. */ 6477 if ((WIFSIGNALED (w) || WIFEXITED (w))
6499 if (input_available_clear_time) 6478 && p->infd >= 0)
6500 *input_available_clear_time = make_emacs_time (0, 0); 6479 clear_desc_flag = 1;
6501 }
6502 6480
6503 /* There was no asynchronous process found for that pid: we have 6481 /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */
6504 a synchronous process. */ 6482 if (clear_desc_flag)
6505 else
6506 { 6483 {
6507 synch_process_alive = 0; 6484 FD_CLR (p->infd, &input_wait_mask);
6508 6485 FD_CLR (p->infd, &non_keyboard_wait_mask);
6509 /* Report the status of the synchronous process. */
6510 if (WIFEXITED (w))
6511 synch_process_retcode = WEXITSTATUS (w);
6512 else if (WIFSIGNALED (w))
6513 synch_process_termsig = WTERMSIG (w);
6514
6515 /* Tell wait_reading_process_output that it needs to wake up and
6516 look around. */
6517 if (input_available_clear_time)
6518 *input_available_clear_time = make_emacs_time (0, 0);
6519 } 6486 }
6520 6487
6521 sigchld_end_of_loop: 6488 /* Tell wait_reading_process_output that it needs to wake up and
6522 ; 6489 look around. */
6490 if (input_available_clear_time)
6491 *input_available_clear_time = make_emacs_time (0, 0);
6492 }
6493 /* There was no asynchronous process found for that pid: we have
6494 a synchronous process. */
6495 else
6496 {
6497 synch_process_alive = 0;
6498
6499 /* Report the status of the synchronous process. */
6500 if (WIFEXITED (w))
6501 synch_process_retcode = WEXITSTATUS (w);
6502 else if (WIFSIGNALED (w))
6503 synch_process_termsig = WTERMSIG (w);
6504
6505 /* Tell wait_reading_process_output that it needs to wake up and
6506 look around. */
6507 if (input_available_clear_time)
6508 *input_available_clear_time = make_emacs_time (0, 0);
6509 }
6510
6511 return true;
6512}
6523 6513
6524 /* On some systems, we must return right away. 6514/* On some systems, the SIGCHLD handler must return right away. If
6525 If any more processes want to signal us, we will 6515 any more processes want to signal us, we will get another signal.
6526 get another signal. 6516 Otherwise, loop around to use up all the processes that have
6527 Otherwise (on systems that have WNOHANG), loop around 6517 something to tell us. */
6528 to use up all the processes that have something to tell us. */
6529#if (defined WINDOWSNT \ 6518#if (defined WINDOWSNT \
6530 || (defined USG && !defined GNU_LINUX \ 6519 || (defined USG && !defined GNU_LINUX \
6531 && !(defined HPUX && defined WNOHANG))) 6520 && !(defined HPUX && defined WNOHANG)))
6532 errno = old_errno; 6521enum { CAN_HANDLE_MULTIPLE_CHILDREN = 1 };
6533 return; 6522#else
6534#endif /* USG, but not HPUX with WNOHANG */ 6523enum { CAN_HANDLE_MULTIPLE_CHILDREN = 0 };
6535 } 6524#endif
6525
6526static void
6527handle_child_signal (int sig)
6528{
6529 while (record_child_status_change () && CAN_HANDLE_MULTIPLE_CHILDREN)
6530 continue;
6536} 6531}
6532
6533static void
6534deliver_child_signal (int sig)
6535{
6536 handle_on_main_thread (sig, handle_child_signal);
6537}
6538
6537#endif /* SIGCHLD */ 6539#endif /* SIGCHLD */
6538 6540
6539 6541
@@ -7387,7 +7389,7 @@ init_process_emacs (void)
7387#ifndef CANNOT_DUMP 7389#ifndef CANNOT_DUMP
7388 if (! noninteractive || initialized) 7390 if (! noninteractive || initialized)
7389#endif 7391#endif
7390 signal (SIGCHLD, sigchld_handler); 7392 signal (SIGCHLD, deliver_child_signal);
7391#endif 7393#endif
7392 7394
7393 FD_ZERO (&input_wait_mask); 7395 FD_ZERO (&input_wait_mask);
diff --git a/src/sysdep.c b/src/sysdep.c
index 1f4de194c64..42b8baf78e0 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1551,6 +1551,40 @@ sys_sigsetmask (sigset_t new_mask)
1551 return (old_mask); 1551 return (old_mask);
1552} 1552}
1553 1553
1554#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
1555pthread_t main_thread;
1556#endif
1557
1558/* If we are on the main thread, handle the signal SIG with HANDLER.
1559 Otherwise, redirect the signal to the main thread, blocking it from
1560 this thread. POSIX says any thread can receive a signal that is
1561 associated with a process, process group, or asynchronous event.
1562 On GNU/Linux that is not true, but for other systems (FreeBSD at
1563 least) it is. */
1564void
1565handle_on_main_thread (int sig, signal_handler_t handler)
1566{
1567 /* Preserve errno, to avoid race conditions with signal handlers that
1568 might change errno. Races can occur even in single-threaded hosts. */
1569 int old_errno = errno;
1570
1571 bool on_main_thread = true;
1572#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
1573 if (! pthread_equal (pthread_self (), main_thread))
1574 {
1575 sigset_t blocked;
1576 sigemptyset (&blocked);
1577 sigaddset (&blocked, sig);
1578 pthread_sigmask (SIG_BLOCK, &blocked, 0);
1579 pthread_kill (main_thread, sig);
1580 on_main_thread = false;
1581 }
1582#endif
1583 if (on_main_thread)
1584 handler (sig);
1585
1586 errno = old_errno;
1587}
1554 1588
1555#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST 1589#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
1556static char *my_sys_siglist[NSIG]; 1590static char *my_sys_siglist[NSIG];
@@ -1565,6 +1599,10 @@ init_signals (void)
1565{ 1599{
1566 sigemptyset (&empty_mask); 1600 sigemptyset (&empty_mask);
1567 1601
1602#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
1603 main_thread = pthread_self ();
1604#endif
1605
1568#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST 1606#if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST
1569 if (! initialized) 1607 if (! initialized)
1570 { 1608 {
diff --git a/src/syssignal.h b/src/syssignal.h
index 71151ed4c6a..504aff43083 100644
--- a/src/syssignal.h
+++ b/src/syssignal.h
@@ -133,24 +133,5 @@ char *strsignal (int);
133 133
134#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD 134#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD
135extern pthread_t main_thread; 135extern pthread_t main_thread;
136#define SIGNAL_THREAD_CHECK(signo) \ 136void handle_on_main_thread (int, signal_handler_t);
137 do { \ 137#endif
138 if (!pthread_equal (pthread_self (), main_thread)) \
139 { \
140 /* POSIX says any thread can receive the signal. On GNU/Linux \
141 that is not true, but for other systems (FreeBSD at least) \
142 it is. So direct the signal to the correct thread and block \
143 it from this thread. */ \
144 sigset_t new_mask; \
145 \
146 sigemptyset (&new_mask); \
147 sigaddset (&new_mask, signo); \
148 pthread_sigmask (SIG_BLOCK, &new_mask, 0); \
149 pthread_kill (main_thread, signo); \
150 return; \
151 } \
152 } while (0)
153
154#else /* not FORWARD_SIGNAL_TO_MAIN_THREAD */
155#define SIGNAL_THREAD_CHECK(signo)
156#endif /* not FORWARD_SIGNAL_TO_MAIN_THREAD */
diff --git a/src/window.c b/src/window.c
index 08608e0d451..1869a3b65cf 100644
--- a/src/window.c
+++ b/src/window.c
@@ -6576,15 +6576,17 @@ freeze_window_starts (struct frame *f, int freeze_p)
6576/* Return 1 if window configurations CONFIGURATION1 and CONFIGURATION2 6576/* Return 1 if window configurations CONFIGURATION1 and CONFIGURATION2
6577 describe the same state of affairs. This is used by Fequal. 6577 describe the same state of affairs. This is used by Fequal.
6578 6578
6579 ignore_positions non-zero means ignore non-matching scroll positions 6579 IGNORE_POSITIONS means ignore non-matching scroll positions
6580 and the like. 6580 and the like.
6581 6581
6582 This ignores a couple of things like the dedication status of 6582 This ignores a couple of things like the dedication status of
6583 window, combination_limit and the like. This might have to be 6583 window, combination_limit and the like. This might have to be
6584 fixed. */ 6584 fixed. */
6585 6585
6586int 6586bool
6587compare_window_configurations (Lisp_Object configuration1, Lisp_Object configuration2, int ignore_positions) 6587compare_window_configurations (Lisp_Object configuration1,
6588 Lisp_Object configuration2,
6589 bool ignore_positions)
6588{ 6590{
6589 register struct save_window_data *d1, *d2; 6591 register struct save_window_data *d1, *d2;
6590 struct Lisp_Vector *sws1, *sws2; 6592 struct Lisp_Vector *sws1, *sws2;
diff --git a/src/window.h b/src/window.h
index dfb88b2cf3c..a70bc55bac5 100644
--- a/src/window.h
+++ b/src/window.h
@@ -27,8 +27,6 @@ INLINE_HEADER_BEGIN
27# define WINDOW_INLINE INLINE 27# define WINDOW_INLINE INLINE
28#endif 28#endif
29 29
30extern Lisp_Object Qleft, Qright;
31
32/* Windows are allocated as if they were vectors, but then the 30/* Windows are allocated as if they were vectors, but then the
33Lisp data type is changed to Lisp_Window. They are garbage 31Lisp data type is changed to Lisp_Window. They are garbage
34collected along with the vectors. 32collected along with the vectors.
@@ -973,7 +971,7 @@ extern Lisp_Object Qwindowp, Qwindow_live_p;
973extern Lisp_Object Vwindow_list; 971extern Lisp_Object Vwindow_list;
974 972
975extern struct window *decode_live_window (Lisp_Object); 973extern struct window *decode_live_window (Lisp_Object);
976extern int compare_window_configurations (Lisp_Object, Lisp_Object, int); 974extern bool compare_window_configurations (Lisp_Object, Lisp_Object, bool);
977extern void mark_window_cursors_off (struct window *); 975extern void mark_window_cursors_off (struct window *);
978extern int window_internal_height (struct window *); 976extern int window_internal_height (struct window *);
979extern int window_body_cols (struct window *w); 977extern int window_body_cols (struct window *w);
diff --git a/src/xdisp.c b/src/xdisp.c
index 90a8de0be27..bec9ec91d2f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10601,12 +10601,12 @@ set_message (const char *s, Lisp_Object string,
10601 message_buf_print = 0; 10601 message_buf_print = 0;
10602 help_echo_showing_p = 0; 10602 help_echo_showing_p = 0;
10603 10603
10604 if (NILP (Vinhibit_debug_on_message) && 10604 if (NILP (Vinhibit_debug_on_message) && STRINGP (Vdebug_on_message)
10605 STRINGP (Vdebug_on_message) && 10605 && fast_string_match (Vdebug_on_message, string) >= 0)
10606 fast_string_match (Vdebug_on_message, string) >= 0) { 10606 {
10607 specbind (Qinhibit_debug_on_message, Qt); 10607 specbind (Qinhibit_debug_on_message, Qt);
10608 call_debugger (Fcons (Qerror, Fcons (string, Qnil))); 10608 call_debugger (list2 (Qerror, string));
10609 } 10609 }
10610 10610
10611 unbind_to (count, Qnil); 10611 unbind_to (count, Qnil);
10612} 10612}