chiark / gitweb /
sd-resolve: rename get_next() and get_n_queries() + cleanup
[elogind.git] / src / shared / util.c
index 50dac708040973e95afc0ef8c1cb6f3be1ce9405..5551714a366de924978cc72762491d7eedbafdc0 100644 (file)
@@ -359,8 +359,23 @@ int safe_atod(const char *s, double *ret_d) {
         return 0;
 }
 
+static size_t strcspn_escaped(const char *s, const char *reject) {
+        bool escaped = false;
+        size_t n;
+
+        for (n=0; s[n]; n++) {
+                if (escaped)
+                        escaped = false;
+                else if (s[n] == '\\')
+                        escaped = true;
+                else if (strchr(reject, s[n]))
+                        return n;
+        }
+        return n;
+}
+
 /* Split a string into words. */
-char *split(const char *c, size_t *l, const char *separator, char **state) {
+char *split(const char *c, size_t *l, const char *separator, bool quoted, char **state) {
         char *current;
 
         current = *state ? *state : (char*) c;
@@ -369,70 +384,19 @@ char *split(const char *c, size_t *l, const char *separator, char **state) {
                 return NULL;
 
         current += strspn(current, separator);
-        *l = strcspn(current, separator);
-        *state = current+*l;
-
-        return (char*) current;
-}
-
-/* Split a string into words, but consider strings enclosed in '' and
- * "" as words even if they include spaces. */
-char *split_quoted(const char *c, size_t *l, char **state) {
-        const char *current, *e;
-        bool escaped = false;
-
-        assert(c);
-        assert(l);
-        assert(state);
-
-        current = *state ? *state : c;
-
-        current += strspn(current, WHITESPACE);
-
-        if (*current == 0)
+        if (!*current)
                 return NULL;
 
-        else if (*current == '\'') {
-                current ++;
-
-                for (e = current; *e; e++) {
-                        if (escaped)
-                                escaped = false;
-                        else if (*e == '\\')
-                                escaped = true;
-                        else if (*e == '\'')
-                                break;
-                }
-
-                *l = e-current;
-                *state = (char*) (*e == 0 ? e : e+1);
-
-        } else if (*current == '\"') {
-                current ++;
-
-                for (e = current; *e; e++) {
-                        if (escaped)
-                                escaped = false;
-                        else if (*e == '\\')
-                                escaped = true;
-                        else if (*e == '\"')
-                                break;
-                }
-
-                *l = e-current;
-                *state = (char*) (*e == 0 ? e : e+1);
-
+        if (quoted && strchr("\'\"", *current)) {
+                char quotechar = *(current++);
+                *l = strcspn_escaped(current, (char[]){quotechar, '\0'});
+                *state = current+*l+1;
+        } else if (quoted) {
+                *l = strcspn_escaped(current, separator);
+                *state = current+*l;
         } else {
-                for (e = current; *e; e++) {
-                        if (escaped)
-                                escaped = false;
-                        else if (*e == '\\')
-                                escaped = true;
-                        else if (strchr(WHITESPACE, *e))
-                                break;
-                }
-                *l = e-current;
-                *state = (char*) e;
+                *l = strcspn(current, separator);
+                *state = current+*l;
         }
 
         return (char*) current;
@@ -440,8 +404,7 @@ char *split_quoted(const char *c, size_t *l, char **state) {
 
 int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
         int r;
-        _cleanup_fclose_ FILE *f = NULL;
-        char line[LINE_MAX];
+        _cleanup_free_ char *line = NULL;
         long unsigned ppid;
         const char *p;
 
@@ -454,14 +417,9 @@ int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
         }
 
         p = procfs_file_alloca(pid, "stat");
-        f = fopen(p, "re");
-        if (!f)
-                return -errno;
-
-        if (!fgets(line, sizeof(line), f)) {
-                r = feof(f) ? -EIO : -errno;
+        r = read_one_line_file(p, &line);
+        if (r < 0)
                 return r;
-        }
 
         /* Let's skip the pid and comm fields. The latter is enclosed
          * in () but does not escape any () in its value, so let's
@@ -488,25 +446,17 @@ int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
 }
 
 int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
-        _cleanup_fclose_ FILE *f = NULL;
-        char line[LINE_MAX];
+        int r;
+        _cleanup_free_ char *line = NULL;
         const char *p;
 
         assert(pid >= 0);
         assert(st);
 
         p = procfs_file_alloca(pid, "stat");
-
-        f = fopen(p, "re");
-        if (!f)
-                return errno == ENOENT ? -ESRCH : -errno;
-
-        if (!fgets(line, sizeof(line), f)) {
-                if (ferror(f))
-                        return -errno;
-
-                return -EIO;
-        }
+        r = read_one_line_file(p, &line);
+        if (r < 0)
+                return r;
 
         /* Let's skip the pid and comm fields. The latter is enclosed
          * in () but does not escape any () in its value, so let's
@@ -2527,21 +2477,17 @@ int getttyname_harder(int fd, char **r) {
 }
 
 int get_ctty_devnr(pid_t pid, dev_t *d) {
-        _cleanup_fclose_ FILE *f = NULL;
-        char line[LINE_MAX], *p;
+        int r;
+        _cleanup_free_ char *line = NULL;
+        const char *p;
         unsigned long ttynr;
-        const char *fn;
 
         assert(pid >= 0);
 
-        fn = procfs_file_alloca(pid, "stat");
-
-        f = fopen(fn, "re");
-        if (!f)
-                return -errno;
-
-        if (!fgets(line, sizeof(line), f))
-                return feof(f) ? -EIO : -errno;
+        p = procfs_file_alloca(pid, "stat");
+        r = read_one_line_file(p, &line);
+        if (r < 0)
+                return r;
 
         p = strrchr(line, ')');
         if (!p)