diff options
author | Guillem Jover <guillem@debian.org> | 2014-03-26 17:21:36 +0100 |
---|---|---|
committer | Guillem Jover <guillem@debian.org> | 2014-04-21 16:54:28 +0200 |
commit | 51e4a23b56464da01481969d141aa5a41ad3b2ef (patch) | |
tree | a37616b1d9e561bb522a75e736350f508548aa7f /utils | |
parent | d3611d0d83151f0405506419111bc9cc4066af68 (diff) | |
download | dpkg-51e4a23b56464da01481969d141aa5a41ad3b2ef.tar.gz |
s-s-d: Refactor Linux comm retrieval and switch to use /proc/PID/status
This trades parsing ambiguities due to process names with ‘)’ for ones
with embedded ‘\n’. But it should be more robust and future proof in
general, and allows to retrieve any field by name, which makes the code
more clear and reusable.
Diffstat (limited to 'utils')
-rw-r--r-- | utils/start-stop-daemon.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/utils/start-stop-daemon.c b/utils/start-stop-daemon.c index 77a66e6ad..357293900 100644 --- a/utils/start-stop-daemon.c +++ b/utils/start-stop-daemon.c @@ -1068,6 +1068,40 @@ setup_options(void) } } +#if defined(OSLinux) +static const char * +proc_status_field(pid_t pid, const char *field) +{ + static char *line = NULL; + static size_t line_size = 0; + + FILE *fp; + char filename[32]; + char *value = NULL; + ssize_t line_len; + size_t field_len = strlen(field); + + sprintf(filename, "/proc/%d/status", pid); + fp = fopen(filename, "r"); + if (!fp) + return NULL; + while ((line_len = getline(&line, &line_size, fp)) >= 0) { + if (strncasecmp(line, field, field_len) == 0) { + line[line_len - 1] = '\0'; + + value = line + field_len; + while (isspace(*value)) + value++; + + break; + } + } + fclose(fp); + + return value; +} +#endif + #if defined(OSHurd) static void init_procset(void) @@ -1270,25 +1304,13 @@ pid_is_user(pid_t pid, uid_t uid) static bool pid_is_cmd(pid_t pid, const char *name) { - char buf[32]; - FILE *f; - int c; + const char *comm; - sprintf(buf, "/proc/%d/stat", pid); - f = fopen(buf, "r"); - if (!f) - return false; - while ((c = getc(f)) != EOF && c != '(') - ; - if (c != '(') { - fclose(f); + comm = proc_status_field(pid, "Name:"); + if (comm == NULL) return false; - } - /* This hopefully handles command names containing ‘)’. */ - while ((c = getc(f)) != EOF && c == *name) - name++; - fclose(f); - return (c == ')' && *name == '\0'); + + return strcmp(comm, name) == 0; } #elif defined(OSHurd) static bool |