diff options
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/fileio.c | 40 | ||||
-rw-r--r-- | src/basic/fileio.h | 2 | ||||
-rw-r--r-- | src/basic/process-util.c | 2 | ||||
-rw-r--r-- | src/basic/virt.c | 2 |
4 files changed, 35 insertions, 11 deletions
diff --git a/src/basic/fileio.c b/src/basic/fileio.c index 4a9105f421..13a85e1158 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -775,15 +775,19 @@ int executable_is_script(const char *path, char **interpreter) { /** * Retrieve one field from a file like /proc/self/status. pattern - * should start with '\n' and end with a ':'. Whitespace and zeros - * after the ':' will be skipped. field must be freed afterwards. + * should not include whitespace or the delimiter (':'). pattern matches only + * the beginning of a line. Whitespace before ':' is skipped. Whitespace and + * zeros after the ':' will be skipped. field must be freed afterwards. + * terminator specifies the terminating characters of the field value (not + * included in the value). */ -int get_status_field(const char *filename, const char *pattern, char **field) { +int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) { _cleanup_free_ char *status = NULL; char *t, *f; size_t len; int r; + assert(terminator); assert(filename); assert(pattern); assert(field); @@ -792,11 +796,31 @@ int get_status_field(const char *filename, const char *pattern, char **field) { if (r < 0) return r; - t = strstr(status, pattern); - if (!t) - return -ENOENT; + t = status; + + do { + bool pattern_ok; + + do { + t = strstr(t, pattern); + if (!t) + return -ENOENT; + + /* Check that pattern occurs in beginning of line. */ + pattern_ok = (t == status || t[-1] == '\n'); + + t += strlen(pattern); + + } while (!pattern_ok); + + t += strspn(t, " \t"); + if (!*t) + return -ENOENT; + + } while (*t != ':'); + + t++; - t += strlen(pattern); if (*t) { t += strspn(t, " \t"); @@ -812,7 +836,7 @@ int get_status_field(const char *filename, const char *pattern, char **field) { t --; } - len = strcspn(t, WHITESPACE); + len = strcspn(t, terminator); f = strndup(t, len); if (!f) diff --git a/src/basic/fileio.h b/src/basic/fileio.h index 2e8148ff24..4998d4d042 100644 --- a/src/basic/fileio.h +++ b/src/basic/fileio.h @@ -48,4 +48,4 @@ int write_env_file(const char *fname, char **l); int executable_is_script(const char *path, char **interpreter); -int get_status_field(const char *filename, const char *pattern, char **field); +int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field); diff --git a/src/basic/process-util.c b/src/basic/process-util.c index cff2d2a034..d8a94a4572 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -215,7 +215,7 @@ int get_process_capeff(pid_t pid, char **capeff) { p = procfs_file_alloca(pid, "status"); - r = get_status_field(p, "\nCapEff:", capeff); + r = get_proc_field(p, "CapEff", WHITESPACE, capeff); if (r == -ENOENT) return -ESRCH; diff --git a/src/basic/virt.c b/src/basic/virt.c index 1fc6c1baba..70543177b6 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -240,7 +240,7 @@ static int detect_vm_zvm(void) { _cleanup_free_ char *t = NULL; int r; - r = get_status_field("/proc/sysinfo", "VM00 Control Program:", &t); + r = get_proc_field("/proc/sysinfo", "VM00 Control Program", WHITESPACE, &t); if (r == -ENOENT) return VIRTUALIZATION_NONE; if (r < 0) |