1
/***************************************************************************
2
* libancillary - black magic on Unix domain sockets
4
* fd_send.c - receiving file descriptors
5
***************************************************************************/
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions are met:
11
* 1. Redistributions of source code must retain the above copyright notice,
12
* this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
* 3. The name of the author may not be used to endorse or promote products
17
* derived from this software without specific prior written permission.
19
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
20
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
22
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
#ifndef _XPG4_2 /* Solaris sucks */
36
#include <sys/types.h>
37
#include <sys/socket.h>
40
#if defined(__FreeBSD__)
41
# include <sys/param.h> /* FreeBSD sucks */
44
#include "ancillary.h"
47
ancil_recv_fds_with_buffer(int sock, int *fds, unsigned n_fds, void *buffer)
51
struct iovec nothing_ptr;
55
nothing_ptr.iov_base = ¬hing;
56
nothing_ptr.iov_len = 1;
57
msghdr.msg_name = NULL;
58
msghdr.msg_namelen = 0;
59
msghdr.msg_iov = ¬hing_ptr;
60
msghdr.msg_iovlen = 1;
62
msghdr.msg_control = buffer;
63
msghdr.msg_controllen = sizeof(struct cmsghdr) + sizeof(int) * n_fds;
64
cmsg = CMSG_FIRSTHDR(&msghdr);
65
cmsg->cmsg_len = msghdr.msg_controllen;
66
cmsg->cmsg_level = SOL_SOCKET;
67
cmsg->cmsg_type = SCM_RIGHTS;
68
for(i = 0; i < n_fds; i++)
69
((int *)CMSG_DATA(cmsg))[i] = -1;
71
if(recvmsg(sock, &msghdr, 0) < 0)
73
for(i = 0; i < n_fds; i++)
74
fds[i] = ((int *)CMSG_DATA(cmsg))[i];
75
n_fds = (cmsg->cmsg_len - sizeof(struct cmsghdr)) / sizeof(int);
79
#ifndef SPARE_RECV_FDS
81
ancil_recv_fds(int sock, int *fd, unsigned n_fds)
83
ANCIL_FD_BUFFER(ANCIL_MAX_N_FDS) buffer;
85
assert(n_fds <= ANCIL_MAX_N_FDS);
86
return(ancil_recv_fds_with_buffer(sock, fd, n_fds, &buffer));
88
#endif /* SPARE_RECV_FDS */
92
ancil_recv_fd(int sock, int *fd)
94
ANCIL_FD_BUFFER(1) buffer;
96
return(ancil_recv_fds_with_buffer(sock, fd, 1, &buffer) == 1 ? 0 : -1);
98
#endif /* SPARE_RECV_FD */