aboutsummaryrefslogtreecommitdiffstats
path: root/capchild/capture_sync.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2015-11-18 11:39:57 -0800
committerGuy Harris <guy@alum.mit.edu>2015-11-18 19:40:36 +0000
commitbdea0d450476a077f64acbfe26e62251fcbb339d (patch)
treeaddb64eb5827492ddb4a4cbca4a65258184f15e6 /capchild/capture_sync.c
parent5c49facc4f2a9a054258c5921bc68293d6eab3e4 (diff)
Check for ECHILD, not for "not ECHILD".
That makes the logic a bit clearer (and puts the "unexpected other error" case at the end, where it should be). Put all the errno checks inside an else clause, making it clearer that it runs only if waitpid() returned -1. Add comments, including comments explaining why just driving on after getting EINTR should be OK. Change-Id: Iaa1b151393fcec8b4f5bd560ef913a224400932b Reviewed-on: https://code.wireshark.org/review/11951 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'capchild/capture_sync.c')
-rw-r--r--capchild/capture_sync.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/capchild/capture_sync.c b/capchild/capture_sync.c
index b1e1e38f2f..905d514c95 100644
--- a/capchild/capture_sync.c
+++ b/capchild/capture_sync.c
@@ -1988,6 +1988,7 @@ sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp)
#else
while (--retry_waitpid >= 0) {
if (waitpid(fork_child, &fork_child_status, 0) != -1) {
+ /* waitpid() succeeded */
if (WIFEXITED(fork_child_status)) {
/*
* The child exited; return its exit status. Do not treat this as
@@ -2012,15 +2013,40 @@ sync_pipe_wait_for_child(ws_process_id fork_child, gchar **msgp)
fork_child_status);
ret = -1;
}
- } else if (errno == EINTR) {
- g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, "sync_pipe_wait_for_child: waitpid returned EINTR. retrying.");
- continue;
- } else if (errno != ECHILD) {
- *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
- ret = -1;
} else {
- /* errno == ECHILD ; echld might have already reaped the child */
- ret = fetch_dumpcap_pid ? 0 : -1;
+ /* waitpid() failed */
+ if (errno == EINTR) {
+ /*
+ * Signal interrupted waitpid().
+ *
+ * If it's SIGALRM, we just want to keep waiting, in case
+ * there's some timer using it (e.g., in a GUI toolkit).
+ *
+ * If you ^C TShark (or Wireshark), that should deliver
+ * SIGINT to dumpcap as well. dumpcap catches SIGINT,
+ * and should clean up and exit, so we should eventually
+ * see that and clean up and terminate.
+ *
+ * If we're sent a SIGTERM, we should (and do) catch it,
+ * and TShark, at least, calls sync_pipe_stop(). which
+ * kills dumpcap, so we should eventually see that and
+ * clean up and terminate.
+ */
+ g_log(LOG_DOMAIN_CAPTURE, G_LOG_LEVEL_WARNING, "sync_pipe_wait_for_child: waitpid returned EINTR. retrying.");
+ continue;
+ } else if (errno == ECHILD) {
+ /*
+ * The process identified by fork_child either doesn't
+ * exist any more or isn't our child process (anymore?).
+ *
+ * echld might have already reaped the child.
+ */
+ ret = fetch_dumpcap_pid ? 0 : -1;
+ } else {
+ /* Unknown error. */
+ *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
+ ret = -1;
+ }
}
break;
}