-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfdrightsrecv.c
88 lines (78 loc) · 1.95 KB
/
fdrightsrecv.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/* $Id: fdrights.c,v 3.6 2009/10/16 15:41:17 ksb Exp $
* $Compile: ${cc-cc} ${cc_debug--O} -DTEST %f -o %F
* $Compile: ${cc-cc} ${cc_debug--O} -DTEST %f -o %F -lsocket
* $Test: date > /tmp/test && ./%F
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/uio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include "fdrights.h"
#if !defined(USE_STRINGS)
#define USE_STRINGS (defined(bsd))
#endif
#include "machine.h"
char acRightsRecvBuf[RIGHTS_TAG_LINE];
/* Receive an array of descriptors through a unix domain socket (bj)
* return -1 on error, 0 on success
*/
int
RightsRecvFd(s, piFds, iFdCount, pcText, piTextLen)
int s;
int *piFds;
unsigned iFdCount;
char *pcText;
size_t *piTextLen;
{
int error;
struct msghdr msg;
struct iovec iov;
#if HAVE_SCM_RIGHTS
struct cmsghdr *pcmsg;
int iLen;
iLen = sizeof(struct cmsghdr) + sizeof(int)*iFdCount;
if ((struct cmsghdr *)0 == (pcmsg = (struct cmsghdr *) malloc(iLen))) {
errno = ENOMEM;
return -1;
}
pcmsg->cmsg_len = iLen;
pcmsg->cmsg_level = SOL_SOCKET;
pcmsg->cmsg_type = SCM_RIGHTS;
msg.msg_control = (caddr_t) pcmsg;
msg.msg_controllen = pcmsg->cmsg_len;
#else
msg.msg_accrights = (caddr_t) piFds;
msg.msg_accrightslen = sizeof(int) * iFdCount;
#endif /* HAVE_SCM_RIGHTS */
/* no name (assume socket is connected */
msg.msg_name = (char *)0;
msg.msg_namelen = 0;
/* some sync data data and our file descriptors */
if ((char *)0 != pcText) {
iov.iov_base = pcText;
iov.iov_len = (size_t *)0 == piTextLen ? 0 : *piTextLen;
} else {
iov.iov_base = acRightsRecvBuf;
iov.iov_len = sizeof(acRightsRecvBuf);
}
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
error = recvmsg(s, &msg, 0);
#if HAVE_SCM_RIGHTS
{
int e = errno;
#if USE_STRINGS
bcopy(pcmsg+1, piFds, sizeof(int)*iFdCount);
#else
memcpy(piFds, pcmsg+1, sizeof(int)*iFdCount);
#endif
free((char *) pcmsg);
errno = e;
}
#endif /* HAVE_SCM_RIGHTS */
return error;
}