diff options
author | Aaro Koskinen <aaro.koskinen@nokia.com> | 2015-09-30 15:57:55 +0300 |
---|---|---|
committer | Aaro Koskinen <aaro.koskinen@nokia.com> | 2015-09-30 15:57:55 +0300 |
commit | c4cd1d4d93e4a45a088edb6517555aa7e06e5f86 (patch) | |
tree | 4529a045943ee56bf1e96a6d2820318f36e5473d /src/basic | |
parent | 5e6ad75f259942c33bbb0b9bfc1e8dd5cc0d96e7 (diff) |
fileio: make get_status_field() more generic
All users of get_status_field() expect the field pattern to occur in
the beginning of a line, and the delimiter is ':'.
Hardcode this into the function, and also skip any whitespace before ':'
to support fields in files like /proc/cpuinfo. Add support for returning
the full field value (currently stops on first whitespace).
Rename the function so it's easier to ensure all callers switch to new
semantics.
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) |