From: Lennart Poettering Date: Mon, 16 Oct 2023 13:56:58 +0000 (+0200) Subject: serialize: add serialize_fd_many() helper X-Git-Tag: v255-rc1~212^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b444970e609410951b4a96a9dcb648453c8b3f2;p=thirdparty%2Fsystemd.git serialize: add serialize_fd_many() helper --- diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index 5292e41937a..33c4a057adf 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -99,6 +99,13 @@ void close_many(const int fds[], size_t n_fd) { safe_close(fds[i]); } +void close_many_and_free(int *fds, size_t n_fds) { + assert(fds || n_fds <= 0); + + close_many(fds, n_fds); + free(fds); +} + int fclose_nointr(FILE *f) { assert(f); diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h index 6aecb91fab3..1f5ed828b7b 100644 --- a/src/basic/fd-util.h +++ b/src/basic/fd-util.h @@ -30,6 +30,7 @@ static inline int safe_close_above_stdio(int fd) { } void close_many(const int fds[], size_t n_fd); +void close_many_and_free(int *fds, size_t n_fds); int fclose_nointr(FILE *f); FILE* safe_fclose(FILE *f); diff --git a/src/core/execute-serialize.c b/src/core/execute-serialize.c index ca65ca2c421..55f5bdc8c97 100644 --- a/src/core/execute-serialize.c +++ b/src/core/execute-serialize.c @@ -1117,33 +1117,13 @@ static int exec_runtime_serialize(const ExecRuntime *rt, FILE *f, FDSet *fds) { return r; if (rt->shared->netns_storage_socket[0] >= 0 && rt->shared->netns_storage_socket[1] >= 0) { - int a, b; - - a = fdset_put_dup(fds, rt->shared->netns_storage_socket[0]); - if (a < 0) - return a; - - b = fdset_put_dup(fds, rt->shared->netns_storage_socket[1]); - if (b < 0) - return b; - - r = serialize_item_format(f, "exec-runtime-netns-storage-socket", "%d %d", a, b); + r = serialize_fd_many(f, fds, "exec-runtime-netns-storage-socket", rt->shared->netns_storage_socket, 2); if (r < 0) return r; } if (rt->shared->ipcns_storage_socket[0] >= 0 && rt->shared->ipcns_storage_socket[1] >= 0) { - int a, b; - - a = fdset_put_dup(fds, rt->shared->ipcns_storage_socket[0]); - if (a < 0) - return a; - - b = fdset_put_dup(fds, rt->shared->ipcns_storage_socket[1]); - if (b < 0) - return b; - - r = serialize_item_format(f, "exec-runtime-ipcns-storage-socket", "%d %d", a, b); + r = serialize_fd_many(f, fds, "exec-runtime-ipcns-storage-socket", rt->shared->ipcns_storage_socket, 2); if (r < 0) return r; } @@ -1170,17 +1150,7 @@ static int exec_runtime_serialize(const ExecRuntime *rt, FILE *f, FDSet *fds) { return r; if (rt->ephemeral_storage_socket[0] >= 0 && rt->ephemeral_storage_socket[1] >= 0) { - int a, b; - - a = fdset_put_dup(fds, rt->ephemeral_storage_socket[0]); - if (a < 0) - return a; - - b = fdset_put_dup(fds, rt->ephemeral_storage_socket[1]); - if (b < 0) - return b; - - r = serialize_item_format(f, "exec-runtime-ephemeral-storage-socket", "%d %d", a, b); + r = serialize_fd_many(f, fds, "exec-runtime-ephemeral-storage-socket", rt->ephemeral_storage_socket, 2); if (r < 0) return r; } @@ -1222,39 +1192,17 @@ static int exec_runtime_deserialize(ExecRuntime *rt, FILE *f, FDSet *fds) { if (r < 0) return r; } else if ((val = startswith(l, "exec-runtime-netns-storage-socket="))) { - for (size_t i = 0; i < 2; ++i) { - _cleanup_free_ char *w = NULL; - int fd; - r = extract_first_word(&val, &w, WHITESPACE, 0); - if (r < 0) - return r; - if (r == 0) - break; - - fd = deserialize_fd(fds, w); - if (fd < 0) - continue; + r = deserialize_fd_many(fds, val, 2, rt->shared->netns_storage_socket); + if (r < 0) + continue; - rt->shared->netns_storage_socket[i] = fd; - } } else if ((val = startswith(l, "exec-runtime-ipcns-storage-socket="))) { - for (size_t i = 0; i < 2; ++i) { - _cleanup_free_ char *w = NULL; - int fd; - r = extract_first_word(&val, &w, WHITESPACE, 0); - if (r < 0) - return r; - if (r == 0) - break; - - fd = deserialize_fd(fds, w); - if (fd < 0) - continue; + r = deserialize_fd_many(fds, val, 2, rt->shared->ipcns_storage_socket); + if (r < 0) + continue; - rt->shared->ipcns_storage_socket[i] = fd; - } } else if ((val = startswith(l, "exec-runtime-dynamic-creds-user="))) dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->user); else if ((val = startswith(l, "exec-runtime-dynamic-creds-group="))) @@ -1275,22 +1223,10 @@ static int exec_runtime_deserialize(ExecRuntime *rt, FILE *f, FDSet *fds) { if (r < 0) return r; } else if ((val = startswith(l, "exec-runtime-ephemeral-storage-socket="))) { - for (size_t i = 0; i < 2; ++i) { - _cleanup_free_ char *w = NULL; - int fd; - r = extract_first_word(&val, &w, WHITESPACE, 0); - if (r < 0) - return r; - if (r == 0) - break; - - fd = deserialize_fd(fds, w); - if (fd < 0) - continue; - - rt->ephemeral_storage_socket[i] = fd; - } + r = deserialize_fd_many(fds, val, 2, rt->ephemeral_storage_socket); + if (r < 0) + continue; } else log_warning("Failed to parse serialized line, ignoring: %s", l); } @@ -1338,26 +1274,7 @@ static int exec_parameters_serialize(const ExecParameters *p, FILE *f, FDSet *fd } if (p->n_socket_fds + p->n_storage_fds > 0) { - _cleanup_free_ char *serialized_fds = NULL; - - if (!p->fds) - return -EINVAL; - - FOREACH_ARRAY(fd, p->fds, p->n_socket_fds + p->n_storage_fds) { - int copy = -EBADF; - - if (*fd >= 0) { - copy = fdset_put_dup(fds, *fd); - if (copy < 0) - return copy; - } - - r = strextendf(&serialized_fds, "%d ", copy); - if (r < 0) - return r; - } - - r = serialize_item(f, "exec-parameters-fds", serialized_fds); + r = serialize_fd_many(f, fds, "exec-parameters-fds", p->fds, p->n_socket_fds + p->n_storage_fds); if (r < 0) return r; } @@ -1427,19 +1344,7 @@ static int exec_parameters_serialize(const ExecParameters *p, FILE *f, FDSet *fd } if (exec_parameters_is_idle_pipe_set(p)) { - _cleanup_free_ char *serialized_fds = NULL; - - for (size_t i = 0; i < 4; ++i) { - int copy = fdset_put_dup(fds, p->idle_pipe[i]); - if (copy < 0) - return copy; - - r = strextendf(&serialized_fds, "%d ", copy); - if (r < 0) - return r; - } - - r = serialize_item(f, "exec-parameters-idle-pipe", serialized_fds); + r = serialize_fd_many(f, fds, "exec-parameters-idle-pipe", p->idle_pipe, 4); if (r < 0) return r; } @@ -1587,22 +1492,10 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) { for (size_t i = 0; i < p->n_socket_fds + p->n_storage_fds; ++i) p->fds[i] = -EBADF; - for (size_t i = 0; i < p->n_socket_fds + p->n_storage_fds; ++i) { - _cleanup_free_ char *w = NULL; - int fd; - - r = extract_first_word(&val, &w, WHITESPACE, 0); - if (r < 0) - return r; - if (r == 0) - break; - - fd = deserialize_fd(fds, w); - if (fd < 0) - continue; + r = deserialize_fd_many(fds, val, p->n_socket_fds + p->n_storage_fds, p->fds); + if (r < 0) + continue; - p->fds[i] = fd; - } } else if ((val = startswith(l, "exec-parameters-fd-names="))) { r = deserialize_strv(val, &p->fd_names); if (r < 0) @@ -1691,22 +1584,10 @@ static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) { p->idle_pipe[0] = p->idle_pipe[1] = p->idle_pipe[2] = p->idle_pipe[3] = -EBADF; - for (size_t i = 0; i < 4; ++i) { - _cleanup_free_ char *w = NULL; - int fd; - - r = extract_first_word(&val, &w, WHITESPACE, 0); - if (r < 0) - return r; - if (r == 0) - break; - - fd = deserialize_fd(fds, w); - if (fd < 0) - continue; + r = deserialize_fd_many(fds, val, 4, p->idle_pipe); + if (r < 0) + continue; - p->idle_pipe[i] = fd; - } } else if ((val = startswith(l, "exec-parameters-stdin-fd="))) { int fd; diff --git a/src/shared/serialize.c b/src/shared/serialize.c index 5fecaa87028..cb1255932bb 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 b2dcfd21102..c5211191f03 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);