diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-10-16 15:56:58 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-10-18 13:51:02 +0200 |
commit | 3b444970e609410951b4a96a9dcb648453c8b3f2 (patch) | |
tree | dde1e7e30eae0632f6541a5235c3d08734886465 /src/shared | |
parent | serialize: change order of deserialize_strv() parameters (diff) | |
download | systemd-3b444970e609410951b4a96a9dcb648453c8b3f2.tar.xz systemd-3b444970e609410951b4a96a9dcb648453c8b3f2.zip |
serialize: add serialize_fd_many() helper
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/serialize.c | 69 | ||||
-rw-r--r-- | src/shared/serialize.h | 2 |
2 files changed, 71 insertions, 0 deletions
diff --git a/src/shared/serialize.c b/src/shared/serialize.c index 5fecaa8702..cb1255932b 100644 --- a/src/shared/serialize.c +++ b/src/shared/serialize.c @@ -116,6 +116,33 @@ int serialize_fd(FILE *f, FDSet *fds, const char *key, int fd) { return serialize_item_format(f, key, "%i", copy); } +int serialize_fd_many(FILE *f, FDSet *fds, const char *key, const int fd_array[], size_t n_fd_array) { + _cleanup_free_ char *t = NULL; + + assert(f); + + if (n_fd_array == 0) + return 0; + + assert(fd_array); + + for (size_t i = 0; i < n_fd_array; i++) { + int copy; + + if (fd_array[i] < 0) + return -EBADF; + + copy = fdset_put_dup(fds, fd_array[i]); + if (copy < 0) + return log_error_errno(copy, "Failed to add file descriptor to serialization set: %m"); + + if (strextendf_with_separator(&t, " ", "%i", copy) < 0) + return log_oom(); + } + + return serialize_item(f, key, t); +} + int serialize_usec(FILE *f, const char *key, usec_t usec) { assert(f); assert(key); @@ -302,6 +329,48 @@ int deserialize_fd(FDSet *fds, const char *value) { return TAKE_FD(our_fd); } +int deserialize_fd_many(FDSet *fds, const char *value, size_t n, int *ret) { + int r, *fd_array = NULL; + size_t m = 0; + + assert(value); + + fd_array = new(int, n); + if (!fd_array) + return -ENOMEM; + + CLEANUP_ARRAY(fd_array, m, close_many_and_free); + + for (;;) { + _cleanup_free_ char *w = NULL; + int fd; + + r = extract_first_word(&value, &w, NULL, 0); + if (r < 0) + return r; + if (r == 0) { + if (m < n) /* Too few */ + return -EINVAL; + + break; + } + + if (m >= n) /* Too many */ + return -EINVAL; + + fd = deserialize_fd(fds, w); + if (fd < 0) + return fd; + + fd_array[m++] = fd; + } + + memcpy(ret, fd_array, m * sizeof(int)); + fd_array = mfree(fd_array); + + return 0; +} + int deserialize_strv(const char *value, char ***l) { ssize_t unescaped_len; char *unescaped; diff --git a/src/shared/serialize.h b/src/shared/serialize.h index b2dcfd2110..c5211191f0 100644 --- a/src/shared/serialize.h +++ b/src/shared/serialize.h @@ -17,6 +17,7 @@ int serialize_item_format(FILE *f, const char *key, const char *value, ...) _pri int serialize_item_hexmem(FILE *f, const char *key, const void *p, size_t l); int serialize_item_base64mem(FILE *f, const char *key, const void *p, size_t l); int serialize_fd(FILE *f, FDSet *fds, const char *key, int fd); +int serialize_fd_many(FILE *f, FDSet *fds, const char *key, const int fd_array[], size_t n_fd_array); int serialize_usec(FILE *f, const char *key, usec_t usec); int serialize_dual_timestamp(FILE *f, const char *key, const dual_timestamp *t); int serialize_strv(FILE *f, const char *key, char **l); @@ -38,6 +39,7 @@ static inline int serialize_item_tristate(FILE *f, const char *key, int value) { int deserialize_read_line(FILE *f, char **ret); int deserialize_fd(FDSet *fds, const char *value); +int deserialize_fd_many(FDSet *fds, const char *value, size_t n, int *ret); int deserialize_usec(const char *value, usec_t *ret); int deserialize_dual_timestamp(const char *value, dual_timestamp *ret); int deserialize_environment(const char *value, char ***environment); |