summaryrefslogtreecommitdiffstats
path: root/sbin/hastd/proto_common.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2011-01-31 18:35:17 +0000
committerpjd <pjd@FreeBSD.org>2011-01-31 18:35:17 +0000
commit214239b194b6861580bd58356d9abc3e0e9b50b6 (patch)
tree6ba0be808ae947b55743d27f5ae29dc66e331979 /sbin/hastd/proto_common.c
parentd916d2edb510181e3ab25256b84c439c5e1b8498 (diff)
downloadFreeBSD-src-214239b194b6861580bd58356d9abc3e0e9b50b6.zip
FreeBSD-src-214239b194b6861580bd58356d9abc3e0e9b50b6.tar.gz
Implement two new functions for sending descriptor and receving descriptor
over UNIX domain sockets and socket pairs. This is in preparation for capsicum. MFC after: 1 week
Diffstat (limited to 'sbin/hastd/proto_common.c')
-rw-r--r--sbin/hastd/proto_common.c75
1 files changed, 69 insertions, 6 deletions
diff --git a/sbin/hastd/proto_common.c b/sbin/hastd/proto_common.c
index 89c637d..d638d3b 100644
--- a/sbin/hastd/proto_common.c
+++ b/sbin/hastd/proto_common.c
@@ -46,18 +46,18 @@ __FBSDID("$FreeBSD$");
#endif
int
-proto_common_send(int fd, const unsigned char *data, size_t size)
+proto_common_send(int sock, const unsigned char *data, size_t size)
{
ssize_t done;
size_t sendsize;
- PJDLOG_ASSERT(fd >= 0);
+ PJDLOG_ASSERT(sock >= 0);
PJDLOG_ASSERT(data != NULL);
PJDLOG_ASSERT(size > 0);
do {
sendsize = size < MAX_SEND_SIZE ? size : MAX_SEND_SIZE;
- done = send(fd, data, sendsize, MSG_NOSIGNAL);
+ done = send(sock, data, sendsize, MSG_NOSIGNAL);
if (done == 0)
return (ENOTCONN);
else if (done < 0) {
@@ -73,16 +73,16 @@ proto_common_send(int fd, const unsigned char *data, size_t size)
}
int
-proto_common_recv(int fd, unsigned char *data, size_t size)
+proto_common_recv(int sock, unsigned char *data, size_t size)
{
ssize_t done;
- PJDLOG_ASSERT(fd >= 0);
+ PJDLOG_ASSERT(sock >= 0);
PJDLOG_ASSERT(data != NULL);
PJDLOG_ASSERT(size > 0);
do {
- done = recv(fd, data, size, MSG_WAITALL);
+ done = recv(sock, data, size, MSG_WAITALL);
} while (done == -1 && errno == EINTR);
if (done == 0)
return (ENOTCONN);
@@ -90,3 +90,66 @@ proto_common_recv(int fd, unsigned char *data, size_t size)
return (errno);
return (0);
}
+
+int
+proto_common_descriptor_send(int sock, int fd)
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(fd))];
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+
+ PJDLOG_ASSERT(sock >= 0);
+ PJDLOG_ASSERT(fd >= 0);
+
+ bzero(&msg, sizeof(msg));
+ bzero(&ctrl, sizeof(ctrl));
+
+ msg.msg_iov = NULL;
+ msg.msg_iovlen = 0;
+ msg.msg_control = ctrl;
+ msg.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ *((int *)CMSG_DATA(cmsg)) = fd;
+
+ if (sendmsg(sock, &msg, 0) == -1)
+ return (errno);
+
+ return (0);
+}
+
+int
+proto_common_descriptor_recv(int sock, int *fdp)
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(*fdp))];
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+
+ PJDLOG_ASSERT(sock >= 0);
+ PJDLOG_ASSERT(fdp != NULL);
+
+ bzero(&msg, sizeof(msg));
+ bzero(&ctrl, sizeof(ctrl));
+
+ msg.msg_iov = NULL;
+ msg.msg_iovlen = 0;
+ msg.msg_control = ctrl;
+ msg.msg_controllen = sizeof(ctrl);
+
+ if (recvmsg(sock, &msg, 0) == -1)
+ return (errno);
+
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_RIGHTS) {
+ *fdp = *((int *)CMSG_DATA(cmsg));
+ return (0);
+ }
+ }
+
+ return (ENOENT);
+}
OpenPOWER on IntegriCloud