summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorGuillem Jover <guillem@debian.org>2014-03-26 17:21:36 +0100
committerGuillem Jover <guillem@debian.org>2014-04-21 16:54:28 +0200
commit51e4a23b56464da01481969d141aa5a41ad3b2ef (patch)
treea37616b1d9e561bb522a75e736350f508548aa7f /utils
parentd3611d0d83151f0405506419111bc9cc4066af68 (diff)
downloaddpkg-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.c56
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