aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVik <vkp129+ubuntu@gmail.com>2015-03-12 20:32:48 -0700
committerAnders Broman <a.broman58@gmail.com>2015-03-16 06:04:58 +0000
commitdc2195711c2eec6e459ecdf17a01139895ace479 (patch)
treee8620bfeb238792f290ddb28331440c9a0b163c6
parentf0855e03d1018a83c98402fe22dfe21705dfb0d9 (diff)
Fix for waitpid return EINTR sometimes on launch.
The return of EINTR is not exactly a failure of child process but may be because of any number of reasons. Adding logic to retry to get status of child process. Bug: 10889 Change-Id: Ic2de7248cb7bd9c801b917c841ce911fb7c17dcc Reviewed-on: https://code.wireshark.org/review/7669 Petri-Dish: Graham Bloice <graham.bloice@trihedral.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r--capchild/capture_sync.c67
1 files changed, 38 insertions, 29 deletions
diff --git a/capchild/capture_sync.c b/capchild/capture_sync.c
index 55be896395..1624230772 100644
--- a/capchild/capture_sync.c
+++ b/capchild/capture_sync.c
@@ -1865,7 +1865,10 @@ static int
sync_pipe_wait_for_child(int fork_child, gchar **msgp)
{
int fork_child_status;
- int ret;
+#ifndef _WIN32
+ int retry_waitpid = 3;
+#endif
+ int ret = -1;
GTimeVal start_time;
GTimeVal end_time;
float elapsed;
@@ -1898,37 +1901,43 @@ sync_pipe_wait_for_child(int fork_child, gchar **msgp)
}
}
#else
- if (waitpid(fork_child, &fork_child_status, 0) != -1) {
- if (WIFEXITED(fork_child_status)) {
- /*
- * The child exited; return its exit status. Do not treat this as
- * an error.
- */
- ret = WEXITSTATUS(fork_child_status);
- } else if (WIFSTOPPED(fork_child_status)) {
- /* It stopped, rather than exiting. "Should not happen." */
- *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
- sync_pipe_signame(WSTOPSIG(fork_child_status)));
- ret = -1;
- } else if (WIFSIGNALED(fork_child_status)) {
- /* It died with a signal. */
- *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
- sync_pipe_signame(WTERMSIG(fork_child_status)),
- WCOREDUMP(fork_child_status) ? " - core dumped" : "");
+ while (--retry_waitpid >= 0) {
+ if (waitpid(fork_child, &fork_child_status, 0) != -1) {
+ if (WIFEXITED(fork_child_status)) {
+ /*
+ * The child exited; return its exit status. Do not treat this as
+ * an error.
+ */
+ ret = WEXITSTATUS(fork_child_status);
+ } else if (WIFSTOPPED(fork_child_status)) {
+ /* It stopped, rather than exiting. "Should not happen." */
+ *msgp = g_strdup_printf("Child dumpcap process stopped: %s",
+ sync_pipe_signame(WSTOPSIG(fork_child_status)));
+ ret = -1;
+ } else if (WIFSIGNALED(fork_child_status)) {
+ /* It died with a signal. */
+ *msgp = g_strdup_printf("Child dumpcap process died: %s%s",
+ sync_pipe_signame(WTERMSIG(fork_child_status)),
+ WCOREDUMP(fork_child_status) ? " - core dumped" : "");
+ ret = -1;
+ } else {
+ /* What? It had to either have exited, or stopped, or died with
+ a signal; what happened here? */
+ *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
+ fork_child_status);
+ ret = -1;
+ }
+ } else if (errno != ECHILD) {
+ *msgp = g_strdup_printf("Error from waitpid(): %s", g_strerror(errno));
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 {
- /* What? It had to either have exited, or stopped, or died with
- a signal; what happened here? */
- *msgp = g_strdup_printf("Bad status from waitpid(): %#o",
- fork_child_status);
- ret = -1;
+ /* errno == ECHILD ; echld might have already reaped the child */
+ ret = fetch_dumpcap_pid ? 0 : -1;
}
- } 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;
+ break;
}
#endif