diff options
author | Thomas Voss <mail@thomasvoss.com> | 2023-12-11 17:24:34 +0100 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2023-12-11 17:24:34 +0100 |
commit | 2fb71458d07f4ddc6f04773ae75341300fda8905 (patch) | |
tree | 125d601da3c2089b48177e36bf5559cc40a32080 /c/fd-over-sock/client.c | |
parent | e10f9802088722e85fd4f2f9cb006d2bdca37d3c (diff) |
Add fc-over-sock
Diffstat (limited to 'c/fd-over-sock/client.c')
-rw-r--r-- | c/fd-over-sock/client.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/c/fd-over-sock/client.c b/c/fd-over-sock/client.c new file mode 100644 index 0000000..506c2ca --- /dev/null +++ b/c/fd-over-sock/client.c @@ -0,0 +1,81 @@ +#define _GNU_SOURCE +#include <sys/mman.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/un.h> + +#include <err.h> +#include <fcntl.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define die(...) err(EXIT_FAILURE, __VA_ARGS__) + +typedef uint8_t u8; + +int +main(int argc, char **argv) +{ + int fd, sfd; + void *shm; + socklen_t saddrlen = sizeof(struct sockaddr_un); + struct stat sb; + struct sockaddr_un saddr = { + .sun_family = AF_UNIX, + .sun_path = "foo.sock", + }; + + *argv = basename(*argv); + if (argc != 2) { + fprintf(stderr, "Usage: %s file\n", *argv); + exit(EXIT_FAILURE); + } + + if ((fd = open(argv[1], O_RDONLY)) == -1) + die("open: %s", argv[1]); + if (fstat(fd, &sb) == -1) + die("fstat: %s", argv[1]); + shm = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (shm == MAP_FAILED) + die("mmap: %s", argv[1]); + + if ((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + die("socket"); + if (connect(sfd, &saddr, saddrlen) == -1) + die("connect"); + + u8 msg[sizeof(size_t) * 2 + sizeof("hello world") - 1]; + char buf[CMSG_SPACE(sizeof(int))]; + struct iovec iov = { + .iov_base = msg, + .iov_len = sizeof(msg) - 1, + }; + struct msghdr hdr = { + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = buf, + .msg_controllen = CMSG_SPACE(sizeof(int)), + }; + struct cmsghdr *cmsg = CMSG_FIRSTHDR(&hdr); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + *(int *)CMSG_DATA(cmsg) = fd; + + size_t len = sb.st_size; + size_t len2 = 11; + memcpy(msg, &len, sizeof(size_t)); + memcpy(msg + sizeof(size_t), &len2, sizeof(size_t)); + memcpy(msg + sizeof(size_t) * 2, "hello, world", 11); + + if (sendmsg(sfd, &hdr, 0) == -1) + die("sendmsg"); + + munmap(shm, sb.st_size); + close(fd); + close(sfd); + return EXIT_SUCCESS; +} |