diff options
author | Luca Boccassi <luca.boccassi@microsoft.com> | 2021-09-16 13:43:51 +0200 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@microsoft.com> | 2021-09-20 15:23:55 +0200 |
commit | 447d46879ca2b7c001a3d27d6a89ef05fb77c297 (patch) | |
tree | a32a3a237153d26529be0d6c5893698996b423ee /src/portable/portable.c | |
parent | selinux: add mac_selinux_create_file_prepare_label helper (diff) | |
download | systemd-447d46879ca2b7c001a3d27d6a89ef05fb77c297.tar.xz systemd-447d46879ca2b7c001a3d27d6a89ef05fb77c297.zip |
portable: use send_one_fd_iov/receive_one_fd_iov instead of custom helpers
Will be useful for the next commit switching to multiple IOVs
Diffstat (limited to 'src/portable/portable.c')
-rw-r--r-- | src/portable/portable.c | 113 |
1 files changed, 26 insertions, 87 deletions
diff --git a/src/portable/portable.c b/src/portable/portable.c index 3f841b9258..8af7fe2aef 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -134,96 +134,23 @@ int portable_metadata_hashmap_to_sorted_array(Hashmap *unit_files, PortableMetad return 0; } -static int send_item( +static int send_one_fd_iov_with_data_fd( int socket_fd, - const char *name, + const struct iovec *iov, + size_t iovlen, int fd) { - CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control = {}; - struct iovec iovec; - struct msghdr mh = { - .msg_control = &control, - .msg_controllen = sizeof(control), - .msg_iov = &iovec, - .msg_iovlen = 1, - }; - struct cmsghdr *cmsg; _cleanup_close_ int data_fd = -1; + assert(iov || iovlen == 0); assert(socket_fd >= 0); - assert(name); assert(fd >= 0); data_fd = copy_data_fd(fd); if (data_fd < 0) return data_fd; - cmsg = CMSG_FIRSTHDR(&mh); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - memcpy(CMSG_DATA(cmsg), &data_fd, sizeof(int)); - - iovec = IOVEC_MAKE_STRING(name); - - if (sendmsg(socket_fd, &mh, MSG_NOSIGNAL) < 0) - return -errno; - - return 0; -} - -static int recv_item( - int socket_fd, - char **ret_name, - int *ret_fd) { - - CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control; - char buffer[PATH_MAX+2]; - struct iovec iov = IOVEC_INIT(buffer, sizeof(buffer)-1); - struct msghdr mh = { - .msg_control = &control, - .msg_controllen = sizeof(control), - .msg_iov = &iov, - .msg_iovlen = 1, - }; - struct cmsghdr *cmsg; - _cleanup_close_ int found_fd = -1; - char *copy; - ssize_t n; - - assert(socket_fd >= 0); - assert(ret_name); - assert(ret_fd); - - n = recvmsg_safe(socket_fd, &mh, MSG_CMSG_CLOEXEC); - if (n < 0) - return (int) n; - - CMSG_FOREACH(cmsg, &mh) { - if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SCM_RIGHTS) { - - if (cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { - assert(found_fd < 0); - found_fd = *(int*) CMSG_DATA(cmsg); - break; - } - - cmsg_close_all(&mh); - return -EIO; - } - } - - buffer[n] = 0; - - copy = strdup(buffer); - if (!copy) - return -ENOMEM; - - *ret_name = copy; - *ret_fd = TAKE_FD(found_fd); - - return 0; + return send_one_fd_iov(socket_fd, data_fd, iov, iovlen, 0); } DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(portable_metadata_hash_ops, char, string_hash_func, string_compare_func, @@ -272,7 +199,11 @@ static int extract_now( path_is_extension ? "extension-release " : "os-release"); else { if (socket_fd >= 0) { - r = send_item(socket_fd, os_release_id, os_release_fd); + struct iovec iov[] = { + IOVEC_MAKE_STRING(os_release_id), + }; + + r = send_one_fd_iov_with_data_fd(socket_fd, iov, ELEMENTSOF(iov), os_release_fd); if (r < 0) return log_debug_errno(r, "Failed to send os-release file: %m"); } @@ -333,7 +264,11 @@ static int extract_now( } if (socket_fd >= 0) { - r = send_item(socket_fd, de->d_name, fd); + struct iovec iov[] = { + IOVEC_MAKE_STRING(de->d_name), + }; + + r = send_one_fd_iov_with_data_fd(socket_fd, iov, ELEMENTSOF(iov), fd); if (r < 0) return log_debug_errno(r, "Failed to send unit metadata to parent: %m"); } @@ -465,23 +400,27 @@ static int portable_extract_by_path( for (;;) { _cleanup_(portable_metadata_unrefp) PortableMetadata *add = NULL; - _cleanup_free_ char *name = NULL; _cleanup_close_ int fd = -1; + char iov_buffer[PATH_MAX + 2]; + struct iovec iov = IOVEC_INIT(iov_buffer, sizeof(iov_buffer)); - r = recv_item(seq[0], &name, &fd); - if (r < 0) - return log_debug_errno(r, "Failed to receive item: %m"); + ssize_t n = receive_one_fd_iov(seq[0], &iov, 1, 0, &fd); + if (n == -EIO) + break; + if (n < 0) + return log_debug_errno(n, "Failed to receive item: %m"); + iov_buffer[n] = 0; /* We can't really distinguish a zero-length datagram without any fds from EOF (both are signalled the * same way by recvmsg()). Hence, accept either as end notification. */ - if (isempty(name) && fd < 0) + if (isempty(iov_buffer) && fd < 0) break; - if (isempty(name) || fd < 0) + if (isempty(iov_buffer) || fd < 0) return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid item sent from child."); - add = portable_metadata_new(name, path, fd); + add = portable_metadata_new(iov_buffer, path, fd); if (!add) return -ENOMEM; fd = -1; |