summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/socket-util.c26
-rw-r--r--src/shared/socket-util.h2
-rw-r--r--src/shared/util.c10
-rw-r--r--src/shared/util.h48
4 files changed, 55 insertions, 31 deletions
diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c
index 4908403d9f..8bc3729857 100644
--- a/src/shared/socket-util.c
+++ b/src/shared/socket-util.c
@@ -194,7 +194,7 @@ int socket_address_parse(SocketAddress *a, const char *s) {
int socket_address_parse_netlink(SocketAddress *a, const char *s) {
int family;
unsigned group = 0;
- char* sfamily = NULL;
+ _cleanup_free_ char *sfamily = NULL;
assert(a);
assert(s);
@@ -205,13 +205,9 @@ int socket_address_parse_netlink(SocketAddress *a, const char *s) {
if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
return errno ? -errno : -EINVAL;
- if ((family = netlink_family_from_string(sfamily)) < 0)
- if (safe_atoi(sfamily, &family) < 0) {
- free(sfamily);
- return -EINVAL;
- }
-
- free(sfamily);
+ family = netlink_family_from_string(sfamily);
+ if (family < 0)
+ return -EINVAL;
a->sockaddr.nl.nl_family = AF_NETLINK;
a->sockaddr.nl.nl_groups = group;
@@ -367,15 +363,13 @@ int socket_address_print(const SocketAddress *a, char **p) {
}
case AF_NETLINK: {
- const char *sfamily;
-
- if ((sfamily = netlink_family_to_string(a->protocol)))
- r = asprintf(p, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
- else
- r = asprintf(p, "%i %u", a->protocol, a->sockaddr.nl.nl_groups);
+ char *sfamily;
+ r = netlink_family_to_string_alloc(a->protocol, &sfamily);
if (r < 0)
- return -ENOMEM;
+ return r;
+ r = asprintf(p, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
+ free(sfamily);
return 0;
}
@@ -540,7 +534,7 @@ static const char* const netlink_family_table[] = {
[NETLINK_ECRYPTFS] = "ecryptfs"
};
-DEFINE_STRING_TABLE_LOOKUP(netlink_family, int);
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
[SOCKET_ADDRESS_DEFAULT] = "default",
diff --git a/src/shared/socket-util.h b/src/shared/socket-util.h
index 7cca2f53c6..04cfb83f5a 100644
--- a/src/shared/socket-util.h
+++ b/src/shared/socket-util.h
@@ -93,7 +93,7 @@ bool socket_address_needs_mount(const SocketAddress *a, const char *prefix);
const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b);
SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s);
-const char* netlink_family_to_string(int b);
+int netlink_family_to_string_alloc(int b, char **s);
int netlink_family_from_string(const char *s);
bool socket_ipv6_is_supported(void);
diff --git a/src/shared/util.c b/src/shared/util.c
index 23832fe16a..402b7caa3f 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -5207,7 +5207,7 @@ static const char *const ioprio_class_table[] = {
[IOPRIO_CLASS_IDLE] = "idle"
};
-DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int);
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
static const char *const sigchld_code_table[] = {
[CLD_EXITED] = "exited",
@@ -5243,7 +5243,7 @@ static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
[LOG_FAC(LOG_LOCAL7)] = "local7"
};
-DEFINE_STRING_TABLE_LOOKUP(log_facility_unshifted, int);
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
static const char *const log_level_table[] = {
[LOG_EMERG] = "emerg",
@@ -5256,7 +5256,7 @@ static const char *const log_level_table[] = {
[LOG_DEBUG] = "debug"
};
-DEFINE_STRING_TABLE_LOOKUP(log_level, int);
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
static const char* const sched_policy_table[] = {
[SCHED_OTHER] = "other",
@@ -5266,7 +5266,7 @@ static const char* const sched_policy_table[] = {
[SCHED_RR] = "rr"
};
-DEFINE_STRING_TABLE_LOOKUP(sched_policy, int);
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
static const char* const rlimit_table[] = {
[RLIMIT_CPU] = "LimitCPU",
@@ -5296,7 +5296,7 @@ static const char* const ip_tos_table[] = {
[IPTOS_LOWCOST] = "low-cost",
};
-DEFINE_STRING_TABLE_LOOKUP(ip_tos, int);
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
static const char *const __signal_table[] = {
[SIGHUP] = "HUP",
diff --git a/src/shared/util.h b/src/shared/util.h
index f726263dd3..ca80bfe2e8 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -291,6 +291,7 @@ int make_console_stdio(void);
unsigned long long random_ull(void);
+/* For basic lookup tables with strictly enumerated entries */
#define __DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \
scope const char *name##_to_string(type i) { \
if (i < 0 || i >= (type) ELEMENTSOF(name##_table)) \
@@ -299,15 +300,11 @@ unsigned long long random_ull(void);
} \
scope type name##_from_string(const char *s) { \
type i; \
- unsigned u = 0; \
assert(s); \
for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \
if (name##_table[i] && \
streq(name##_table[i], s)) \
return i; \
- if (safe_atou(s, &u) >= 0 && \
- u < ELEMENTSOF(name##_table)) \
- return (type) u; \
return (type) -1; \
} \
struct __useless_struct_to_allow_trailing_semicolon__
@@ -315,6 +312,39 @@ unsigned long long random_ull(void);
#define DEFINE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,)
#define DEFINE_PRIVATE_STRING_TABLE_LOOKUP(name,type) __DEFINE_STRING_TABLE_LOOKUP(name,type,static)
+/* For string conversions where numbers are also acceptable */
+#define DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(name,type,max) \
+ int name##_to_string_alloc(type i, char **str) { \
+ char *s; \
+ int r; \
+ if (i < 0 || i > max) \
+ return -ERANGE; \
+ if (i < (type) ELEMENTSOF(name##_table)) { \
+ s = strdup(name##_table[i]); \
+ if (!s) \
+ return log_oom(); \
+ } else { \
+ r = asprintf(&s, "%u", i); \
+ if (r < 0) \
+ return log_oom(); \
+ } \
+ *str = s; \
+ return 0; \
+ } \
+ type name##_from_string(const char *s) { \
+ type i; \
+ unsigned u = 0; \
+ assert(s); \
+ for (i = 0; i < (type)ELEMENTSOF(name##_table); i++) \
+ if (name##_table[i] && \
+ streq(name##_table[i], s)) \
+ return i; \
+ if (safe_atou(s, &u) >= 0 && u < max) \
+ return (type) u; \
+ return (type) -1; \
+ } \
+ struct __useless_struct_to_allow_trailing_semicolon__
+
int fd_nonblock(int fd, bool nonblock);
int fd_cloexec(int fd, bool cloexec);
@@ -478,25 +508,25 @@ int strdup_or_null(const char *a, char **b);
#define NULSTR_FOREACH_PAIR(i, j, l) \
for ((i) = (l), (j) = strchr((i), 0)+1; (i) && *(i); (i) = strchr((j), 0)+1, (j) = *(i) ? strchr((i), 0)+1 : (i))
-const char *ioprio_class_to_string(int i);
+int ioprio_class_to_string_alloc(int i, char **s);
int ioprio_class_from_string(const char *s);
const char *sigchld_code_to_string(int i);
int sigchld_code_from_string(const char *s);
-const char *log_facility_unshifted_to_string(int i);
+int log_facility_unshifted_to_string_alloc(int i, char **s);
int log_facility_unshifted_from_string(const char *s);
-const char *log_level_to_string(int i);
+int log_level_to_string_alloc(int i, char **s);
int log_level_from_string(const char *s);
-const char *sched_policy_to_string(int i);
+int sched_policy_to_string_alloc(int i, char **s);
int sched_policy_from_string(const char *s);
const char *rlimit_to_string(int i);
int rlimit_from_string(const char *s);
-const char *ip_tos_to_string(int i);
+int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
const char *signal_to_string(int i);