aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Henriksen <LarsHenriksen@get2net.dk>2020-07-14 09:07:00 +0200
committerLukas Fleischer <lfleischer@calcurse.org>2020-07-26 10:31:28 -0400
commitf743eab5ac96314044fe748f0f1875a1ee78d3a9 (patch)
treeade004dff23390840584fb768fca536fcc6f056c
parent41e1a89aa73877d3477595b7425ac7c2ab65a573 (diff)
downloadcalcurse-f743eab5ac96314044fe748f0f1875a1ee78d3a9.tar.gz
calcurse-f743eab5ac96314044fe748f0f1875a1ee78d3a9.zip
Remove SIGCHLD signal handler
The purpose is to make child_wait() reliable. The handler is meant for the notify main thread, but signal handlers are shared by all threads. In the calcurse main thread and the periodic save thread (hooks) the handler and child_wait() will compete (if the signal handler kicks in first, the waitpid() call in child_wait() will fail with errno ECHILD). All child processes in the main thread, the notify thread, the periodic save thread and the notify demon are explicitly waited for. Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
-rw-r--r--src/dmon.c8
-rw-r--r--src/notify.c4
-rw-r--r--src/sigs.c18
-rw-r--r--src/utils.c6
4 files changed, 17 insertions, 19 deletions
diff --git a/src/dmon.c b/src/dmon.c
index f9bbfd2..e61caf5 100644
--- a/src/dmon.c
+++ b/src/dmon.c
@@ -34,7 +34,7 @@
*
*/
-#include <sys/types.h>
+#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <paths.h>
@@ -143,8 +143,7 @@ static unsigned daemonize(int status)
|| !sigs_set_hdlr(SIGTERM, dmon_sigs_hdlr)
|| !sigs_set_hdlr(SIGALRM, dmon_sigs_hdlr)
|| !sigs_set_hdlr(SIGQUIT, dmon_sigs_hdlr)
- || !sigs_set_hdlr(SIGUSR1, dmon_sigs_hdlr)
- || !sigs_set_hdlr(SIGCHLD, SIG_IGN))
+ || !sigs_set_hdlr(SIGUSR1, dmon_sigs_hdlr))
return 0;
return 1;
@@ -203,6 +202,9 @@ void dmon_start(int parent_exit_status)
DMON_SLEEP_TIME);
psleep(DMON_SLEEP_TIME);
DMON_LOG(_("awakened at %s\n"), nowstr());
+ /* Reap the user-defined notifications. */
+ while (waitpid(0, NULL, WNOHANG) > 0)
+ ;
}
}
diff --git a/src/notify.c b/src/notify.c
index a24beb2..036af0f 100644
--- a/src/notify.c
+++ b/src/notify.c
@@ -34,6 +34,7 @@
*
*/
+#include <sys/wait.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
@@ -358,6 +359,9 @@ static void *notify_main_thread(void *arg)
pthread_mutex_unlock(&notify.mutex);
notify_update_bar();
psleep(thread_sleep);
+ /* Reap the user-defined notifications. */
+ while (waitpid(0, NULL, WNOHANG) > 0)
+ ;
elapse += thread_sleep;
if (elapse >= check_app) {
elapse = 0;
diff --git a/src/sigs.c b/src/sigs.c
index 02457ae..fab4498 100644
--- a/src/sigs.c
+++ b/src/sigs.c
@@ -68,27 +68,18 @@
/*
* General signal handling routine.
- * Catch return values from children (user-defined notification commands).
- * This is needed to avoid zombie processes running on system.
- * Also catch CTRL-C (SIGINT), and SIGWINCH to resize screen automatically.
+ * Catch SIGWINCH to resize screen automatically.
*/
static void generic_hdlr(int sig)
{
switch (sig) {
- case SIGCHLD:
- while (waitpid(WAIT_MYPGRP, NULL, WNOHANG) > 0) ;
- break;
case SIGWINCH:
resize = 1;
clearok(curscr, TRUE);
ungetch(KEY_RESIZE);
break;
case SIGTERM:
- if (unlink(path_cpid) != 0) {
- EXIT(_("Could not remove calcurse lock file: %s\n"),
- strerror(errno));
- }
- exit(EXIT_SUCCESS);
+ exit_calcurse(EXIT_SUCCESS);
break;
case SIGUSR1:
want_reload = 1;
@@ -117,12 +108,11 @@ unsigned sigs_set_hdlr(int sig, void (*handler) (int))
/* Signal handling init. */
void sigs_init()
{
- if (!sigs_set_hdlr(SIGCHLD, generic_hdlr)
- || !sigs_set_hdlr(SIGWINCH, generic_hdlr)
+ if (!sigs_set_hdlr(SIGWINCH, generic_hdlr)
|| !sigs_set_hdlr(SIGTERM, generic_hdlr)
|| !sigs_set_hdlr(SIGUSR1, generic_hdlr)
|| !sigs_set_hdlr(SIGINT, SIG_IGN))
- exit_calcurse(1);
+ exit_calcurse(EXIT_FAILURE);
}
/* Ignore SIGWINCH and SIGTERM signals. */
diff --git a/src/utils.c b/src/utils.c
index 0a98ce0..2d2f615 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -1425,8 +1425,10 @@ int child_wait(int *pfdin, int *pfdout, int pid)
if (pfdout)
close(*pfdout);
- waitpid(pid, &stat, 0);
- return stat;
+ if (waitpid(pid, &stat, 0) == pid)
+ return stat;
+ else
+ return -1;
}
/* Display "Press any key to continue..." and wait for a key press. */