iovec-util: add exported constant empty but valid (i.e. non-NULL) iovec

Also, make sure the NUL byte iovec becomes an exported constant too.

This is better than the previous situation where this was a macro
resolving to a compount expression, since the lifetime of the expression
is limited to its invoking scope. By turning this into a proper variable
the lifetime becomes unbounded, which makes it easier to use in various
scenarios, such as "if" blocks.
This commit is contained in:
Lennart Poettering 2024-06-03 17:39:04 +02:00 committed by Luca Boccassi
parent acaca5ab25
commit 432977a0a4
4 changed files with 18 additions and 12 deletions

View file

@ -3,6 +3,18 @@
#include "iovec-util.h"
#include "string-util.h"
static const uint8_t nul_byte = 0;
const struct iovec iovec_nul_byte = {
.iov_base = (void*) &nul_byte,
.iov_len = 1,
};
const struct iovec iovec_empty = {
.iov_base = (void*) &nul_byte,
.iov_len = 0,
};
size_t iovec_total_size(const struct iovec *iovec, size_t n) {
size_t sum = 0;

View file

@ -8,11 +8,8 @@
#include "alloc-util.h"
#include "macro.h"
/* An iovec pointing to a single NUL byte */
#define IOVEC_NUL_BYTE (const struct iovec) { \
.iov_base = (void*) (const uint8_t[1]) { 0 }, \
.iov_len = 1, \
}
extern const struct iovec iovec_nul_byte; /* Points to a single NUL byte */
extern const struct iovec iovec_empty; /* Points to an empty, but valid (i.e. non-NULL) pointer */
size_t iovec_total_size(const struct iovec *iovec, size_t n);

View file

@ -41,7 +41,7 @@ static int process_vsock(const char *host, const char *port) {
return log_error_errno(errno, "Failed to connect to vsock:%u:%u: %m", sa.vm.svm_cid, sa.vm.svm_port);
/* OpenSSH wants us to send a single byte along with the file descriptor, hence do so */
r = send_one_fd_iov(STDOUT_FILENO, fd, &IOVEC_NUL_BYTE, /* n_iovec= */ 1, /* flags= */ 0);
r = send_one_fd_iov(STDOUT_FILENO, fd, &iovec_nul_byte, /* n_iovec= */ 1, /* flags= */ 0);
if (r < 0)
return log_error_errno(r, "Failed to send socket via STDOUT: %m");
@ -72,7 +72,7 @@ static int process_unix(const char *path) {
if (r < 0)
return log_error_errno(r, "Failed to connect to AF_UNIX socket %s: %m", path);
r = send_one_fd_iov(STDOUT_FILENO, fd, &IOVEC_NUL_BYTE, /* n_iovec= */ 1, /* flags= */ 0);
r = send_one_fd_iov(STDOUT_FILENO, fd, &iovec_nul_byte, /* n_iovec= */ 1, /* flags= */ 0);
if (r < 0)
return log_error_errno(r, "Failed to send socket via STDOUT: %m");
@ -116,7 +116,7 @@ static int process_vsock_mux(const char *path, const char *port) {
if (r < 0)
return log_error_errno(r, "Failed to send CONNECT to %s:%s: %m", path, port);
r = send_one_fd_iov(STDOUT_FILENO, fd, &IOVEC_NUL_BYTE, /* n_iovec= */ 1, /* flags= */ 0);
r = send_one_fd_iov(STDOUT_FILENO, fd, &iovec_nul_byte, /* n_iovec= */ 1, /* flags= */ 0);
if (r < 0)
return log_error_errno(r, "Failed to send socket via STDOUT: %m");

View file

@ -453,13 +453,10 @@ TEST(send_emptydata) {
if (r == 0) {
/* Child */
struct iovec iov = IOVEC_MAKE_STRING(""); /* zero-length iov */
assert_se(iov.iov_len == 0);
pair[0] = safe_close(pair[0]);
/* This will succeed, since iov is set. */
assert_se(send_one_fd_iov(pair[1], -1, &iov, 1, MSG_DONTWAIT) == 0);
assert_se(send_one_fd_iov(pair[1], -1, &iovec_empty, 1, MSG_DONTWAIT) == 0);
_exit(EXIT_SUCCESS);
}