summaryrefslogtreecommitdiffstats
path: root/src/portable/portable.c
diff options
context:
space:
mode:
authorLuca Boccassi <luca.boccassi@microsoft.com>2021-09-16 13:43:51 +0200
committerLuca Boccassi <luca.boccassi@microsoft.com>2021-09-20 15:23:55 +0200
commit447d46879ca2b7c001a3d27d6a89ef05fb77c297 (patch)
treea32a3a237153d26529be0d6c5893698996b423ee /src/portable/portable.c
parentselinux: add mac_selinux_create_file_prepare_label helper (diff)
downloadsystemd-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.c113
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;