summaryrefslogtreecommitdiffstats
path: root/cmds/dumpstate/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/dumpstate/utils.c')
-rw-r--r--cmds/dumpstate/utils.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 8f132d5..2ef541d 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -133,12 +133,23 @@ void do_dmesg() {
}
void do_showmap(int pid, const char *name) {
+ static bool ran = false, skip = false;
char title[255];
char arg[255];
sprintf(title, "SHOW MAP %d (%s)", pid, name);
sprintf(arg, "%d", pid);
- run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
+
+ if (skip) {
+ /* Skip due to non-zero exit status on first run. */
+ printf("------ %s: Skipped. ------\n", title);
+ } else {
+ int status = run_command(title, 10, SU_PATH, "root", "showmap", arg, NULL);
+ if (!ran) {
+ ran = true;
+ skip = !WIFEXITED(status) || WEXITSTATUS(status) != 0;
+ }
+ }
}
/* prints the contents of a file */
@@ -197,14 +208,29 @@ int run_command(const char *title, int timeout_seconds, const char *command, ...
/* handle child case */
if (pid == 0) {
const char *args[1024] = {command};
- size_t arg;
+ size_t arg = 1;
+ char sucmd[255];
+ bool su = false;
+
+ if (strcmp(command, SU_PATH) == 0) {
+ /* Need to transform calls to su from:
+ * su LOGIN COMMAND ...
+ * to:
+ * su -c 'COMMAND "$@"' -- LOGIN COMMAND ... */
+ args[arg++] = "-c";
+ args[arg++] = sucmd;
+ args[arg++] = "--";
+ sucmd[0] = '\0';
+ su = true;
+ }
va_list ap;
va_start(ap, command);
if (title) printf("------ %s (%s", title, command);
- for (arg = 1; arg < sizeof(args) / sizeof(args[0]); ++arg) {
+ for (; arg < sizeof(args) / sizeof(args[0]); ++arg) {
args[arg] = va_arg(ap, const char *);
if (args[arg] == NULL) break;
+ if (su && arg == 5) snprintf(sucmd, sizeof(sucmd), "%s \"$@\"", args[arg]);
if (title) printf(" %s", args[arg]);
}
if (title) printf(") ------\n");