summaryrefslogtreecommitdiff
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:47 +0000
commit1f3e0c03c548ef84b4ce36e224102dae6b914ad5 (patch)
treedff83f9335440b499511cb80344c28ff60eac2b8
parentc3ac3d0217b3f81387cb520c21da27ab46b53041 (diff)
downloadwireshark-1f3e0c03c548ef84b4ce36e224102dae6b914ad5.tar.gz
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> (cherry picked from commit bdea0d450476a077f64acbfe26e62251fcbb339d) Reviewed-on: https://code.wireshark.org/review/11952
-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 417d5c4807..970688e842 100644
--- a/capchild/capture_sync.c
+++ b/capchild/capture_sync.c
@@ -1996,6 +1996,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
@@ -2020,15 +2021,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;
}