diff options
author | Vik <vkp129+ubuntu@gmail.com> | 2015-03-12 20:32:48 -0700 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2015-03-16 06:04:58 +0000 |
commit | dc2195711c2eec6e459ecdf17a01139895ace479 (patch) | |
tree | e8620bfeb238792f290ddb28331440c9a0b163c6 /capchild | |
parent | f0855e03d1018a83c98402fe22dfe21705dfb0d9 (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>
Diffstat (limited to 'capchild')
-rw-r--r-- | capchild/capture_sync.c | 67 |
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 |