fdpass.c revision 165d0aa06624a02a29adf56f031b555b5fd64771
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen/*
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen fdpass.c - FD passing
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen Copyright (c) 2002 Timo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen Permission is hereby granted, free of charge, to any person obtaining
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen a copy of this software and associated documentation files (the
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen "Software"), to deal in the Software without restriction, including
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen without limitation the rights to use, copy, modify, merge, publish,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen distribute, sublicense, and/or sell copies of the Software, and to
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen permit persons to whom the Software is furnished to do so, subject to
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen the following conditions:
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen The above copyright notice and this permission notice shall be
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen included in all copies or substantial portions of the Software.
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen*/
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#define _XPG4_2
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "lib.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "network.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include "fdpass.h"
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include <sys/un.h>
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#include <sys/uio.h>
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#ifndef CMSG_SPACE
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen# define CMSG_ALIGN(len) \
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen (((len) + sizeof(size_t) - 1) & ~(sizeof(size_t) - 1))
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen# define CMSG_SPACE(len) \
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen (CMSG_ALIGN(len) + CMSG_ALIGN(sizeof(struct cmsghdr)))
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen# define CMSG_LEN(len) \
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen#endif
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenint fd_send(int handle, int send_fd, const void *data, size_t size)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct msghdr msg;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct iovec iov;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct cmsghdr *cmsg;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen int *fdptr;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen char buf[CMSG_SPACE(sizeof(int))];
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen i_assert(size < SSIZE_T_MAX);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen memset(&msg, 0, sizeof (struct msghdr));
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen iov.iov_base = (void *) data;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen iov.iov_len = size;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen msg.msg_control = buf;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen msg.msg_controllen = sizeof(buf);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen msg.msg_iov = &iov;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen msg.msg_iovlen = 1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cmsg = CMSG_FIRSTHDR(&msg);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cmsg->cmsg_level = SOL_SOCKET;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cmsg->cmsg_type = SCM_RIGHTS;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cmsg->cmsg_len = CMSG_LEN(sizeof(int));
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen fdptr = (int *) CMSG_DATA(cmsg);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen *fdptr = send_fd;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return sendmsg(handle, &msg, 0);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainenint fd_read(int handle, void *data, size_t size, int *fd)
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen{
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct msghdr msg;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct iovec iov;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen struct cmsghdr *cmsg;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen int ret;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen char buf[CMSG_SPACE(sizeof(int))];
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen i_assert(size < SSIZE_T_MAX);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen memset(&msg, 0, sizeof (struct msghdr));
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen msg.msg_control = buf;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen msg.msg_controllen = sizeof(buf);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen msg.msg_iov = &iov;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen msg.msg_iovlen = 1;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cmsg = CMSG_FIRSTHDR(&msg);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cmsg->cmsg_level = SOL_SOCKET;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen cmsg->cmsg_type = SCM_RIGHTS;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen iov.iov_base = data;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen iov.iov_len = size;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen ret = recvmsg(handle, &msg, 0);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen *fd = *(int *) CMSG_DATA(cmsg);
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen return ret;
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen}
c6a57378d3c54988f525f81e19c0c5d132a0770dTimo Sirainen