aboutsummaryrefslogtreecommitdiff
path: root/c/fd-over-sock/server.c
blob: 948e0ec800f3d37627d595d29f54f40d10a94a4a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <sys/socket.h>
#include <sys/un.h>

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define die(...) err(EXIT_FAILURE, __VA_ARGS__)

int
main(void)
{
	int sfd;
	socklen_t saddrlen = sizeof(struct sockaddr_un);
	struct sockaddr_un saddr = {
		.sun_family = AF_UNIX,
		.sun_path = "foo.sock",
	};

	if ((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		die("socket");
	if (bind(sfd, (struct sockaddr *)&saddr, saddrlen) == -1)
		die("bind");
	if (listen(sfd, 4) == -1)
		die("listen");

	for (;;) {
		int cfd = accept(sfd, NULL, NULL);
		if (cfd == -1)
			die("accept");

		struct msghdr msg = {0};
		char m_buffer[sizeof(size_t) * 2];
		struct iovec io = {
			.iov_base = m_buffer,
			.iov_len = sizeof(m_buffer),
		};
		msg.msg_iov = &io;
		msg.msg_iovlen = 1;

		char c_buffer[256];
		msg.msg_control = c_buffer;
		msg.msg_controllen = sizeof(c_buffer);

		if (recvmsg(cfd, &msg, 0) == -1)
			die("recvmsg");

		struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
		unsigned char *data = CMSG_DATA(cmsg);
		int fd = *(int *)data;

		size_t flen, mlen;
		memcpy(&flen, m_buffer, sizeof(size_t));
		memcpy(&mlen, m_buffer + sizeof(size_t), sizeof(size_t));

		// printf("len: %zu\n", msg.msg_iov->iov_len);
		write(STDOUT_FILENO, m_buffer + sizeof(size_t) * 2, mlen);
		putchar('\n');

		char buf[flen];
		read(fd, buf, flen);
		write(STDOUT_FILENO, buf, flen);
		close(cfd);
	}

	return EXIT_SUCCESS;
}