main neuswc / launch / protocol.c
 1#include "protocol.h"
 2
 3#include <stdio.h>
 4#include <string.h>
 5#include <sys/socket.h>
 6
 7ssize_t
 8send_fd(int socket, int fd, struct iovec *iov, int iovlen)
 9{
10	char control[CMSG_SPACE(sizeof(fd))];
11	struct msghdr message = {
12	    .msg_name = NULL,
13	    .msg_namelen = 0,
14	    .msg_iov = iov,
15	    .msg_iovlen = iovlen,
16	};
17	struct cmsghdr *cmsg;
18
19	if (fd != -1) {
20		message.msg_control = control, message.msg_controllen = sizeof(control);
21
22		cmsg = CMSG_FIRSTHDR(&message);
23		cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
24		cmsg->cmsg_level = SOL_SOCKET;
25		cmsg->cmsg_type = SCM_RIGHTS;
26
27		memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
28	} else {
29		message.msg_control = NULL;
30		message.msg_controllen = 0;
31	}
32
33	return sendmsg(socket, &message, 0);
34}
35
36ssize_t
37receive_fd(int socket, int *fd, struct iovec *iov, int iovlen)
38{
39	ssize_t size;
40	char control[CMSG_SPACE(sizeof(*fd))];
41	struct msghdr message = {
42	    .msg_name = NULL,
43	    .msg_namelen = 0,
44	    .msg_iov = iov,
45	    .msg_iovlen = iovlen,
46	};
47	struct cmsghdr *cmsg;
48
49	if (fd) {
50		*fd = -1;
51		message.msg_control = &control;
52		message.msg_controllen = sizeof(control);
53	}
54
55	size = recvmsg(socket, &message, MSG_CMSG_CLOEXEC);
56	if (size < 0) {
57		return -1;
58	}
59
60	cmsg = CMSG_FIRSTHDR(&message);
61	if (fd && cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(*fd)) &&
62	    cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
63		memcpy(fd, CMSG_DATA(cmsg), sizeof(*fd));
64	}
65
66	return size;
67}