X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Ffileio.c;h=603a1c7b38755ad35fec95f48915367341776361;hb=1e5413f74faa378172d556e5dec35ab55de16bbf;hp=77fd05955a54b4286f4a845025d462d4fbca716f;hpb=335c46b59888d431e5a57cddcf7ceecd09ec8e4a;p=elogind.git diff --git a/src/shared/fileio.c b/src/shared/fileio.c index 77fd05955..603a1c7b3 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -24,6 +24,7 @@ #include "util.h" #include "strv.h" #include "utf8.h" +#include "ctype.h" int write_string_to_file(FILE *f, const char *line) { errno = 0; @@ -648,3 +649,50 @@ int executable_is_script(const char *path, char **interpreter) { *interpreter = ans; return 1; } + +/** + * 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. + */ +int get_status_field(const char *filename, const char *pattern, char **field) { + _cleanup_free_ char *status = NULL; + char *t; + size_t len; + int r; + + assert(filename); + assert(field); + + r = read_full_file(filename, &status, NULL); + if (r < 0) + return r; + + t = strstr(status, pattern); + if (!t) + return -ENOENT; + + t += strlen(pattern); + if (*t) { + t += strspn(t, " \t"); + + /* Also skip zeros, because when this is used for + * capabilities, we don't want the zeros. This way the + * same capability set always maps to the same string, + * irrespective of the total capability set size. For + * other numbers it shouldn't matter. */ + t += strspn(t, "0"); + /* Back off one char if there's nothing but whitespace + and zeros */ + if (!*t || isspace(*t)) + t --; + } + + len = strcspn(t, WHITESPACE); + + *field = strndup(t, len); + if (!*field) + return -ENOMEM; + + return 0; +}