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