diff options
Diffstat (limited to 'tools/lib/subcmd/run-command.c')
| -rw-r--r-- | tools/lib/subcmd/run-command.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/tools/lib/subcmd/run-command.c b/tools/lib/subcmd/run-command.c index 4e3a557a2f37..b7510f83209a 100644 --- a/tools/lib/subcmd/run-command.c +++ b/tools/lib/subcmd/run-command.c @@ -2,8 +2,10 @@ #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> +#include <ctype.h> #include <fcntl.h> #include <string.h> +#include <linux/compiler.h> #include <linux/string.h> #include <errno.h> #include <sys/wait.h> @@ -215,10 +217,52 @@ static int wait_or_whine(struct child_process *cmd, bool block) return result; } +/* + * Conservative estimate of number of characaters needed to hold an a decoded + * integer, assume each 3 bits needs a character byte and plus a possible sign + * character. + */ +#ifndef is_signed_type +#define is_signed_type(type) (((type)(-1)) < (type)1) +#endif +#define MAX_STRLEN_TYPE(type) (sizeof(type) * 8 / 3 + (is_signed_type(type) ? 1 : 0)) + int check_if_command_finished(struct child_process *cmd) { +#ifdef __linux__ + char filename[6 + MAX_STRLEN_TYPE(typeof(cmd->pid)) + 7 + 1]; + char status_line[256]; + FILE *status_file; + + /* + * Check by reading /proc/<pid>/status as calling waitpid causes + * stdout/stderr to be closed and data lost. + */ + sprintf(filename, "/proc/%u/status", cmd->pid); + status_file = fopen(filename, "r"); + if (status_file == NULL) { + /* Open failed assume finish_command was called. */ + return true; + } + while (fgets(status_line, sizeof(status_line), status_file) != NULL) { + char *p; + + if (strncmp(status_line, "State:", 6)) + continue; + + fclose(status_file); + p = status_line + 6; + while (isspace(*p)) + p++; + return *p == 'Z' ? 1 : 0; + } + /* Read failed assume finish_command was called. */ + fclose(status_file); + return 1; +#else wait_or_whine(cmd, /*block=*/false); return cmd->finished; +#endif } int finish_command(struct child_process *cmd) |
