summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorDaniel Mack <github@zonque.org>2015-09-30 16:35:49 +0200
committerDaniel Mack <github@zonque.org>2015-09-30 16:35:49 +0200
commita19c7a4a4b773e25671a5fa874e7c421685d1bde (patch)
tree3b7e20eb79359b4f3579870beb279df35ae207cd /src/basic
parent6e8337580862037d0639961cb51ef82270c1a30f (diff)
parentf2d28e80bc6260c90396e9fc798d559775dbde23 (diff)
Merge pull request #1415 from aakoskin/bootchart-v2
[v2] bootchart: don't fail if "model name" is missing from cpuinfo
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/fileio.c40
-rw-r--r--src/basic/fileio.h2
-rw-r--r--src/basic/process-util.c2
-rw-r--r--src/basic/virt.c2
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)