summaryrefslogtreecommitdiff
path: root/src/dillo.cc
diff options
context:
space:
mode:
authorJorge Arellano Cid <jcid@dillo.org>2013-09-02 11:31:37 -0400
committerJorge Arellano Cid <jcid@dillo.org>2013-09-02 11:31:37 -0400
commit75ad99f0389fb9f7434cfbefa205b1636d4ee1f1 (patch)
treec02ce11a51d4775ade5acd0e60b1d3d0f7444296 /src/dillo.cc
parentdb7c32080a7f22f5ee7898f094ed40ac89e5ce13 (diff)
Avoid Dpid children to become zombies
This handler was long overdue... Patch: Jorge Arellano, J. Gaffney
Diffstat (limited to 'src/dillo.cc')
-rw-r--r--src/dillo.cc62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/dillo.cc b/src/dillo.cc
index 5c1e7364..567d897f 100644
--- a/src/dillo.cc
+++ b/src/dillo.cc
@@ -21,8 +21,11 @@
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include <signal.h>
#include <locale.h>
+#include <errno.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
@@ -95,6 +98,63 @@ static const CLI_options Options[] = {
{NULL, NULL, 0, DILLO_CLI_NONE, NULL}
};
+
+/*
+ * SIGCHLD handling ----------------------------------------------------------
+ */
+
+/*
+ * Avoid our children (Dpid) to become zombies. :-)
+ * Notes:
+ * . We let sigaction block SIGCHLD while in the handler.
+ * . Portability is not simple. e.g.
+ * http://www.faqs.org/faqs/unix-faq/faq/part3/section-13.html
+ * man sigaction, waitpid
+ */
+static void raw_sigchld2(int signum)
+{
+ pid_t pid;
+ int status;
+
+ while (1) {
+ pid = waitpid(-1, &status, WNOHANG);
+ if (pid > 0) {
+ if (WIFEXITED(status)) /* normal exit */
+ printf("[dpid]: terminated normally (%d)\n", WEXITSTATUS(status));
+ else if (WIFSIGNALED(status)) /* terminated by signal */
+ printf("[dpid]: terminated by signal %d\n", WTERMSIG(status));
+ } else if (pid == 0 || errno == ECHILD) {
+ break;
+ } else {
+ if (errno == EINTR)
+ continue;
+ perror("waitpid");
+ break;
+ }
+ }
+ ++signum; /* compiler happiness */
+}
+
+/*
+ * Establish SIGCHLD handler
+ */
+static void est_sigchld(void)
+{
+ struct sigaction sigact;
+ sigset_t set;
+
+ (void) sigemptyset(&set);
+ sigact.sa_handler = raw_sigchld2; /* our custom handler */
+ sigact.sa_mask = set; /* no aditional signal blocks */
+ sigact.sa_flags = SA_NOCLDSTOP; /* ignore stop/resume states */
+ if (sigaction(SIGCHLD, &sigact, NULL) == -1) {
+ perror("sigaction");
+ exit(1);
+ }
+}
+
+//----------------------------------------------------------------------------
+
/*
* Print help text generated from the options structure
*/
@@ -329,6 +389,8 @@ int main(int argc, char **argv)
// Some OSes exit dillo without this (not GNU/Linux).
signal(SIGPIPE, SIG_IGN);
+ // Establish our custom SIGCHLD handler
+ est_sigchld();
/* Handle command line options */
opt_argv = dNew0(char*, numOptions(Options) + 1);