parse-util: add parse_errno() and parse_syscall_and_errno()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 11 Nov 2017 12:29:17 +0000 (21:29 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 11 Nov 2017 12:29:17 +0000 (21:29 +0900)
src/basic/parse-util.c
src/basic/parse-util.h

index 4ae07b0..9108820 100644 (file)
@@ -25,6 +25,7 @@
 #include <string.h>
 
 #include "alloc-util.h"
+#include "errno-list.h"
 #include "extract-word.h"
 #include "macro.h"
 #include "parse-util.h"
@@ -268,6 +269,64 @@ int parse_range(const char *t, unsigned *lower, unsigned *upper) {
         return 0;
 }
 
+int parse_errno(const char *t) {
+        int r, e;
+
+        assert(t);
+
+        r = errno_from_name(t);
+        if (r > 0)
+                return r;
+
+        r = safe_atoi(t, &e);
+        if (r < 0)
+                return r;
+
+        if (e < 0 || e > ERRNO_MAX)
+                return -ERANGE;
+
+        return e;
+}
+
+int parse_syscall_and_errno(const char *in, char **name, int *error) {
+        _cleanup_free_ char *n = NULL;
+        char *p;
+        int e = -1;
+
+        assert(in);
+        assert(name);
+        assert(error);
+
+        /*
+         * This parse "syscall:errno" like "uname:EILSEQ", "@sync:255".
+         * If errno is omitted, then error is set to -1.
+         * Empty syscall name is not allowed.
+         * Here, we do not check that the syscall name is valid or not.
+         */
+
+        p = strchr(in, ':');
+        if (p) {
+                e = parse_errno(p + 1);
+                if (e < 0)
+                        return e;
+
+                n = strndup(in, p - in);
+        } else
+                n = strdup(in);
+
+        if (!n)
+                return -ENOMEM;
+
+        if (isempty(n))
+                return -EINVAL;
+
+        *error = e;
+        *name = n;
+        n = NULL;
+
+        return 0;
+}
+
 char *format_bytes(char *buf, size_t l, uint64_t t) {
         unsigned i;
 
index dc09782..5f1c850 100644 (file)
@@ -37,6 +37,8 @@ int parse_ifindex(const char *s, int *ret);
 
 int parse_size(const char *t, uint64_t base, uint64_t *size);
 int parse_range(const char *t, unsigned *lower, unsigned *upper);
+int parse_errno(const char *t);
+int parse_syscall_and_errno(const char *in, char **name, int *error);
 
 #define FORMAT_BYTES_MAX 8
 char *format_bytes(char *buf, size_t l, uint64_t t);