diff options
| author | Paul Eggert | 2022-09-09 15:22:16 -0500 |
|---|---|---|
| committer | Paul Eggert | 2022-09-09 16:19:49 -0500 |
| commit | fa993926181f8c607fbb1e86c3fe1f7e7bacf5e9 (patch) | |
| tree | ab932ac50c73eb5511ca24eddf49645b56dc63bb /src/process.c | |
| parent | 9189ad45612141cc9db5c3e98de5e44e07e6f9b0 (diff) | |
| download | emacs-fa993926181f8c607fbb1e86c3fe1f7e7bacf5e9.tar.gz emacs-fa993926181f8c607fbb1e86c3fe1f7e7bacf5e9.zip | |
Fix problem with Glib 2.73.2+ and SIGCHLD handler
This code fix is by Stefan Monnier (Bug#57699).
* src/process.c (init_process_emacs) [HAVE_GLIB && !WINDOWSNT]:
Adjust to Glib 2.73.2 behavior change on Linux kernel 5.3+.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/src/process.c b/src/process.c index 7a133cda00f..358899cdede 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -7391,7 +7391,8 @@ child_signal_notify (void) | |||
| 7391 | } | 7391 | } |
| 7392 | 7392 | ||
| 7393 | /* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing | 7393 | /* LIB_CHILD_HANDLER is a SIGCHLD handler that Emacs calls while doing |
| 7394 | its own SIGCHLD handling. On POSIXish systems, glib needs this to | 7394 | its own SIGCHLD handling. On POSIXish systems lacking |
| 7395 | pidfd_open+waitid or using Glib 2.73.1-, Glib needs this to | ||
| 7395 | keep track of its own children. GNUstep is similar. */ | 7396 | keep track of its own children. GNUstep is similar. */ |
| 7396 | 7397 | ||
| 7397 | static void dummy_handler (int sig) {} | 7398 | static void dummy_handler (int sig) {} |
| @@ -8358,7 +8359,7 @@ DEFUN ("signal-names", Fsignal_names, Ssignal_names, 0, 0, 0, | |||
| 8358 | 8359 | ||
| 8359 | #ifdef subprocesses | 8360 | #ifdef subprocesses |
| 8360 | /* Arrange to catch SIGCHLD if this hasn't already been arranged. | 8361 | /* Arrange to catch SIGCHLD if this hasn't already been arranged. |
| 8361 | Invoke this after init_process_emacs, and after glib and/or GNUstep | 8362 | Invoke this after init_process_emacs, and after Glib and/or GNUstep |
| 8362 | futz with the SIGCHLD handler, but before Emacs forks any children. | 8363 | futz with the SIGCHLD handler, but before Emacs forks any children. |
| 8363 | This function's caller should block SIGCHLD. */ | 8364 | This function's caller should block SIGCHLD. */ |
| 8364 | 8365 | ||
| @@ -8423,26 +8424,35 @@ init_process_emacs (int sockfd) | |||
| 8423 | if (!will_dump_with_unexec_p ()) | 8424 | if (!will_dump_with_unexec_p ()) |
| 8424 | { | 8425 | { |
| 8425 | #if defined HAVE_GLIB && !defined WINDOWSNT | 8426 | #if defined HAVE_GLIB && !defined WINDOWSNT |
| 8426 | /* Tickle glib's child-handling code. Ask glib to install a | 8427 | /* Tickle Glib's child-handling code. Ask Glib to install a |
| 8427 | watch source for Emacs itself which will initialize glib's | 8428 | watch source for Emacs itself which will initialize glib's |
| 8428 | private SIGCHLD handler, allowing catch_child_signal to copy | 8429 | private SIGCHLD handler, allowing catch_child_signal to copy |
| 8429 | it into lib_child_handler. | 8430 | it into lib_child_handler. This is a hacky workaround to get |
| 8431 | glib's g_unix_signal_handler into lib_child_handler. | ||
| 8430 | 8432 | ||
| 8431 | Unfortunately in glib commit 2e471acf, the behavior changed to | 8433 | In Glib 2.37.5 (2013), commit 2e471acf changed Glib to |
| 8432 | always install a signal handler when g_child_watch_source_new | 8434 | always install a signal handler when g_child_watch_source_new |
| 8433 | is called and not just the first time it's called. Glib also | 8435 | is called and not just the first time it's called, and to |
| 8434 | now resets signal handlers to SIG_DFL when it no longer has a | 8436 | reset signal handlers to SIG_DFL when it no longer has a |
| 8435 | watcher on that signal. This is a hackey work around to get | 8437 | watcher on that signal. Arrange for Emacs's signal handler |
| 8436 | glib's g_unix_signal_handler into lib_child_handler. */ | 8438 | to be reinstalled even if this happens. |
| 8439 | |||
| 8440 | In Glib 2.73.2 (2022), commit f615eef4 changed Glib again, | ||
| 8441 | to not install a signal handler if the system supports | ||
| 8442 | pidfd_open and waitid (as in Linux kernel 5.3+). The hacky | ||
| 8443 | workaround is not needed in this case. */ | ||
| 8437 | GSource *source = g_child_watch_source_new (getpid ()); | 8444 | GSource *source = g_child_watch_source_new (getpid ()); |
| 8438 | catch_child_signal (); | 8445 | catch_child_signal (); |
| 8439 | g_source_unref (source); | 8446 | g_source_unref (source); |
| 8440 | 8447 | ||
| 8441 | eassert (lib_child_handler != dummy_handler); | 8448 | if (lib_child_handler != dummy_handler) |
| 8442 | signal_handler_t lib_child_handler_glib = lib_child_handler; | 8449 | { |
| 8443 | catch_child_signal (); | 8450 | /* The hacky workaround is needed on this platform. */ |
| 8444 | eassert (lib_child_handler == dummy_handler); | 8451 | signal_handler_t lib_child_handler_glib = lib_child_handler; |
| 8445 | lib_child_handler = lib_child_handler_glib; | 8452 | catch_child_signal (); |
| 8453 | eassert (lib_child_handler == dummy_handler); | ||
| 8454 | lib_child_handler = lib_child_handler_glib; | ||
| 8455 | } | ||
| 8446 | #else | 8456 | #else |
| 8447 | catch_child_signal (); | 8457 | catch_child_signal (); |
| 8448 | #endif | 8458 | #endif |