const struct sockaddr *sa, socklen_t len,
int flags) {
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control = {};
struct msghdr mh = {
.msg_name = (struct sockaddr*) sa,
.msg_namelen = len,
int flags,
int *ret_fd) {
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control;
struct msghdr mh = {
.msg_control = &control,
.msg_controllen = sizeof(control),
(ctype*) (_found ? CMSG_DATA(_found) : NULL); \
})
+/* Resolves to a type that can carry cmsghdr structures. Make sure things are properly aligned, i.e. the type
+ * itself is placed properly in memory and the size is also aligned to what's appropriate for "cmsghdr"
+ * structures. */
+#define CMSG_BUFFER_TYPE(size) \
+ union { \
+ struct cmsghdr cmsghdr; \
+ uint8_t buf[size]; \
+ uint8_t align_check[(size) >= CMSG_SPACE(0) && \
+ (size) == CMSG_ALIGN(size) ? 1 : -1]; \
+ }
+
/*
* Certain hardware address types (e.g Infiniband) do not fit into sll_addr
* (8 bytes) and run over the structure. This macro returns the correct size that
.iov_base = buf,
.iov_len = sizeof(buf)-1,
};
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
- CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)];
- } control = {};
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) +
+ CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)) control;
struct msghdr msghdr = {
.msg_iov = &iovec,
.msg_iovlen = 1,
log_debug("Processing coredump received on stdin...");
for (;;) {
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control;
struct msghdr mh = {
.msg_control = &control,
.msg_controllen = sizeof(control),
return -ENOMEM;
if (ret_sender) {
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
- } control;
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
bool found_ucred = false;
struct cmsghdr *cmsg;
struct msghdr mh;
.iov_base = buf,
.iov_len = sizeof(buf)-1,
};
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
- CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)];
- } control = {};
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) +
+ CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)) control;
struct msghdr msghdr = {
.msg_iov = &iovec,
.msg_iovlen = 1,
int *fds = NULL, v = 0;
size_t n_fds = 0;
- union {
- struct cmsghdr cmsghdr;
-
- /* We use NAME_MAX space for the SELinux label
- * here. The kernel currently enforces no
- * limit, but according to suggestions from
- * the SELinux people this will change and it
- * will probably be identical to NAME_MAX. For
- * now we use that, but this should be updated
- * one day when the final limit is known. */
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
- CMSG_SPACE(sizeof(struct timeval)) +
- CMSG_SPACE(sizeof(int)) + /* fd */
- CMSG_SPACE(NAME_MAX)]; /* selinux label */
- } control = {};
+ /* We use NAME_MAX space for the SELinux label here. The kernel currently enforces no limit, but
+ * according to suggestions from the SELinux people this will change and it will probably be
+ * identical to NAME_MAX. For now we use that, but this should be updated one day when the final
+ * limit is known. */
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) +
+ CMSG_SPACE(sizeof(struct timeval)) +
+ CMSG_SPACE(sizeof(int)) + /* fd */
+ CMSG_SPACE(NAME_MAX) /* selinux label */) control;
union sockaddr_union sa = {};
}
static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
StdoutStream *s = userdata;
struct ucred *ucred;
struct iovec iovec;
struct msghdr msghdr = {
.msg_iov = &iovec,
.msg_iovlen = 1,
- .msg_control = buf,
- .msg_controllen = sizeof(buf),
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
};
assert(s);
.msg_iovlen = n_iovec,
};
struct cmsghdr *cmsg;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
- } control;
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
const char *j;
int r;
int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
triple_timestamp *timestamp) {
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */
- CMSG_SPACE(sizeof(struct timeval))];
- } control = {};
+
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int)) + /* ttl */
+ CMSG_SPACE(sizeof(struct timeval))) control;
struct iovec iov = {};
union sockaddr_union sa = {};
struct msghdr msg = {
sd_dhcp_client *client = userdata;
_cleanup_free_ DHCPPacket *packet = NULL;
- uint8_t cmsgbuf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct tpacket_auxdata))) control;
struct iovec iov = {};
struct msghdr msg = {
.msg_iov = &iov,
.msg_iovlen = 1,
- .msg_control = cmsgbuf,
- .msg_controllen = sizeof(cmsgbuf),
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
};
struct cmsghdr *cmsg;
bool checksum = true;
.iov_base = message,
.iov_len = len,
};
- uint8_t cmsgbuf[CMSG_SPACE(sizeof(struct in_pktinfo))] = {};
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in_pktinfo))) control = {};
struct msghdr msg = {
.msg_name = &dest,
.msg_namelen = sizeof(dest.in),
.msg_iov = &iov,
.msg_iovlen = 1,
- .msg_control = cmsgbuf,
- .msg_controllen = sizeof(cmsgbuf),
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
};
struct cmsghdr *cmsg;
struct in_pktinfo *pktinfo;
static int server_receive_message(sd_event_source *s, int fd,
uint32_t revents, void *userdata) {
_cleanup_free_ DHCPMessage *message = NULL;
- uint8_t cmsgbuf[CMSG_SPACE(sizeof(struct in_pktinfo))];
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in_pktinfo))) control;
sd_dhcp_server *server = userdata;
struct iovec iov = {};
struct msghdr msg = {
.msg_iov = &iov,
.msg_iovlen = 1,
- .msg_control = cmsgbuf,
- .msg_controllen = sizeof(cmsgbuf),
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
};
struct cmsghdr *cmsg;
ssize_t buflen, len;
ssize_t k;
int r;
void *p;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
- } control;
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)) control;
bool handle_cmsg = false;
assert(b);
size_t need;
int r;
void *b;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)];
- } control;
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int) * BUS_FDS_MAX)) control;
bool handle_cmsg = false;
assert(bus);
.iov_base = &buf,
.iov_len = sizeof(buf)
};
- char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
union sockaddr_union snl;
struct msghdr smsg = {
.msg_iov = &iov,
.msg_iovlen = 1,
- .msg_control = cred_msg,
- .msg_controllen = sizeof(cred_msg),
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
.msg_name = &snl,
.msg_namelen = sizeof(snl),
};
.iov_base = buf,
.iov_len = sizeof(buf)-1,
};
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
- CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)];
- } control = {};
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred)) +
+ CMSG_SPACE(sizeof(int) * NOTIFY_FD_MAX)) control;
struct msghdr msghdr = {
.msg_iov = &iovec,
.msg_iovlen = 1,
const char *name,
int fd) {
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int))) control = {};
struct iovec iovec;
struct msghdr mh = {
.msg_control = &control,
char **ret_name,
int *ret_fd) {
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
+ 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 = {
}
static int dns_stream_identify(DnsStream *s) {
- union {
- struct cmsghdr header; /* For alignment */
- uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
- + EXTRA_CMSG_SPACE /* kernel appears to require extra space */];
- } control;
+ CMSG_BUFFER_TYPE(CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
+ + EXTRA_CMSG_SPACE /* kernel appears to require extra space */) control;
struct msghdr mh = {};
struct cmsghdr *cmsg;
socklen_t sl;
int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) {
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
- union {
- struct cmsghdr header; /* For alignment */
- uint8_t buffer[CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
- + CMSG_SPACE(int) /* ttl/hoplimit */
- + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */];
- } control;
+ CMSG_BUFFER_TYPE(CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
+ + CMSG_SPACE(int) /* ttl/hoplimit */
+ + EXTRA_CMSG_SPACE /* kernel appears to require extra buffer space */) control;
union sockaddr_union sa;
struct iovec iov;
struct msghdr mh = {
uint16_t port,
const struct in_addr *source,
DnsPacket *p) {
- union {
- struct cmsghdr header; /* For alignment */
- uint8_t buffer[CMSG_SPACE(sizeof(struct in_pktinfo))];
- } control = {};
+
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in_pktinfo))) control = {};
union sockaddr_union sa;
struct iovec iov;
struct msghdr mh = {
const struct in6_addr *source,
DnsPacket *p) {
- union {
- struct cmsghdr header; /* For alignment */
- uint8_t buffer[CMSG_SPACE(sizeof(struct in6_pktinfo))];
- } control = {};
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct in6_pktinfo))) control = {};
union sockaddr_union sa;
struct iovec iov;
struct msghdr mh = {
pollfd[FD_INOTIFY].events = POLLIN;
for (;;) {
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
char passphrase[LINE_MAX+1];
struct iovec iovec;
struct ucred *ucred;
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
- } control;
ssize_t n;
int k;
usec_t t;
iovec = IOVEC_MAKE(passphrase, sizeof(passphrase));
- zero(control);
struct msghdr msghdr = {
.msg_iov = &iovec,
.msg_iovlen = 1,
.iov_base = &ntpmsg,
.iov_len = sizeof(ntpmsg),
};
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
- } control;
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct timeval))) control;
union sockaddr_union server_addr;
struct msghdr msghdr = {
.msg_iov = &iov,
_cleanup_(udev_ctrl_disconnect_and_listen_againp) struct udev_ctrl *uctrl = NULL;
struct udev_ctrl_msg_wire msg_wire;
struct iovec iov = IOVEC_MAKE(&msg_wire, sizeof(struct udev_ctrl_msg_wire));
- char cred_msg[CMSG_SPACE(sizeof(struct ucred))];
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
struct msghdr smsg = {
.msg_iov = &iov,
.msg_iovlen = 1,
- .msg_control = cred_msg,
- .msg_controllen = sizeof(cred_msg),
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
};
struct cmsghdr *cmsg;
struct ucred *cred;
.iov_base = &msg,
.iov_len = sizeof(msg),
};
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
- } control = {};
+ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct ucred))) control;
struct msghdr msghdr = {
.msg_iov = &iovec,
.msg_iovlen = 1,