diff options
Diffstat (limited to 'src/basic/process-util.c')
-rw-r--r-- | src/basic/process-util.c | 91 |
1 files changed, 39 insertions, 52 deletions
diff --git a/src/basic/process-util.c b/src/basic/process-util.c index 448503409b..78ce43b944 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -102,7 +102,8 @@ int get_process_comm(pid_t pid, char **ret) { int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) { _cleanup_fclose_ FILE *f = NULL; bool space = false; - char *k, *ans = NULL; + char *k; + _cleanup_free_ char *ans = NULL; const char *p; int c; @@ -129,6 +130,13 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + if (max_length == 0) { + /* This is supposed to be a safety guard against runaway command lines. */ + long l = sysconf(_SC_ARG_MAX); + assert(l > 0); + max_length = l; + } + if (max_length == 1) { /* If there's only room for one byte, return the empty string */ @@ -136,35 +144,9 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * if (!ans) return -ENOMEM; - *line = ans; + *line = TAKE_PTR(ans); return 0; - } else if (max_length == 0) { - size_t len = 0, allocated = 0; - - while ((c = getc(f)) != EOF) { - - if (!GREEDY_REALLOC(ans, allocated, len+3)) { - free(ans); - return -ENOMEM; - } - - if (isprint(c)) { - if (space) { - ans[len++] = ' '; - space = false; - } - - ans[len++] = c; - } else if (len > 0) - space = true; - } - - if (len > 0) - ans[len] = '\0'; - else - ans = mfree(ans); - } else { bool dotdotdot = false; size_t left; @@ -227,7 +209,7 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * _cleanup_free_ char *t = NULL; int h; - free(ans); + ans = mfree(ans); if (!comm_fallback) return -ENOENT; @@ -236,37 +218,42 @@ int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char * if (h < 0) return h; - if (max_length == 0) - ans = strjoin("[", t, "]"); - else { - size_t l; - - l = strlen(t); + size_t l = strlen(t); - if (l + 3 <= max_length) - ans = strjoin("[", t, "]"); - else if (max_length <= 6) { + if (l + 3 <= max_length) { + ans = strjoin("[", t, "]"); + if (!ans) + return -ENOMEM; - ans = new(char, max_length); - if (!ans) - return -ENOMEM; + } else if (max_length <= 6) { + ans = new(char, max_length); + if (!ans) + return -ENOMEM; - memcpy(ans, "[...]", max_length-1); - ans[max_length-1] = 0; - } else { - t[max_length - 6] = 0; + memcpy(ans, "[...]", max_length-1); + ans[max_length-1] = 0; + } else { + t[max_length - 6] = 0; - /* Chop off final spaces */ - delete_trailing_chars(t, WHITESPACE); + /* Chop off final spaces */ + delete_trailing_chars(t, WHITESPACE); - ans = strjoin("[", t, "...]"); - } + ans = strjoin("[", t, "...]"); + if (!ans) + return -ENOMEM; } - if (!ans) - return -ENOMEM; + + *line = TAKE_PTR(ans); + return 0; } - *line = ans; + k = realloc(ans, strlen(ans) + 1); + if (!k) + return -ENOMEM; + + ans = NULL; + *line = k; + return 0; } |