forked from osmocom/wireshark
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>
This commit is contained in:
parent
f0855e03d1
commit
dc2195711c
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue