forked from lix-project/lix
66 lines
1.9 KiB
C
66 lines
1.9 KiB
C
|
#include <sys/socket.h>
|
||
|
#include <sys/un.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stddef.h>
|
||
|
#include <stdio.h>
|
||
|
#include <unistd.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <errno.h>
|
||
|
#include <string.h>
|
||
|
#include <assert.h>
|
||
|
|
||
|
int main(int argc, char **argv) {
|
||
|
|
||
|
assert(argc == 2);
|
||
|
|
||
|
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||
|
|
||
|
// Set up a abstract domain socket path to connect to.
|
||
|
struct sockaddr_un data;
|
||
|
data.sun_family = AF_UNIX;
|
||
|
data.sun_path[0] = 0;
|
||
|
strcpy(data.sun_path + 1, argv[1]);
|
||
|
|
||
|
// Now try to connect, To ensure we work no matter what order we are
|
||
|
// executed in, just busyloop here.
|
||
|
int res = -1;
|
||
|
while (res < 0) {
|
||
|
res = connect(sock, (const struct sockaddr *)&data,
|
||
|
offsetof(struct sockaddr_un, sun_path)
|
||
|
+ strlen(argv[1])
|
||
|
+ 1);
|
||
|
if (res < 0 && errno != ECONNREFUSED) perror("connect");
|
||
|
if (errno != ECONNREFUSED) break;
|
||
|
}
|
||
|
|
||
|
// Write our message header.
|
||
|
struct msghdr msg = {0};
|
||
|
msg.msg_control = malloc(128);
|
||
|
msg.msg_controllen = 128;
|
||
|
|
||
|
// Write an SCM_RIGHTS message containing the output path.
|
||
|
struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
|
||
|
hdr->cmsg_len = CMSG_LEN(sizeof(int));
|
||
|
hdr->cmsg_level = SOL_SOCKET;
|
||
|
hdr->cmsg_type = SCM_RIGHTS;
|
||
|
int fd = open(getenv("out"), O_RDWR | O_CREAT, 0640);
|
||
|
memcpy(CMSG_DATA(hdr), (void *)&fd, sizeof(int));
|
||
|
|
||
|
msg.msg_controllen = CMSG_SPACE(sizeof(int));
|
||
|
|
||
|
// Write a single null byte too.
|
||
|
msg.msg_iov = malloc(sizeof(struct iovec));
|
||
|
msg.msg_iov[0].iov_base = "";
|
||
|
msg.msg_iov[0].iov_len = 1;
|
||
|
msg.msg_iovlen = 1;
|
||
|
|
||
|
// Send it to the othher side of this connection.
|
||
|
res = sendmsg(sock, &msg, 0);
|
||
|
if (res < 0) perror("sendmsg");
|
||
|
int buf;
|
||
|
|
||
|
// Wait for the server to close the socket, implying that it has
|
||
|
// received the commmand.
|
||
|
recv(sock, (void *)&buf, sizeof(int), 0);
|
||
|
}
|