]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
tools subcmd: Add non-waitpid check_if_command_finished()
authorIan Rogers <irogers@google.com>
Fri, 25 Oct 2024 19:21:00 +0000 (12:21 -0700)
committerNamhyung Kim <namhyung@kernel.org>
Mon, 28 Oct 2024 16:32:57 +0000 (09:32 -0700)
Using waitpid can cause stdout/stderr of the child process to be
lost. Use Linux's /prod/<pid>/status file to determine if the process
has reached the zombie state. Use the 'status' file rather than 'stat'
to avoid issues around skipping the process name.

Tested-by: James Clark <james.clark@linaro.org>
Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Colin Ian King <colin.i.king@gmail.com>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Weilin Wang <weilin.wang@intel.com>
Cc: Ilya Leoshkevich <iii@linux.ibm.com>
Cc: Thomas Richter <tmricht@linux.ibm.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: Athira Jajeev <atrajeev@linux.vnet.ibm.com>
Cc: Michael Petlan <mpetlan@redhat.com>
Cc: Veronika Molnarova <vmolnaro@redhat.com>
Link: https://lore.kernel.org/r/20241025192109.132482-2-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
tools/lib/subcmd/run-command.c

index 4e3a557a2f3741229450b5249f9be623333352ca..0a764c25c384f0b2a7d074ef146477c199a845d4 100644 (file)
@@ -2,6 +2,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <ctype.h>
 #include <fcntl.h>
 #include <string.h>
 #include <linux/string.h>
@@ -217,8 +218,40 @@ static int wait_or_whine(struct child_process *cmd, bool block)
 
 int check_if_command_finished(struct child_process *cmd)
 {
+#ifdef __linux__
+       char filename[FILENAME_MAX + 12];
+       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/%d/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)