diff options
| author | Kenichi Handa <handa@m17n.org> | 2012-09-06 10:49:15 +0900 |
|---|---|---|
| committer | Kenichi Handa <handa@m17n.org> | 2012-09-06 10:49:15 +0900 |
| commit | fca81a8d405cd4c825e144099c54dd163636aa3b (patch) | |
| tree | ee09be4b0e079b9c8863c8b570496a169227b218 /src | |
| parent | f41d6f9db69ce77fe9b3a637de407e8b589e0dc4 (diff) | |
| parent | 067b39d4296765e83f9530eca456168f6cda95fc (diff) | |
| download | emacs-fca81a8d405cd4c825e144099c54dd163636aa3b.tar.gz | |
merge trunk
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 101 | ||||
| -rw-r--r-- | src/alloc.c | 72 | ||||
| -rw-r--r-- | src/atimer.c | 24 | ||||
| -rw-r--r-- | src/conf_post.h | 2 | ||||
| -rw-r--r-- | src/data.c | 17 | ||||
| -rw-r--r-- | src/dispnew.c | 20 | ||||
| -rw-r--r-- | src/editfns.c | 4 | ||||
| -rw-r--r-- | src/emacs.c | 98 | ||||
| -rw-r--r-- | src/fileio.c | 199 | ||||
| -rw-r--r-- | src/filelock.c | 24 | ||||
| -rw-r--r-- | src/floatfns.c | 39 | ||||
| -rw-r--r-- | src/fns.c | 70 | ||||
| -rw-r--r-- | src/frame.h | 3 | ||||
| -rw-r--r-- | src/keyboard.c | 54 | ||||
| -rw-r--r-- | src/lisp.h | 47 | ||||
| -rw-r--r-- | src/process.c | 256 | ||||
| -rw-r--r-- | src/sysdep.c | 38 | ||||
| -rw-r--r-- | src/syssignal.h | 23 | ||||
| -rw-r--r-- | src/window.c | 8 | ||||
| -rw-r--r-- | src/window.h | 4 | ||||
| -rw-r--r-- | src/xdisp.c | 12 |
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 @@ +2012-09-05 Paul Eggert <eggert@cs.ucla.edu> + + Fix race conditions with signal handlers and errno. + Be more systematic about preserving errno whenever a signal + handler returns, even if it's not in the main thread. Do this by + renaming signal handlers to distinguish between signal delivery + and signal handling. All uses changed. + * atimer.c (deliver_alarm_signal): Rename from alarm_signal_handler. + * data.c (deliver_arith_signal): Rename from arith_error. + * dispnew.c (deliver_window_change_signal): Rename from + window_change_signal. + * emacs.c (deliver_error_signal): Rename from fatal_error_signal. + (deliver_danger_signal) [SIGDANGER]: Rename from memory_warning_signal. + * keyboard.c (deliver_input_available_signal): Rename from + input_available_signal. + (deliver_user_signal): Rename from handle_user_signal. + (deliver_interrupt_signal): Rename from interrupt_signal. + * process.c (deliver_pipe_signal): Rename from send_process_trap. + (deliver_child_signal): Rename from sigchld_handler. + * atimer.c (handle_alarm_signal): + * data.c (handle_arith_signal): + * dispnew.c (handle_window_change_signal): + * emacs.c (handle_fatal_signal, handle_danger_signal): + * keyboard.c (handle_input_available_signal): + * keyboard.c (handle_user_signal, handle_interrupt_signal): + * process.c (handle_pipe_signal, handle_child_signal): + New functions, with the actual signal-handling code taken from the + original respective signal handlers, sans the sporadic attempts to + preserve errno, since that's now done by handle_on_main_thread. + * atimer.c (alarm_signal_handler): Remove unnecessary decl. + * emacs.c, floatfns.c, lisp.h: Remove unused FLOAT_CATCH_SIGKILL cruft. + * emacs.c (main_thread) [FORWARD_SIGNAL_TO_MAIN_THREAD]: + Move to sysdep.c. + (main) [FORWARD_SIGNAL_TO_MAIN_THREAD]: + Move initialization of main_thread to sysdep.c's init_signals. + * process.c (waitpid) [!WNOHANG]: #define to wait; that's good enough for + our usage, and simplifies the mainline code. + (record_child_status_change): New static function, as a helper + for handle_child_signal, and with most of the old child handler's + contents. + (CAN_HANDLE_MULTIPLE_CHILDREN): New constant. + (handle_child_signal): Use the above. + * sysdep.c (main_thread) [FORWARD_SIGNAL_TO_MAIN_THREAD]: + Moved here from emacs.c. + (init_signals) [FORWARD_SIGNAL_TO_MAIN_THREAD]: Initialize it; + code moved here from emacs.c's main function. + * sysdep.c, syssignal.h (handle_on_main_thread): New function, + replacing the old SIGNAL_THREAD_CHECK. All uses changed. This + lets callers save and restore errno properly. + +2012-09-05 Dmitry Antipov <dmantipov@yandex.ru> + + Remove redundant or unused things here and there. + * lisp.h (CYCLE_CHECK, CHAR_TABLE_TRANSLATE): Remove. + * conf_post.h (RE_TRANSLATE): Use char_table_translate. + * editfns.c (Fcompare_buffer_substrings): Likewise. + * frame.h (struct terminal, struct font_driver_list): + Remove redundant declarations. + * window.h (Qleft, Qright): Likewise. + +2012-09-05 Dmitry Antipov <dmantipov@yandex.ru> + + Do not mark objects from deleted buffers, windows and frames. + * alloc.c (mark_buffer): Mark just the buffer if it is dead. + (mark_object): Likewise for windows and frames. + +2012-09-05 Dmitry Antipov <dmantipov@yandex.ru> + + * alloc.c (valid_lisp_object_p): Treat killed buffers, + buffer_defaults and buffer_local_symbols as valid objects. + Return special value to denote them. + +2012-09-05 Paul Eggert <eggert@cs.ucla.edu> + + * fileio.c, filelock.c, floatfns.c, fns.c: Use bool for boolean. + * fileio.c (auto_saving, auto_save_error_occurred, make_temp_name) + (Fexpand_file_name, barf_or_query_if_file_exists, Fcopy_file) + (file_name_absolute_p, Fsubstitute_in_file_name): + (check_executable, check_writable, Ffile_accessible_directory_p) + (Fset_file_selinux_context, Fdefault_file_modes) + (Finsert_file_contents, choose_write_coding_system) + (Fwrite_region, build_annotations, a_write, e_write) + (Fdo_auto_save): + * filelock.c (boot_time_initialized, get_boot_time) + (get_boot_time_1, lock_file_1, within_one_second): + * floatfns.c (in_float): + * fns.c (concat, internal_equal, Frequire, base64_encode_1) + (base64_decode_1, cmpfn_eql, cmpfn_user_defined) + (sweep_weak_table, sweep_weak_hash_tables, secure_hash): + * lisp.h (struct Lisp_Hash_Table.cmpfn): + * window.c (compare_window_configurations): + Use bool for booleans. + * fileio.c (auto_saving_dir_umask, auto_saving_mode_bits) + (Fdefault_file_modes): Now mode_t, not int, for modes. + (Fdo_auto_save): Set a boolean to 1 rather than using ++. + (internal_delete_file): Now returns void, not a (boolean) int, + since nobody was looking at the return value. + * lisp.h, window.h: Adjust to above API changes. + + * xdisp.c (set_message): Simplify and reindent last change. + 2012-09-05 Juanma Barranquero <lekktu@gmail.com> * 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) #endif } -/* Return 1 if OBJ is a valid lisp object. +/* Return 2 if OBJ is a killed or special buffer object. + Return 1 if OBJ is a valid lisp object. Return 0 if OBJ is NOT a valid lisp object. Return -1 if we cannot validate OBJ. This function can be quite slow, @@ -5002,6 +5003,9 @@ valid_lisp_object_p (Lisp_Object obj) if (PURE_POINTER_P (p)) return 1; + if (p == &buffer_defaults || p == &buffer_local_symbols) + return 2; + #if !GC_MARK_STACK return valid_pointer_p (p); #else @@ -5027,7 +5031,7 @@ valid_lisp_object_p (Lisp_Object obj) return 0; case MEM_TYPE_BUFFER: - return live_buffer_p (m, p); + return live_buffer_p (m, p) ? 1 : 2; case MEM_TYPE_CONS: return live_cons_p (m, p); @@ -5834,23 +5838,29 @@ mark_overlay (struct Lisp_Overlay *ptr) static void mark_buffer (struct buffer *buffer) { - /* This is handled much like other pseudovectors... */ - mark_vectorlike ((struct Lisp_Vector *) buffer); + if (NILP (BVAR (buffer, name))) + /* If the buffer is killed, mark just the buffer itself. */ + VECTOR_MARK (buffer); + else + { + /* This is handled much like other pseudovectors... */ + mark_vectorlike ((struct Lisp_Vector *) buffer); - /* ...but there are some buffer-specific things. */ + /* ...but there are some buffer-specific things. */ - MARK_INTERVAL_TREE (buffer_intervals (buffer)); + MARK_INTERVAL_TREE (buffer_intervals (buffer)); - /* For now, we just don't mark the undo_list. It's done later in - a special way just before the sweep phase, and after stripping - some of its elements that are not needed any more. */ + /* For now, we just don't mark the undo_list. It's done later in + a special way just before the sweep phase, and after stripping + some of its elements that are not needed any more. */ - mark_overlay (buffer->overlays_before); - mark_overlay (buffer->overlays_after); + mark_overlay (buffer->overlays_before); + mark_overlay (buffer->overlays_after); - /* If this is an indirect buffer, mark its base buffer. */ - if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer)) - mark_buffer (buffer->base_buffer); + /* If this is an indirect buffer, mark its base buffer. */ + if (buffer->base_buffer && !VECTOR_MARKED_P (buffer->base_buffer)) + mark_buffer (buffer->base_buffer); + } } /* Determine type of generic Lisp_Object and mark it accordingly. */ @@ -5993,24 +6003,38 @@ mark_object (Lisp_Object arg) case PVEC_FRAME: { - mark_vectorlike (ptr); - mark_face_cache (((struct frame *) ptr)->face_cache); + struct frame *f = (struct frame *) ptr; + + if (FRAME_LIVE_P (f)) + { + mark_vectorlike (ptr); + mark_face_cache (f->face_cache); + } + else + /* If the frame is deleted, mark just the frame itself. */ + VECTOR_MARK (ptr); } break; case PVEC_WINDOW: { struct window *w = (struct window *) ptr; + bool leaf = NILP (w->hchild) && NILP (w->vchild); - mark_vectorlike (ptr); - /* Mark glyphs for leaf windows. Marking window - matrices is sufficient because frame matrices - use the same glyph memory. */ - if (NILP (w->hchild) && NILP (w->vchild) - && w->current_matrix) + if (leaf && NILP (w->buffer)) + /* If the window is deleted, mark just the window itself. */ + VECTOR_MARK (ptr); + else { - mark_glyph_matrix (w->current_matrix); - mark_glyph_matrix (w->desired_matrix); + mark_vectorlike (ptr); + /* Mark glyphs for leaf windows. Marking window + matrices is sufficient because frame matrices + use the same glyph memory. */ + if (leaf && w->current_matrix) + { + mark_glyph_matrix (w->current_matrix); + mark_glyph_matrix (w->desired_matrix); + } } } 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; static struct atimer *atimers; -/* Non-zero means alarm_signal_handler has found ripe timers but +/* Non-zero means alarm signal handler has found ripe timers but interrupt_input_blocked was non-zero. In this case, timer functions are not called until the next UNBLOCK_INPUT because timer functions are expected to call X, and X cannot be assumed to be @@ -60,8 +60,6 @@ static void set_alarm (void); static void schedule_atimer (struct atimer *); static struct atimer *append_atimer_lists (struct atimer *, struct atimer *); -static void alarm_signal_handler (int signo); - /* Start a new atimer of type TYPE. TIME specifies when the timer is ripe. FN is the function to call when the timer fires. @@ -374,13 +372,9 @@ run_timers (void) /* Signal handler for SIGALRM. SIGNO is the signal number, i.e. SIGALRM. */ -void -alarm_signal_handler (int signo) +static void +handle_alarm_signal (int sig) { -#ifndef SYNC_INPUT - SIGNAL_THREAD_CHECK (signo); -#endif - pending_atimers = 1; #ifdef SYNC_INPUT pending_signals = 1; @@ -389,8 +383,14 @@ alarm_signal_handler (int signo) #endif } +static void +deliver_alarm_signal (int sig) +{ + handle_on_main_thread (sig, handle_alarm_signal); +} + -/* Call alarm_signal_handler for pending timers. */ +/* Call alarm signal handler for pending timers. */ void do_pending_atimers (void) @@ -412,7 +412,7 @@ turn_on_atimers (bool on) { if (on) { - signal (SIGALRM, alarm_signal_handler); + signal (SIGALRM, deliver_alarm_signal); set_alarm (); } else @@ -426,5 +426,5 @@ init_atimer (void) free_atimers = stopped_atimers = atimers = NULL; pending_atimers = 0; /* pending_signals is initialized in init_keyboard.*/ - signal (SIGALRM, alarm_signal_handler); + signal (SIGALRM, deliver_alarm_signal); } 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 */ #ifdef emacs /* Don't do this for lib-src. */ /* Tell regex.c to use a type compatible with Emacs. */ #define RE_TRANSLATE_TYPE Lisp_Object -#define RE_TRANSLATE(TBL, C) CHAR_TABLE_TRANSLATE (TBL, C) +#define RE_TRANSLATE(TBL, C) char_table_translate (TBL, C) #ifdef make_number /* If make_number is a macro, use it. */ #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) XSYMBOL (intern_c_string ("most-negative-fixnum"))->constant = 1; } -#ifndef FORWARD_SIGNAL_TO_MAIN_THREAD -_Noreturn -#endif -static void -arith_error (int signo) +static _Noreturn void +handle_arith_signal (int sig) { sigsetmask (SIGEMPTYMASK); - - SIGNAL_THREAD_CHECK (signo); xsignal0 (Qarith_error); } +static void +deliver_arith_signal (int sig) +{ + handle_on_main_thread (sig, handle_arith_signal); +} + void init_data (void) { @@ -3230,5 +3231,5 @@ init_data (void) if (!initialized) return; #endif /* CANNOT_DUMP */ - signal (SIGFPE, arith_error); + signal (SIGFPE, deliver_arith_signal); } 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, #ifdef SIGWINCH +static void deliver_window_change_signal (int); + static void -window_change_signal (int signalnum) /* If we don't have an argument, */ - /* some compilers complain in signal calls. */ +handle_window_change_signal (int sig) { int width, height; - int old_errno = errno; - struct tty_display_info *tty; - signal (SIGWINCH, window_change_signal); - SIGNAL_THREAD_CHECK (signalnum); + signal (SIGWINCH, deliver_window_change_signal); /* The frame size change obviously applies to a single 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, */ change_frame_size (XFRAME (frame), height, width, 0, 1, 0); } } +} - errno = old_errno; +static void +deliver_window_change_signal (int sig) +{ + handle_on_main_thread (sig, handle_window_change_signal); } #endif /* SIGWINCH */ @@ -5604,7 +5606,7 @@ window_change_signal (int signalnum) /* If we don't have an argument, */ void do_pending_window_change (bool safe) { - /* If window_change_signal should have run before, run it now. */ + /* If window change signal handler should have run before, run it now. */ if (redisplaying_p && !safe) return; @@ -6173,7 +6175,7 @@ init_display (void) #ifndef CANNOT_DUMP if (initialized) #endif /* CANNOT_DUMP */ - signal (SIGWINCH, window_change_signal); + signal (SIGWINCH, deliver_window_change_signal); #endif /* SIGWINCH */ /* 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. */) if (!NILP (trt)) { - c1 = CHAR_TABLE_TRANSLATE (trt, c1); - c2 = CHAR_TABLE_TRANSLATE (trt, c2); + c1 = char_table_translate (trt, c1); + c2 = char_table_translate (trt, c2); } if (c1 < c2) 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; /* True if handling a fatal error already. */ bool fatal_error_in_progress; -#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD -/* When compiled with GTK and running under Gnome, - multiple threads may be created. Keep track of our main - thread to make sure signals are delivered to it (see syssignal.h). */ - -pthread_t main_thread; -#endif - #ifdef HAVE_NS /* NS autrelease pool, for memory management. */ static void *ns_pool; @@ -291,16 +283,18 @@ static void *ns_pool; /* Handle bus errors, invalid instruction, etc. */ -#ifndef FLOAT_CATCH_SIGILL -static -#endif -void -fatal_error_signal (int sig) +static void +handle_fatal_signal (int sig) { - SIGNAL_THREAD_CHECK (sig); fatal_error_backtrace (sig, 10); } +static void +deliver_fatal_signal (int sig) +{ + handle_on_main_thread (sig, handle_fatal_signal); +} + /* Report a fatal error due to signal SIG, output a backtrace of at most BACKTRACE_LIMIT lines, and exit. */ _Noreturn void @@ -340,17 +334,23 @@ fatal_error_backtrace (int sig, int backtrace_limit) #ifdef SIGDANGER /* Handler for SIGDANGER. */ -void -memory_warning_signal (int sig) -{ - signal (sig, memory_warning_signal); - SIGNAL_THREAD_CHECK (sig); +static void deliver_danger_signal (int); +static void +handle_danger_signal (int sig) +{ + signal (sig, deliver_danger_signal); malloc_warning ("Operating system warns that virtual memory is running low.\n"); /* It might be unsafe to call do_auto_save now. */ force_auto_save_soon (); } + +static void +deliver_danger_signal (int sig) +{ + handle_on_main_thread (sig, handle_danger_signal); +} #endif /* Code for dealing with Lisp access to the Unix command line. */ @@ -851,10 +851,6 @@ main (int argc, char **argv) # endif /* not SYNC_INPUT */ #endif /* not SYSTEM_MALLOC */ -#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD - main_thread = pthread_self (); -#endif /* FORWARD_SIGNAL_TO_MAIN_THREAD */ - #if defined (MSDOS) || defined (WINDOWSNT) /* We do all file input/output as binary files. When we need to translate newlines, we do that manually. */ @@ -1120,7 +1116,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem That makes nohup work. */ if (! noninteractive || signal (SIGHUP, SIG_IGN) != SIG_IGN) - signal (SIGHUP, fatal_error_signal); + signal (SIGHUP, deliver_fatal_signal); sigunblock (sigmask (SIGHUP)); } @@ -1135,9 +1131,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem /* Don't catch these signals in batch mode if dumping. On some machines, this sets static data that would make signal fail to work right when the dumped Emacs is run. */ - signal (SIGQUIT, fatal_error_signal); - signal (SIGILL, fatal_error_signal); - signal (SIGTRAP, fatal_error_signal); + signal (SIGQUIT, deliver_fatal_signal); + signal (SIGILL, deliver_fatal_signal); + signal (SIGTRAP, deliver_fatal_signal); #ifdef SIGUSR1 add_user_signal (SIGUSR1, "sigusr1"); #endif @@ -1145,68 +1141,68 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem add_user_signal (SIGUSR2, "sigusr2"); #endif #ifdef SIGABRT - signal (SIGABRT, fatal_error_signal); + signal (SIGABRT, deliver_fatal_signal); #endif #ifdef SIGHWE - signal (SIGHWE, fatal_error_signal); + signal (SIGHWE, deliver_fatal_signal); #endif #ifdef SIGPRE - signal (SIGPRE, fatal_error_signal); + signal (SIGPRE, deliver_fatal_signal); #endif #ifdef SIGORE - signal (SIGORE, fatal_error_signal); + signal (SIGORE, deliver_fatal_signal); #endif #ifdef SIGUME - signal (SIGUME, fatal_error_signal); + signal (SIGUME, deliver_fatal_signal); #endif #ifdef SIGDLK - signal (SIGDLK, fatal_error_signal); + signal (SIGDLK, deliver_fatal_signal); #endif #ifdef SIGCPULIM - signal (SIGCPULIM, fatal_error_signal); + signal (SIGCPULIM, deliver_fatal_signal); #endif #ifdef SIGIOT /* This is missing on some systems - OS/2, for example. */ - signal (SIGIOT, fatal_error_signal); + signal (SIGIOT, deliver_fatal_signal); #endif #ifdef SIGEMT - signal (SIGEMT, fatal_error_signal); + signal (SIGEMT, deliver_fatal_signal); #endif - signal (SIGFPE, fatal_error_signal); + signal (SIGFPE, deliver_fatal_signal); #ifdef SIGBUS - signal (SIGBUS, fatal_error_signal); + signal (SIGBUS, deliver_fatal_signal); #endif - signal (SIGSEGV, fatal_error_signal); + signal (SIGSEGV, deliver_fatal_signal); #ifdef SIGSYS - signal (SIGSYS, fatal_error_signal); + signal (SIGSYS, deliver_fatal_signal); #endif /* May need special treatment on MS-Windows. See http://lists.gnu.org/archive/html/emacs-devel/2010-09/msg01062.html Please update the doc of kill-emacs, kill-emacs-hook, and NEWS if you change this. */ - if (noninteractive) signal (SIGINT, fatal_error_signal); - signal (SIGTERM, fatal_error_signal); + if (noninteractive) signal (SIGINT, deliver_fatal_signal); + signal (SIGTERM, deliver_fatal_signal); #ifdef SIGXCPU - signal (SIGXCPU, fatal_error_signal); + signal (SIGXCPU, deliver_fatal_signal); #endif #ifdef SIGXFSZ - signal (SIGXFSZ, fatal_error_signal); + signal (SIGXFSZ, deliver_fatal_signal); #endif /* SIGXFSZ */ #ifdef SIGDANGER /* This just means available memory is getting low. */ - signal (SIGDANGER, memory_warning_signal); + signal (SIGDANGER, deliver_danger_signal); #endif #ifdef AIX /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */ - signal (SIGXCPU, fatal_error_signal); - signal (SIGIOINT, fatal_error_signal); - signal (SIGGRANT, fatal_error_signal); - signal (SIGRETRACT, fatal_error_signal); - signal (SIGSOUND, fatal_error_signal); - signal (SIGMSG, fatal_error_signal); + signal (SIGXCPU, deliver_fatal_signal); + signal (SIGIOINT, deliver_fatal_signal); + signal (SIGGRANT, deliver_fatal_signal); + signal (SIGRETRACT, deliver_fatal_signal); + signal (SIGSOUND, deliver_fatal_signal); + signal (SIGMSG, deliver_fatal_signal); #endif /* AIX */ } 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/>. */ #include "commands.h" -/* Nonzero during writing of auto-save files. */ -static int auto_saving; +/* True during writing of auto-save files. */ +static bool auto_saving; /* Nonzero umask during creation of auto-save directories. */ -static int auto_saving_dir_umask; +static mode_t auto_saving_dir_umask; /* Set by auto_save_1 to mode of original file so Fwrite_region will create a new file with the same mode as the original. */ -static int auto_save_mode_bits; +static mode_t auto_save_mode_bits; /* Set by auto_save_1 if an error occurred during the last auto-save. */ -static int auto_save_error_occurred; +static bool auto_save_error_occurred; /* The symbol bound to coding-system-for-read when insert-file-contents is called for recovering a file. This is not @@ -145,10 +145,10 @@ Lisp_Object Qfile_name_history; static Lisp_Object Qcar_less_than_car; -static int a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, - Lisp_Object *, struct coding_system *); -static int e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, - struct coding_system *); +static bool a_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, + Lisp_Object *, struct coding_system *); +static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, + struct coding_system *); void @@ -595,7 +595,7 @@ static unsigned make_temp_name_count, make_temp_name_count_initialized_p; which has no existing file. To make this work, PREFIX should be an absolute file name. - BASE64_P non-zero means add the pid as 3 characters in base64 + BASE64_P means add the pid as 3 characters in base64 encoding. In this case, 6 characters will be added to PREFIX to form the file name. Otherwise, if Emacs is running on a system 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; generated. */ Lisp_Object -make_temp_name (Lisp_Object prefix, int base64_p) +make_temp_name (Lisp_Object prefix, bool base64_p) { Lisp_Object val; int len, clen; @@ -761,8 +761,8 @@ filesystem tree, not (expand-file-name ".." dirname). */) struct passwd *pw; #ifdef DOS_NT int drive = 0; - int collapse_newdir = 1; - int is_escaped = 0; + bool collapse_newdir = 1; + bool is_escaped = 0; #endif /* DOS_NT */ ptrdiff_t length; Lisp_Object handler, result, handled_name; @@ -920,10 +920,9 @@ filesystem tree, not (expand-file-name ".." dirname). */) /* If it turns out that the filename we want to return is just a suffix of FILENAME, we don't need to go through and edit things; we just need to construct a new string using data - starting at the middle of FILENAME. If we set lose to a - non-zero value, that means we've discovered that we can't do - that cool trick. */ - int lose = 0; + starting at the middle of FILENAME. If we set LOSE, that + means we've discovered that we can't do that cool trick. */ + bool lose = 0; char *p = nm; while (*p) @@ -1360,7 +1359,6 @@ See also the function `substitute-in-file-name'.") ptrdiff_t tlen; unsigned char *target; struct passwd *pw; - int lose; CHECK_STRING (name); nm = SDATA (name); @@ -1369,8 +1367,8 @@ See also the function `substitute-in-file-name'.") If no /./ or /../ we can return right away. */ if (nm[0] == '/') { + bool lose = 0; p = nm; - lose = 0; while (*p) { if (p[0] == '/' && p[1] == '/' @@ -1494,7 +1492,7 @@ See also the function `substitute-in-file-name'.") #endif /* If /~ or // appears, discard everything through first slash. */ -static int +static bool file_name_absolute_p (const char *filename) { return @@ -1560,12 +1558,10 @@ If `//' appears, everything up to and including the first of those `/' is discarded. */) (Lisp_Object filename) { - char *nm; - - register char *s, *p, *o, *x, *endp; + char *nm, *s, *p, *o, *x, *endp; char *target = NULL; int total = 0; - int substituted = 0; + bool substituted = 0; bool multibyte; char *xnm; Lisp_Object handler; @@ -1780,7 +1776,7 @@ expand_and_dir_to_file (Lisp_Object filename, Lisp_Object defdir) } /* Signal an error if the file ABSNAME already exists. - If INTERACTIVE is nonzero, ask the user whether to proceed, + If INTERACTIVE, ask the user whether to proceed, and bypass the error if the user says to go ahead. QUERYSTRING is a name for the action that is being considered to alter the file. @@ -1789,13 +1785,14 @@ expand_and_dir_to_file (Lisp_Object filename, Lisp_Object defdir) If the file does not exist, STATPTR->st_mode is set to 0. If STATPTR is null, we don't store into it. - If QUICK is nonzero, we ask for y or n, not yes or no. */ + If QUICK, ask for y or n, not yes or no. */ static void barf_or_query_if_file_exists (Lisp_Object absname, const char *querystring, - int interactive, struct stat *statptr, int quick) + bool interactive, struct stat *statptr, + bool quick) { - register Lisp_Object tem, encoded_filename; + Lisp_Object tem, encoded_filename; struct stat statbuf; struct gcpro gcpro1; @@ -1869,11 +1866,11 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) Lisp_Object handler; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; ptrdiff_t count = SPECPDL_INDEX (); - int input_file_statable_p; + bool input_file_statable_p; Lisp_Object encoded_file, encoded_newname; #if HAVE_LIBSELINUX security_context_t con; - int fail, conlength = 0; + int conlength = 0; #endif encoded_file = encoded_newname = Qnil; @@ -1988,7 +1985,7 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) S_IREAD | S_IWRITE); #else /* not MSDOS */ { - int new_mask = 0666; + mode_t new_mask = 0666; if (input_file_statable_p) { if (!NILP (preserve_uid_gid)) @@ -2018,7 +2015,7 @@ on the system, we copy the SELinux context of FILE to NEWNAME. */) owner and group. */ if (input_file_statable_p) { - int mode_mask = 07777; + mode_t mode_mask = 07777; if (!NILP (preserve_uid_gid)) { /* 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. */) if (conlength > 0) { /* Set the modified context back to the file. */ - fail = fsetfilecon (ofd, con); + bool fail = fsetfilecon (ofd, con) != 0; /* See http://debbugs.gnu.org/11245 for ENOTSUP. */ if (fail && errno != ENOTSUP) report_file_error ("Doing fsetfilecon", Fcons (newname, Qnil)); @@ -2184,17 +2181,14 @@ internal_delete_file_1 (Lisp_Object ignore) return Qt; } -/* Delete file FILENAME, returning 1 if successful and 0 if failed. +/* Delete file FILENAME. This ignores `delete-by-moving-to-trash'. */ -int +void internal_delete_file (Lisp_Object filename) { - Lisp_Object tem; - - tem = internal_condition_case_2 (Fdelete_file, filename, Qnil, - Qt, internal_delete_file_1); - return NILP (tem); + internal_condition_case_2 (Fdelete_file, filename, Qnil, + Qt, internal_delete_file_1); } DEFUN ("rename-file", Frename_file, Srename_file, 2, 3, @@ -2430,9 +2424,9 @@ On Unix, this is a name starting with a `/' or a `~'. */) return file_name_absolute_p (SSDATA (filename)) ? Qt : Qnil; } -/* Return nonzero if file FILENAME exists and can be executed. */ +/* Return true if file FILENAME exists and can be executed. */ -static int +static bool check_executable (char *filename) { #ifdef DOS_NT @@ -2452,9 +2446,9 @@ check_executable (char *filename) #endif /* not DOS_NT */ } -/* Return nonzero if file FILENAME exists and can be written. */ +/* Return true if file FILENAME exists and can be written. */ -static int +static bool check_writable (const char *filename) { #ifdef MSDOS @@ -2464,7 +2458,7 @@ check_writable (const char *filename) return (st.st_mode & S_IWRITE || S_ISDIR (st.st_mode)); #else /* not MSDOS */ #ifdef HAVE_EUIDACCESS - int res = (euidaccess (filename, 2) >= 0); + bool res = (euidaccess (filename, 2) >= 0); #ifdef CYGWIN /* euidaccess may have returned failure because Cygwin couldn't determine the file's UID or GID; if so, we return success. */ @@ -2732,7 +2726,7 @@ searchable directory. */) (Lisp_Object filename) { Lisp_Object handler; - int tem; + bool tem; struct gcpro gcpro1; /* If the file name has special constructs in it, @@ -2868,7 +2862,8 @@ compiled with SELinux support. */) Lisp_Object type = CAR_SAFE (CDR_SAFE (CDR_SAFE (context))); Lisp_Object range = CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (context)))); security_context_t con; - int fail, conlength; + bool fail; + int conlength; context_t parsed_con; #endif @@ -2912,8 +2907,9 @@ compiled with SELinux support. */) } /* Set the modified context back to the file. */ - fail = lsetfilecon (SSDATA (encoded_absname), - context_str (parsed_con)); + fail = (lsetfilecon (SSDATA (encoded_absname), + context_str (parsed_con)) + != 0); /* See http://debbugs.gnu.org/11245 for ENOTSUP. */ if (fail && errno != ENOTSUP) 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, The value is an integer. */) (void) { - int realmask; + mode_t realmask; Lisp_Object value; BLOCK_INPUT; @@ -3246,29 +3242,29 @@ variable `last-coding-system-used' to the coding system actually used. */) struct stat st; int file_status; EMACS_TIME mtime; - register int fd; + int fd; ptrdiff_t inserted = 0; - int nochange = 0; - register ptrdiff_t how_much; + bool nochange = 0; + ptrdiff_t how_much; off_t beg_offset, end_offset; - register int unprocessed; + int unprocessed; ptrdiff_t count = SPECPDL_INDEX (); struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; Lisp_Object handler, val, insval, orig_filename, old_undo; Lisp_Object p; ptrdiff_t total = 0; - int not_regular = 0; + bool not_regular = 0; int save_errno = 0; char read_buf[READ_BUF_SIZE]; struct coding_system coding; char buffer[1 << 14]; - int replace_handled = 0; - int set_coding_system = 0; + bool replace_handled = 0; + bool set_coding_system = 0; Lisp_Object coding_system; - int read_quit = 0; + bool read_quit = 0; Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark; - int we_locked_file = 0; - int deferred_remove_unwind_protect = 0; + bool we_locked_file = 0; + bool deferred_remove_unwind_protect = 0; if (current_buffer->base_buffer && ! NILP (visit)) error ("Cannot do file visiting in an indirect buffer"); @@ -3569,9 +3565,9 @@ variable `last-coding-system-used' to the coding system actually used. */) ptrdiff_t same_at_end = ZV_BYTE; ptrdiff_t overlap; /* There is still a possibility we will find the need to do code - conversion. If that happens, we set this variable to 1 to + conversion. If that happens, set this variable to give up on handling REPLACE in the optimized way. */ - int giveup_match_end = 0; + bool giveup_match_end = 0; if (beg_offset != 0) { @@ -4427,8 +4423,8 @@ choose_write_coding_system (Lisp_Object start, Lisp_Object end, Lisp_Object file If it is not set locally, we anyway have to convert EOL format if the default value of `buffer-file-coding-system' tells that it is not Unix-like (LF only) format. */ - int using_default_coding = 0; - int force_raw_text = 0; + bool using_default_coding = 0; + bool force_raw_text = 0; val = BVAR (current_buffer, buffer_file_coding_system); if (NILP (val) @@ -4537,8 +4533,8 @@ This calls `write-region-annotate-functions' at the start, and `write-region-post-annotation-function' at the end. */) (Lisp_Object start, Lisp_Object end, Lisp_Object filename, Lisp_Object append, Lisp_Object visit, Lisp_Object lockname, Lisp_Object mustbenew) { - register int desc; - int failure; + int desc; + bool ok; int save_errno = 0; const char *fn; struct stat st; @@ -4548,8 +4544,8 @@ This calls `write-region-annotate-functions' at the start, and Lisp_Object visit_file; Lisp_Object annotations; Lisp_Object encoded_filename; - int visiting = (EQ (visit, Qt) || STRINGP (visit)); - int quietly = !NILP (visit); + bool visiting = (EQ (visit, Qt) || STRINGP (visit)); + bool quietly = !NILP (visit); struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; struct buffer *given_buffer; struct coding_system coding; @@ -4713,37 +4709,27 @@ This calls `write-region-annotate-functions' at the start, and UNGCPRO; - failure = 0; immediate_quit = 1; if (STRINGP (start)) - { - failure = 0 > a_write (desc, start, 0, SCHARS (start), - &annotations, &coding); - save_errno = errno; - } + ok = a_write (desc, start, 0, SCHARS (start), &annotations, &coding); else if (XINT (start) != XINT (end)) - { - failure = 0 > a_write (desc, Qnil, - XINT (start), XINT (end) - XINT (start), - &annotations, &coding); - save_errno = errno; - } + ok = a_write (desc, Qnil, XINT (start), XINT (end) - XINT (start), + &annotations, &coding); else { - /* If file was empty, still need to write the annotations */ + /* If file was empty, still need to write the annotations. */ coding.mode |= CODING_MODE_LAST_BLOCK; - failure = 0 > a_write (desc, Qnil, XINT (end), 0, &annotations, &coding); - save_errno = errno; + ok = a_write (desc, Qnil, XINT (end), 0, &annotations, &coding); } + save_errno = errno; - if (CODING_REQUIRE_FLUSHING (&coding) - && !(coding.mode & CODING_MODE_LAST_BLOCK) - && ! failure) + if (ok && CODING_REQUIRE_FLUSHING (&coding) + && !(coding.mode & CODING_MODE_LAST_BLOCK)) { /* We have to flush out a data. */ coding.mode |= CODING_MODE_LAST_BLOCK; - failure = 0 > e_write (desc, Qnil, 1, 1, &coding); + ok = e_write (desc, Qnil, 1, 1, &coding); save_errno = errno; } @@ -4760,13 +4746,13 @@ This calls `write-region-annotate-functions' at the start, and ignore EINVAL which happens when fsync is not supported on this file. */ if (errno != EINTR && errno != EINVAL) - failure = 1, save_errno = errno; + ok = 0, save_errno = errno; } #endif /* NFS can report a write failure now. */ if (emacs_close (desc) < 0) - failure = 1, save_errno = errno; + ok = 0, save_errno = errno; stat (fn, &st); @@ -4803,7 +4789,7 @@ This calls `write-region-annotate-functions' at the start, and current_buffer->modtime_size = st.st_size; } - if (failure) + if (! ok) error ("IO error writing %s: %s", SDATA (filename), emacs_strerror (save_errno)); @@ -4859,7 +4845,8 @@ build_annotations (Lisp_Object start, Lisp_Object end) Lisp_Object p, res; struct gcpro gcpro1, gcpro2; Lisp_Object original_buffer; - int i, used_global = 0; + int i; + bool used_global = 0; XSETBUFFER (original_buffer, current_buffer); @@ -4939,11 +4926,11 @@ build_annotations (Lisp_Object start, Lisp_Object end) We modify *ANNOT by discarding elements as we use them up. - The return value is negative in case of system call failure. */ + Return true if successful. */ -static int +static bool a_write (int desc, Lisp_Object string, ptrdiff_t pos, - register ptrdiff_t nchars, Lisp_Object *annot, + ptrdiff_t nchars, Lisp_Object *annot, struct coding_system *coding) { Lisp_Object tem; @@ -4965,29 +4952,29 @@ a_write (int desc, Lisp_Object string, ptrdiff_t pos, /* Output buffer text up to the next annotation's position. */ if (nextpos > pos) { - if (0 > e_write (desc, string, pos, nextpos, coding)) - return -1; + if (!e_write (desc, string, pos, nextpos, coding)) + return 0; pos = nextpos; } /* Output the annotation. */ tem = Fcdr (Fcar (*annot)); if (STRINGP (tem)) { - if (0 > e_write (desc, tem, 0, SCHARS (tem), coding)) - return -1; + if (!e_write (desc, tem, 0, SCHARS (tem), coding)) + return 0; } *annot = Fcdr (*annot); } - return 0; + return 1; } /* Write text in the range START and END into descriptor DESC, encoding them with coding system CODING. If STRING is nil, START and END are character positions of the current buffer, else they - are indexes to the string STRING. */ + are indexes to the string STRING. Return true if successful. */ -static int +static bool e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end, struct coding_system *coding) { @@ -5056,12 +5043,12 @@ e_write (int desc, Lisp_Object string, ptrdiff_t start, ptrdiff_t end, coding->produced); if (coding->produced) - return -1; + return 0; } start += coding->consumed_char; } - return 0; + return 1; } DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, @@ -5300,12 +5287,12 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) { struct buffer *old = current_buffer, *b; Lisp_Object tail, buf, hook; - int auto_saved = 0; + bool auto_saved = 0; int do_handled_files; Lisp_Object oquit; FILE *stream = NULL; ptrdiff_t count = SPECPDL_INDEX (); - int orig_minibuffer_auto_raise = minibuffer_auto_raise; + bool orig_minibuffer_auto_raise = minibuffer_auto_raise; bool old_message_p = 0; struct gcpro gcpro1, gcpro2; @@ -5452,7 +5439,7 @@ A non-nil CURRENT-ONLY argument means save only current buffer. */) if (!auto_saved && NILP (no_message)) message1 ("Auto-saving..."); internal_condition_case (auto_save_1, Qt, auto_save_error); - auto_saved++; + auto_saved = 1; BUF_AUTOSAVE_MODIFF (b) = BUF_MODIFF (b); XSETFASTINT (BVAR (current_buffer, save_length), Z - BEG); 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/>. */ /* Return the time of the last system boot. */ static time_t boot_time; -static int boot_time_initialized; +static bool boot_time_initialized; #ifdef BOOT_TIME -static void get_boot_time_1 (const char *, int); +static void get_boot_time_1 (const char *, bool); #endif static time_t @@ -170,7 +170,7 @@ get_boot_time (void) { char cmd_string[sizeof WTMP_FILE ".19.gz"]; Lisp_Object tempname, filename; - int delete_flag = 0; + bool delete_flag = 0; filename = Qnil; @@ -225,13 +225,13 @@ get_boot_time (void) If FILENAME is zero, use the same file as before; if no FILENAME has ever been specified, this is the utmp file. - Use the newest reboot record if NEWEST is nonzero, + Use the newest reboot record if NEWEST, the first reboot record otherwise. Ignore all reboot records on or before BOOT_TIME. Success is indicated by setting BOOT_TIME to a larger value. */ void -get_boot_time_1 (const char *filename, int newest) +get_boot_time_1 (const char *filename, bool newest) { struct utmp ut, *utp; int desc; @@ -331,11 +331,11 @@ fill_in_lock_file_name (register char *lockfile, register Lisp_Object fn) } /* Lock the lock file named LFNAME. - If FORCE is nonzero, we do so even if it is already locked. - Return 1 if successful, 0 if not. */ + If FORCE, do so even if it is already locked. + Return true if successful. */ -static int -lock_file_1 (char *lfname, int force) +static bool +lock_file_1 (char *lfname, bool force) { int err; int symlink_errno; @@ -370,9 +370,9 @@ lock_file_1 (char *lfname, int force) return err == 0; } -/* Return 1 if times A and B are no more than one second apart. */ +/* Return true if times A and B are no more than one second apart. */ -static int +static bool within_one_second (time_t a, time_t b) { return (a - b >= -1 && a - b <= 1); @@ -491,7 +491,7 @@ current_lock_owner (lock_info_type *owner, char *lfname) static int lock_if_free (lock_info_type *clasher, register char *lfname) { - while (lock_file_1 (lfname, 0) == 0) + while (! lock_file_1 (lfname, 0)) { int locker; 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/>. */ Define FLOAT_CHECK_ERRNO if the float library routines set errno. This has no effect if HAVE_MATHERR is defined. - Define FLOAT_CATCH_SIGILL if the float library routines signal SIGILL. - (What systems actually do this? Please let us know.) - Define FLOAT_CHECK_DOMAIN if the float library doesn't handle errors by either setting errno, or signaling SIGFPE/SIGILL. Otherwise, domain and range checking will happen before calling the float routines. This has @@ -99,14 +96,10 @@ extern double logb (double); # include <errno.h> #endif -#ifdef FLOAT_CATCH_SIGILL -static void float_error (); -#endif - -/* Nonzero while executing in floating point. +/* True while executing in floating point. This tells float_error what to do. */ -static int in_float; +static bool in_float; /* If an argument is out of range for a mathematical function, here is the actual argument value to use in the error message. @@ -947,31 +940,6 @@ Rounds the value toward zero. */) return make_float (d); } -#ifdef FLOAT_CATCH_SIGILL -static void -float_error (int signo) -{ - if (! in_float) - fatal_error_signal (signo); - -#ifdef BSD_SYSTEM - sigsetmask (SIGEMPTYMASK); -#else - /* Must reestablish handler each time it is called. */ - signal (SIGILL, float_error); -#endif /* BSD_SYSTEM */ - - SIGNAL_THREAD_CHECK (signo); - in_float = 0; - - xsignal1 (Qarith_error, float_error_arg); -} - -/* Another idea was to replace the library function `infnan' - where SIGILL is signaled. */ - -#endif /* FLOAT_CATCH_SIGILL */ - #ifdef HAVE_MATHERR int matherr (struct exception *x) @@ -1006,9 +974,6 @@ matherr (struct exception *x) void init_floatfns (void) { -#ifdef FLOAT_CATCH_SIGILL - signal (SIGILL, float_error); -#endif in_float = 0; } 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; static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512; -static int internal_equal (Lisp_Object , Lisp_Object, int, int); +static bool internal_equal (Lisp_Object, Lisp_Object, int, bool); DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0, doc: /* Return the argument unchanged. */) @@ -352,7 +352,7 @@ Symbols are also allowed; their print names are used instead. */) } static Lisp_Object concat (ptrdiff_t nargs, Lisp_Object *args, - enum Lisp_Type target_type, int last_special); + enum Lisp_Type target_type, bool last_special); /* ARGSUSED */ Lisp_Object @@ -450,19 +450,19 @@ struct textprop_rec static Lisp_Object concat (ptrdiff_t nargs, Lisp_Object *args, - enum Lisp_Type target_type, int last_special) + enum Lisp_Type target_type, bool last_special) { Lisp_Object val; - register Lisp_Object tail; - register Lisp_Object this; + Lisp_Object tail; + Lisp_Object this; ptrdiff_t toindex; ptrdiff_t toindex_byte = 0; - register EMACS_INT result_len; - register EMACS_INT result_len_byte; + EMACS_INT result_len; + EMACS_INT result_len_byte; ptrdiff_t argnum; Lisp_Object last_tail; Lisp_Object prev; - int some_multibyte; + bool some_multibyte; /* When we make a multibyte string, we can't copy text properties while concatenating each string because the length of resulting string can't be decided until we finish the whole concatenation. @@ -1988,10 +1988,10 @@ of strings. (`equal' ignores text properties.) */) /* DEPTH is current depth of recursion. Signal an error if it gets too deep. - PROPS, if non-nil, means compare string text properties too. */ + PROPS means compare string text properties too. */ -static int -internal_equal (register Lisp_Object o1, register Lisp_Object o2, int depth, int props) +static bool +internal_equal (Lisp_Object o1, Lisp_Object o2, int depth, bool props) { if (depth > 200) error ("Stack overflow in equal"); @@ -2589,9 +2589,9 @@ Normally the return value is FEATURE. The normal messages at start and end of loading FILENAME are suppressed. */) (Lisp_Object feature, Lisp_Object filename, Lisp_Object noerror) { - register Lisp_Object tem; + Lisp_Object tem; struct gcpro gcpro1, gcpro2; - int from_file = load_in_progress; + bool from_file = load_in_progress; CHECK_SYMBOL (feature); @@ -2917,8 +2917,8 @@ static const short base64_char_to_value[128] = base64 characters. */ -static ptrdiff_t base64_encode_1 (const char *, char *, ptrdiff_t, int, int); -static ptrdiff_t base64_decode_1 (const char *, char *, ptrdiff_t, int, +static ptrdiff_t base64_encode_1 (const char *, char *, ptrdiff_t, bool, bool); +static ptrdiff_t base64_decode_1 (const char *, char *, ptrdiff_t, bool, ptrdiff_t *); DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region, @@ -3026,7 +3026,7 @@ into shorter lines. */) static ptrdiff_t base64_encode_1 (const char *from, char *to, ptrdiff_t length, - int line_break, int multibyte) + bool line_break, bool multibyte) { int counter = 0; ptrdiff_t i = 0; @@ -3133,7 +3133,7 @@ If the region can't be decoded, signal an error and don't modify the buffer. */ ptrdiff_t old_pos = PT; ptrdiff_t decoded_length; ptrdiff_t inserted_chars; - int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); + bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); USE_SAFE_ALLOCA; validate_region (&beg, &end); @@ -3218,13 +3218,13 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string, } /* Base64-decode the data at FROM of LENGTH bytes into TO. If - MULTIBYTE is nonzero, the decoded result should be in multibyte + MULTIBYTE, the decoded result should be in multibyte form. If NCHARS_RETURN is not NULL, store the number of produced characters in *NCHARS_RETURN. */ static ptrdiff_t base64_decode_1 (const char *from, char *to, ptrdiff_t length, - int multibyte, ptrdiff_t *nchars_return) + bool multibyte, ptrdiff_t *nchars_return) { ptrdiff_t i = 0; /* Used inside READ_QUADRUPLET_BYTE */ char *e = to; @@ -3340,7 +3340,7 @@ static Lisp_Object Qhash_table_test, Qkey_or_value, Qkey_and_value; static struct Lisp_Hash_Table *check_hash_table (Lisp_Object); static ptrdiff_t get_key_arg (Lisp_Object, ptrdiff_t, Lisp_Object *, char *); static void maybe_resize_hash_table (struct Lisp_Hash_Table *); -static int sweep_weak_table (struct Lisp_Hash_Table *, int); +static bool sweep_weak_table (struct Lisp_Hash_Table *, bool); @@ -3432,10 +3432,10 @@ larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max) ***********************************************************************/ /* Compare KEY1 which has hash code HASH1 and KEY2 with hash code - HASH2 in hash table H using `eql'. Value is non-zero if KEY1 and + HASH2 in hash table H using `eql'. Value is true if KEY1 and KEY2 are the same. */ -static int +static bool cmpfn_eql (struct Lisp_Hash_Table *h, Lisp_Object key1, EMACS_UINT hash1, Lisp_Object key2, EMACS_UINT hash2) @@ -3447,10 +3447,10 @@ cmpfn_eql (struct Lisp_Hash_Table *h, /* Compare KEY1 which has hash code HASH1 and KEY2 with hash code - HASH2 in hash table H using `equal'. Value is non-zero if KEY1 and + HASH2 in hash table H using `equal'. Value is true if KEY1 and KEY2 are the same. */ -static int +static bool cmpfn_equal (struct Lisp_Hash_Table *h, Lisp_Object key1, EMACS_UINT hash1, Lisp_Object key2, EMACS_UINT hash2) @@ -3460,10 +3460,10 @@ cmpfn_equal (struct Lisp_Hash_Table *h, /* Compare KEY1 which has hash code HASH1, and KEY2 with hash code - HASH2 in hash table H using H->user_cmp_function. Value is non-zero + HASH2 in hash table H using H->user_cmp_function. Value is true if KEY1 and KEY2 are the same. */ -static int +static bool cmpfn_user_defined (struct Lisp_Hash_Table *h, Lisp_Object key1, EMACS_UINT hash1, Lisp_Object key2, EMACS_UINT hash2) @@ -3923,16 +3923,16 @@ hash_clear (struct Lisp_Hash_Table *h) Weak Hash Tables ************************************************************************/ -/* Sweep weak hash table H. REMOVE_ENTRIES_P non-zero means remove +/* Sweep weak hash table H. REMOVE_ENTRIES_P means remove entries from the table that don't survive the current GC. - REMOVE_ENTRIES_P zero means mark entries that are in use. Value is - non-zero if anything was marked. */ + !REMOVE_ENTRIES_P means mark entries that are in use. Value is + true if anything was marked. */ -static int -sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p) +static bool +sweep_weak_table (struct Lisp_Hash_Table *h, bool remove_entries_p) { ptrdiff_t bucket, n; - int marked; + bool marked; n = ASIZE (h->index) & ~ARRAY_MARK_FLAG; marked = 0; @@ -3949,7 +3949,7 @@ sweep_weak_table (struct Lisp_Hash_Table *h, int remove_entries_p) ptrdiff_t i = XFASTINT (idx); bool key_known_to_survive_p = survives_gc_p (HASH_KEY (h, i)); bool value_known_to_survive_p = survives_gc_p (HASH_VALUE (h, i)); - int remove_p; + bool remove_p; if (EQ (h->weak, Qkey)) remove_p = !key_known_to_survive_p; @@ -4022,7 +4022,7 @@ void sweep_weak_hash_tables (void) { struct Lisp_Hash_Table *h, *used, *next; - int marked; + bool marked; /* Mark all keys and values that are in use. Keep on marking until 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_ coding_system = Vcoding_system_for_write; else { - int force_raw_text = 0; + bool force_raw_text = 0; coding_system = BVAR (XBUFFER (object), buffer_file_coding_system); 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 #define FRAME_FOREGROUND_PIXEL(f) ((f)->foreground_pixel) #define FRAME_BACKGROUND_PIXEL(f) ((f)->background_pixel) -struct terminal; - -struct font_driver_list; struct frame { 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); static Lisp_Object apply_modifiers (int, Lisp_Object); static void clear_event (struct input_event *); static Lisp_Object restore_kboard_configuration (Lisp_Object); -static void interrupt_signal (int signalnum); #ifdef SIGIO -static void input_available_signal (int signo); +static void deliver_input_available_signal (int signo); #endif static void handle_interrupt (void); static _Noreturn void quit_throw_to_read_char (int); @@ -459,7 +458,7 @@ static void process_special_events (void); static void timer_start_idle (void); static void timer_stop_idle (void); static void timer_resume_idle (void); -static void handle_user_signal (int); +static void deliver_user_signal (int); static char *find_user_signal_name (int); static int store_user_signal_events (void); @@ -3833,7 +3832,7 @@ kbd_buffer_get_event (KBOARD **kbp, unhold_keyboard_input (); #ifdef SIGIO if (!noninteractive) - signal (SIGIO, input_available_signal); + signal (SIGIO, deliver_input_available_signal); #endif /* SIGIO */ start_polling (); } @@ -7236,12 +7235,8 @@ process_pending_signals (void) /* Note SIGIO has been undef'd if FIONREAD is missing. */ static void -input_available_signal (int signo) +handle_input_available_signal (int sig) { - /* Must preserve main program's value of errno. */ - int old_errno = errno; - SIGNAL_THREAD_CHECK (signo); - #ifdef SYNC_INPUT interrupt_input_pending = 1; pending_signals = 1; @@ -7253,8 +7248,12 @@ input_available_signal (int signo) #ifndef SYNC_INPUT handle_async_input (); #endif +} - errno = old_errno; +static void +deliver_input_available_signal (int sig) +{ + handle_on_main_thread (sig, handle_input_available_signal); } #endif /* SIGIO */ @@ -7310,18 +7309,15 @@ add_user_signal (int sig, const char *name) p->next = user_signals; user_signals = p; - signal (sig, handle_user_signal); + signal (sig, deliver_user_signal); } static void handle_user_signal (int sig) { - int old_errno = errno; struct user_signal_info *p; const char *special_event_name = NULL; - SIGNAL_THREAD_CHECK (sig); - if (SYMBOLP (Vdebug_on_event)) special_event_name = SSDATA (SYMBOL_NAME (Vdebug_on_event)); @@ -7355,8 +7351,12 @@ handle_user_signal (int sig) } break; } +} - errno = old_errno; +static void +deliver_user_signal (int sig) +{ + handle_on_main_thread (sig, handle_user_signal); } static char * @@ -10776,17 +10776,10 @@ clear_waiting_for_input (void) Otherwise, tell QUIT to kill Emacs. */ static void -interrupt_signal (int signalnum) /* If we don't have an argument, some */ - /* compilers complain in signal calls. */ +handle_interrupt_signal (int sig) { - /* Must preserve main program's value of errno. */ - int old_errno = errno; - struct terminal *terminal; - - SIGNAL_THREAD_CHECK (signalnum); - /* See if we have an active terminal on our controlling tty. */ - terminal = get_named_tty ("/dev/tty"); + struct terminal *terminal = get_named_tty ("/dev/tty"); if (!terminal) { /* 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 */ handle_interrupt (); } +} - errno = old_errno; +static void +deliver_interrupt_signal (int sig) +{ + handle_on_main_thread (sig, handle_interrupt_signal); } + /* If Emacs is stuck because `inhibit-quit' is true, then keep track of the number of times C-g has been requested. If C-g is pressed enough times, then quit anyway. See bug#6585. */ @@ -11404,17 +11402,17 @@ init_keyboard (void) SIGINT. There is special code in interrupt_signal to exit Emacs on SIGINT when there are no termcap frames on the controlling terminal. */ - signal (SIGINT, interrupt_signal); + signal (SIGINT, deliver_interrupt_signal); #ifndef DOS_NT /* For systems with SysV TERMIO, C-g is set up for both SIGINT and SIGQUIT and we can't tell which one it will give us. */ - signal (SIGQUIT, interrupt_signal); + signal (SIGQUIT, deliver_interrupt_signal); #endif /* not DOS_NT */ } /* Note SIGIO has been undef'd if FIONREAD is missing. */ #ifdef SIGIO if (!noninteractive) - signal (SIGIO, input_available_signal); + signal (SIGIO, deliver_input_available_signal); #endif /* SIGIO */ /* 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 (ASCII_CHAR_P (IDX) ? CHAR_TABLE_REF_ASCII ((CT), (IDX)) \ : char_table_ref ((CT), (IDX))) -/* Almost equivalent to Faref (CT, IDX). However, if the result is - not a character, return IDX. - - For these characters, do not check validity of CT - and do not follow parent. */ -#define CHAR_TABLE_TRANSLATE(CT, IDX) \ - char_table_translate (CT, IDX) - /* Equivalent to Faset (CT, IDX, VAL) with optimization for ASCII and 8-bit European characters. Do not check validity of CT. */ #define CHAR_TABLE_SET(CT, IDX, VAL) \ @@ -1205,9 +1197,9 @@ struct Lisp_Hash_Table struct Lisp_Hash_Table *next_weak; /* C function to compare two keys. */ - int (*cmpfn) (struct Lisp_Hash_Table *, - Lisp_Object, EMACS_UINT, - Lisp_Object, EMACS_UINT); + bool (*cmpfn) (struct Lisp_Hash_Table *, + Lisp_Object, EMACS_UINT, + Lisp_Object, EMACS_UINT); /* C function to compute hash code. */ EMACS_UINT (*hashfn) (struct Lisp_Hash_Table *, Lisp_Object); @@ -3151,9 +3143,9 @@ EXFUN (Fread_file_name, 6); /* not a normal DEFUN */ extern Lisp_Object close_file_unwind (Lisp_Object); extern Lisp_Object restore_point_unwind (Lisp_Object); extern _Noreturn void report_file_error (const char *, Lisp_Object); -extern int internal_delete_file (Lisp_Object); +extern void internal_delete_file (Lisp_Object); extern void syms_of_fileio (void); -extern Lisp_Object make_temp_name (Lisp_Object, int); +extern Lisp_Object make_temp_name (Lisp_Object, bool); extern Lisp_Object Qdelete_file; /* Defined in search.c */ @@ -3264,9 +3256,6 @@ extern bool display_arg; extern Lisp_Object decode_env_path (const char *, const char *); extern Lisp_Object empty_unibyte_string, empty_multibyte_string; extern Lisp_Object Qfile_name_handler_alist; -#ifdef FLOAT_CATCH_SIGILL -extern void fatal_error_signal (int); -#endif extern _Noreturn void fatal_error_backtrace (int, int); extern Lisp_Object Qkill_emacs; #if HAVE_SETLOCALE @@ -3556,32 +3545,6 @@ extern void init_system_name (void); #define make_fixnum_or_float(val) \ (FIXNUM_OVERFLOW_P (val) ? make_float (val) : make_number (val)) - -/* Checks the `cycle check' variable CHECK to see if it indicates that - EL is part of a cycle; CHECK must be either Qnil or a value returned - by an earlier use of CYCLE_CHECK. SUSPICIOUS is the number of - elements after which a cycle might be suspected; after that many - elements, this macro begins consing in order to keep more precise - track of elements. - - Returns nil if a cycle was detected, otherwise a new value for CHECK - that includes EL. - - CHECK is evaluated multiple times, EL and SUSPICIOUS 0 or 1 times, so - the caller should make sure that's ok. */ - -#define CYCLE_CHECK(check, el, suspicious) \ - (NILP (check) \ - ? make_number (0) \ - : (INTEGERP (check) \ - ? (XFASTINT (check) < (suspicious) \ - ? make_number (XFASTINT (check) + 1) \ - : Fcons (el, Qnil)) \ - : (!NILP (Fmemq ((el), (check))) \ - ? Qnil \ - : Fcons ((el), (check))))) - - /* SAFE_ALLOCA normally allocates memory on the stack, but if size is larger than MAX_ALLOCA, use xmalloc to avoid overflowing the stack. */ 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/>. */ #include "xgselect.h" #endif +#ifndef WNOHANG +# undef waitpid +# define waitpid(pid, status, options) wait (status) +#endif +#ifndef WUNTRACED +# define WUNTRACED 0 +#endif + /* Work around GCC 4.7.0 bug with strict overflow checking; see <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>. These lines can be removed once the GCC bug is fixed. */ @@ -801,7 +809,7 @@ get_process (register Lisp_Object name) #ifdef SIGCHLD /* Fdelete_process promises to immediately forget about the process, but in reality, Emacs needs to remember those processes until they have been - treated by sigchld_handler; otherwise this handler would consider the + treated by the SIGCHLD handler; otherwise this handler would consider the process as being synchronous and say that the synchronous process is dead. */ static Lisp_Object deleted_pid_list; @@ -849,7 +857,8 @@ nil, indicating the current buffer's process. */) #endif { Fkill_process (process, Qnil); - /* Do this now, since remove_process will make sigchld_handler do nothing. */ + /* Do this now, since remove_process will make the + SIGCHLD handler do nothing. */ pset_status (p, Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil))); p->tick = ++process_tick; status_notify (p); @@ -1728,7 +1737,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) if (inchannel > max_process_desc) max_process_desc = inchannel; - /* Until we store the proper pid, enable sigchld_handler + /* Until we store the proper pid, enable the SIGCHLD handler to recognize an unknown pid as standing for this process. It is very important not to let this `marker' value stay 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, if (p->pid == -2) { - /* If the EIO occurs on a pty, sigchld_handler's - waitpid() will not find the process object to + /* If the EIO occurs on a pty, the SIGCHLD handler's + waitpid call will not find the process object to delete. Do it here. */ p->tick = ++process_tick; pset_status (p, Qfailed); @@ -5422,18 +5431,19 @@ read_process_output (Lisp_Object proc, register int channel) static jmp_buf send_process_frame; static Lisp_Object process_sent_to; -#ifndef FORWARD_SIGNAL_TO_MAIN_THREAD -static _Noreturn void send_process_trap (int); -#endif - -static void -send_process_trap (int ignore) +static _Noreturn void +handle_pipe_signal (int sig) { - SIGNAL_THREAD_CHECK (SIGPIPE); sigunblock (sigmask (SIGPIPE)); _longjmp (send_process_frame, 1); } +static void +deliver_pipe_signal (int sig) +{ + handle_on_main_thread (sig, handle_pipe_signal); +} + /* In send_process, when a write fails temporarily, wait_reading_process_output is called. It may execute user code, 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, /* Send this batch, using one or more write calls. */ ptrdiff_t written = 0; int outfd = p->outfd; - old_sigpipe = (void (*) (int)) signal (SIGPIPE, send_process_trap); + old_sigpipe = signal (SIGPIPE, deliver_pipe_signal); #ifdef DATAGRAM_SOCKETS if (DATAGRAM_CHAN_P (outfd)) { @@ -6397,143 +6407,135 @@ process has been transmitted to the serial port. */) indirectly; if it does, that is a bug */ #ifdef SIGCHLD -static void -sigchld_handler (int signo) + +/* Record one child's changed status. Return true if a child was found. */ +static bool +record_child_status_change (void) { - int old_errno = errno; Lisp_Object proc; struct Lisp_Process *p; + pid_t pid; + int w; + Lisp_Object tail; - SIGNAL_THREAD_CHECK (signo); - - while (1) - { - pid_t pid; - int w; - Lisp_Object tail; - -#ifdef WNOHANG -#ifndef WUNTRACED -#define WUNTRACED 0 -#endif /* no WUNTRACED */ - /* Keep trying to get a status until we get a definitive result. */ - do - { - errno = 0; - pid = waitpid (-1, &w, WNOHANG | WUNTRACED); - } - while (pid < 0 && errno == EINTR); - - if (pid <= 0) - { - /* PID == 0 means no processes found, PID == -1 means a real - failure. We have done all our job, so return. */ + do + pid = waitpid (-1, &w, WNOHANG | WUNTRACED); + while (pid < 0 && errno == EINTR); - errno = old_errno; - return; - } -#else - pid = wait (&w); -#endif /* no WNOHANG */ + /* PID == 0 means no processes found, PID == -1 means a real failure. + Either way, we have done all our job. */ + if (pid <= 0) + return false; - /* Find the process that signaled us, and record its status. */ + /* Find the process that signaled us, and record its status. */ - /* The process can have been deleted by Fdelete_process. */ - for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) + /* The process can have been deleted by Fdelete_process. */ + for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) + { + Lisp_Object xpid = XCAR (tail); + if ((INTEGERP (xpid) && pid == XINT (xpid)) + || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid))) { - Lisp_Object xpid = XCAR (tail); - if ((INTEGERP (xpid) && pid == XINT (xpid)) - || (FLOATP (xpid) && pid == XFLOAT_DATA (xpid))) - { - XSETCAR (tail, Qnil); - goto sigchld_end_of_loop; - } + XSETCAR (tail, Qnil); + return true; } + } - /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ + /* Otherwise, if it is asynchronous, it is in Vprocess_alist. */ + p = 0; + for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) + { + proc = XCDR (XCAR (tail)); + p = XPROCESS (proc); + if (EQ (p->type, Qreal) && p->pid == pid) + break; p = 0; - for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) - { - proc = XCDR (XCAR (tail)); - p = XPROCESS (proc); - if (EQ (p->type, Qreal) && p->pid == pid) - break; - p = 0; - } - - /* Look for an asynchronous process whose pid hasn't been filled - in yet. */ - if (p == 0) - for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) - { - proc = XCDR (XCAR (tail)); - p = XPROCESS (proc); - if (p->pid == -1) - break; - p = 0; - } - - /* Change the status of the process that was found. */ - if (p != 0) - { - int clear_desc_flag = 0; + } - p->tick = ++process_tick; - p->raw_status = w; - p->raw_status_new = 1; + /* Look for an asynchronous process whose pid hasn't been filled + in yet. */ + if (! p) + for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail)) + { + proc = XCDR (XCAR (tail)); + p = XPROCESS (proc); + if (p->pid == -1) + break; + p = 0; + } - /* If process has terminated, stop waiting for its output. */ - if ((WIFSIGNALED (w) || WIFEXITED (w)) - && p->infd >= 0) - clear_desc_flag = 1; + /* Change the status of the process that was found. */ + if (p) + { + int clear_desc_flag = 0; - /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ - if (clear_desc_flag) - { - FD_CLR (p->infd, &input_wait_mask); - FD_CLR (p->infd, &non_keyboard_wait_mask); - } + p->tick = ++process_tick; + p->raw_status = w; + p->raw_status_new = 1; - /* Tell wait_reading_process_output that it needs to wake up and - look around. */ - if (input_available_clear_time) - *input_available_clear_time = make_emacs_time (0, 0); - } + /* If process has terminated, stop waiting for its output. */ + if ((WIFSIGNALED (w) || WIFEXITED (w)) + && p->infd >= 0) + clear_desc_flag = 1; - /* There was no asynchronous process found for that pid: we have - a synchronous process. */ - else + /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ + if (clear_desc_flag) { - synch_process_alive = 0; - - /* Report the status of the synchronous process. */ - if (WIFEXITED (w)) - synch_process_retcode = WEXITSTATUS (w); - else if (WIFSIGNALED (w)) - synch_process_termsig = WTERMSIG (w); - - /* Tell wait_reading_process_output that it needs to wake up and - look around. */ - if (input_available_clear_time) - *input_available_clear_time = make_emacs_time (0, 0); + FD_CLR (p->infd, &input_wait_mask); + FD_CLR (p->infd, &non_keyboard_wait_mask); } - sigchld_end_of_loop: - ; + /* Tell wait_reading_process_output that it needs to wake up and + look around. */ + if (input_available_clear_time) + *input_available_clear_time = make_emacs_time (0, 0); + } + /* There was no asynchronous process found for that pid: we have + a synchronous process. */ + else + { + synch_process_alive = 0; + + /* Report the status of the synchronous process. */ + if (WIFEXITED (w)) + synch_process_retcode = WEXITSTATUS (w); + else if (WIFSIGNALED (w)) + synch_process_termsig = WTERMSIG (w); + + /* Tell wait_reading_process_output that it needs to wake up and + look around. */ + if (input_available_clear_time) + *input_available_clear_time = make_emacs_time (0, 0); + } + + return true; +} - /* On some systems, we must return right away. - If any more processes want to signal us, we will - get another signal. - Otherwise (on systems that have WNOHANG), loop around - to use up all the processes that have something to tell us. */ +/* On some systems, the SIGCHLD handler must return right away. If + any more processes want to signal us, we will get another signal. + Otherwise, loop around to use up all the processes that have + something to tell us. */ #if (defined WINDOWSNT \ || (defined USG && !defined GNU_LINUX \ && !(defined HPUX && defined WNOHANG))) - errno = old_errno; - return; -#endif /* USG, but not HPUX with WNOHANG */ - } +enum { CAN_HANDLE_MULTIPLE_CHILDREN = 1 }; +#else +enum { CAN_HANDLE_MULTIPLE_CHILDREN = 0 }; +#endif + +static void +handle_child_signal (int sig) +{ + while (record_child_status_change () && CAN_HANDLE_MULTIPLE_CHILDREN) + continue; } + +static void +deliver_child_signal (int sig) +{ + handle_on_main_thread (sig, handle_child_signal); +} + #endif /* SIGCHLD */ @@ -7387,7 +7389,7 @@ init_process_emacs (void) #ifndef CANNOT_DUMP if (! noninteractive || initialized) #endif - signal (SIGCHLD, sigchld_handler); + signal (SIGCHLD, deliver_child_signal); #endif 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) return (old_mask); } +#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD +pthread_t main_thread; +#endif + +/* If we are on the main thread, handle the signal SIG with HANDLER. + Otherwise, redirect the signal to the main thread, blocking it from + this thread. POSIX says any thread can receive a signal that is + associated with a process, process group, or asynchronous event. + On GNU/Linux that is not true, but for other systems (FreeBSD at + least) it is. */ +void +handle_on_main_thread (int sig, signal_handler_t handler) +{ + /* Preserve errno, to avoid race conditions with signal handlers that + might change errno. Races can occur even in single-threaded hosts. */ + int old_errno = errno; + + bool on_main_thread = true; +#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD + if (! pthread_equal (pthread_self (), main_thread)) + { + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, sig); + pthread_sigmask (SIG_BLOCK, &blocked, 0); + pthread_kill (main_thread, sig); + on_main_thread = false; + } +#endif + if (on_main_thread) + handler (sig); + + errno = old_errno; +} #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST static char *my_sys_siglist[NSIG]; @@ -1565,6 +1599,10 @@ init_signals (void) { sigemptyset (&empty_mask); +#ifdef FORWARD_SIGNAL_TO_MAIN_THREAD + main_thread = pthread_self (); +#endif + #if !defined HAVE_STRSIGNAL && !HAVE_DECL_SYS_SIGLIST if (! initialized) { 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); #ifdef FORWARD_SIGNAL_TO_MAIN_THREAD extern pthread_t main_thread; -#define SIGNAL_THREAD_CHECK(signo) \ - do { \ - if (!pthread_equal (pthread_self (), main_thread)) \ - { \ - /* POSIX says any thread can receive the signal. On GNU/Linux \ - that is not true, but for other systems (FreeBSD at least) \ - it is. So direct the signal to the correct thread and block \ - it from this thread. */ \ - sigset_t new_mask; \ - \ - sigemptyset (&new_mask); \ - sigaddset (&new_mask, signo); \ - pthread_sigmask (SIG_BLOCK, &new_mask, 0); \ - pthread_kill (main_thread, signo); \ - return; \ - } \ - } while (0) - -#else /* not FORWARD_SIGNAL_TO_MAIN_THREAD */ -#define SIGNAL_THREAD_CHECK(signo) -#endif /* not FORWARD_SIGNAL_TO_MAIN_THREAD */ +void handle_on_main_thread (int, signal_handler_t); +#endif 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) /* Return 1 if window configurations CONFIGURATION1 and CONFIGURATION2 describe the same state of affairs. This is used by Fequal. - ignore_positions non-zero means ignore non-matching scroll positions + IGNORE_POSITIONS means ignore non-matching scroll positions and the like. This ignores a couple of things like the dedication status of window, combination_limit and the like. This might have to be fixed. */ -int -compare_window_configurations (Lisp_Object configuration1, Lisp_Object configuration2, int ignore_positions) +bool +compare_window_configurations (Lisp_Object configuration1, + Lisp_Object configuration2, + bool ignore_positions) { register struct save_window_data *d1, *d2; 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 # define WINDOW_INLINE INLINE #endif -extern Lisp_Object Qleft, Qright; - /* Windows are allocated as if they were vectors, but then the Lisp data type is changed to Lisp_Window. They are garbage collected along with the vectors. @@ -973,7 +971,7 @@ extern Lisp_Object Qwindowp, Qwindow_live_p; extern Lisp_Object Vwindow_list; extern struct window *decode_live_window (Lisp_Object); -extern int compare_window_configurations (Lisp_Object, Lisp_Object, int); +extern bool compare_window_configurations (Lisp_Object, Lisp_Object, bool); extern void mark_window_cursors_off (struct window *); extern int window_internal_height (struct window *); extern 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, message_buf_print = 0; help_echo_showing_p = 0; - if (NILP (Vinhibit_debug_on_message) && - STRINGP (Vdebug_on_message) && - fast_string_match (Vdebug_on_message, string) >= 0) { - specbind (Qinhibit_debug_on_message, Qt); - call_debugger (Fcons (Qerror, Fcons (string, Qnil))); - } + if (NILP (Vinhibit_debug_on_message) && STRINGP (Vdebug_on_message) + && fast_string_match (Vdebug_on_message, string) >= 0) + { + specbind (Qinhibit_debug_on_message, Qt); + call_debugger (list2 (Qerror, string)); + } unbind_to (count, Qnil); } |
