sendfds.c
51 lines
| 1.3 KiB
| text/x-c
|
CLexer
Yuya Nishihara
|
r40005 | /* | ||
* Utility to send fds via Unix domain socket | ||||
* | ||||
* Copyright 2011, 2018 Yuya Nishihara <yuya@tcha.org> | ||||
* | ||||
* This software may be used and distributed according to the terms of the | ||||
* GNU General Public License version 2 or any later version. | ||||
*/ | ||||
#include <errno.h> | ||||
#include <stdlib.h> | ||||
#include <string.h> | ||||
#include <sys/socket.h> | ||||
#include <sys/types.h> | ||||
#define MAX_FD_LEN 10 | ||||
/* | ||||
* Sends the given fds with 1-byte dummy payload. | ||||
* | ||||
* Returns the number of bytes sent on success, -1 on error and errno is set | ||||
* appropriately. | ||||
*/ | ||||
ssize_t sendfds(int sockfd, const int *fds, size_t fdlen) | ||||
{ | ||||
char dummy[1] = {0}; | ||||
struct iovec iov = {dummy, sizeof(dummy)}; | ||||
char fdbuf[CMSG_SPACE(sizeof(fds[0]) * MAX_FD_LEN)]; | ||||
struct msghdr msgh; | ||||
struct cmsghdr *cmsg; | ||||
/* just use a fixed-size buffer since we'll never send tons of fds */ | ||||
if (fdlen > MAX_FD_LEN) { | ||||
errno = EINVAL; | ||||
return -1; | ||||
} | ||||
memset(&msgh, 0, sizeof(msgh)); | ||||
msgh.msg_iov = &iov; | ||||
msgh.msg_iovlen = 1; | ||||
msgh.msg_control = fdbuf; | ||||
msgh.msg_controllen = CMSG_SPACE(sizeof(fds[0]) * fdlen); | ||||
cmsg = CMSG_FIRSTHDR(&msgh); | ||||
cmsg->cmsg_level = SOL_SOCKET; | ||||
cmsg->cmsg_type = SCM_RIGHTS; | ||||
cmsg->cmsg_len = CMSG_LEN(sizeof(fds[0]) * fdlen); | ||||
memcpy(CMSG_DATA(cmsg), fds, sizeof(fds[0]) * fdlen); | ||||
msgh.msg_controllen = cmsg->cmsg_len; | ||||
return sendmsg(sockfd, &msgh, 0); | ||||
} | ||||