chiark / gitweb /
Merge pull request #5 from elogind/dev_v227
[elogind.git] / src / basic / fileio.c
index 718ed3642dca88c5dfe18fe32566940671a30d47..a3f8d42f5edb9e9d32dacbbb59cdf76b85ad5099 100644 (file)
 #include "fileio.h"
 
 int write_string_stream(FILE *f, const char *line, bool enforce_newline) {
+
         assert(f);
         assert(line);
 
-        errno = 0;
-
         fputs(line, f);
         if (enforce_newline && !endswith(line, "\n"))
                 fputc('\n', f);
 
-        fflush(f);
-
-        if (ferror(f))
-                return errno ? -errno : -EIO;
-
-        return 0;
+        return fflush_and_check(f);
 }
 
 static int write_string_file_atomic(const char *fn, const char *line, bool enforce_newline) {
@@ -134,6 +128,8 @@ int read_one_line_file(const char *fn, char **line) {
         return 0;
 }
 
+/// UNNEEDED by elogind
+#if 0
 int verify_one_line_file(const char *fn, const char *line) {
         _cleanup_free_ char *value = NULL;
         int r;
@@ -144,6 +140,7 @@ int verify_one_line_file(const char *fn, const char *line) {
 
         return streq(value, line);
 }
+#endif // 0
 
 int read_full_stream(FILE *f, char **contents, size_t *size) {
         size_t n, l;
@@ -787,15 +784,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;
+        char *t, *f;
         size_t len;
         int r;
 
+        assert(terminator);
         assert(filename);
         assert(pattern);
         assert(field);
@@ -804,11 +805,31 @@ int get_status_field(const char *filename, const char *pattern, char **field) {
         if (r < 0)
                 return r;
 
-        t = strstr(status, pattern);
+        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++;
+
         if (*t) {
                 t += strspn(t, " \t");
 
@@ -824,11 +845,12 @@ int get_status_field(const char *filename, const char *pattern, char **field) {
                         t --;
         }
 
-        len = strcspn(t, WHITESPACE);
+        len = strcspn(t, terminator);
 
-        *field = strndup(t, len);
-        if (!*field)
+        f = strndup(t, len);
+        if (!f)
                 return -ENOMEM;
 
+        *field = f;
         return 0;
 }