diff options
-rw-r--r-- | src/basic/parse-util.c | 59 | ||||
-rw-r--r-- | src/basic/parse-util.h | 2 |
2 files changed, 61 insertions, 0 deletions
diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c index 4ae07b0a8e..9108820ca8 100644 --- a/src/basic/parse-util.c +++ b/src/basic/parse-util.c @@ -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; diff --git a/src/basic/parse-util.h b/src/basic/parse-util.h index dc09782ca8..5f1c850855 100644 --- a/src/basic/parse-util.h +++ b/src/basic/parse-util.h @@ -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); |