-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfdrightssend.c
83 lines (74 loc) · 1.79 KB
/
fdrightssend.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
/* $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"
/* Send an array of descriptors through a unix domain socket. (bj)
* return -1 on error, 0 on success
*/
int
RightsSendFd(s, piFds, iFdCount, pcText)
int s;
int *piFds;
unsigned iFdCount;
char *pcText;
{
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;
#if USE_STRINGS
bcopy(piFds, pcmsg+1, sizeof(int)*iFdCount);
#else
memcpy(pcmsg+1, piFds, sizeof(int)*iFdCount);
#endif
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 */
if ((char *)0 == pcText) {
pcText = "ok";
}
msg.msg_name = (char *)0;
msg.msg_namelen = 0;
/* some sync data data and our file descriptors */
iov.iov_base = pcText;
iov.iov_len = strlen(pcText)+1;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
error = sendmsg(s, &msg, 0);
#if HAVE_SCM_RIGHTS
{
int e = errno;
free((char *) pcmsg);
errno = e;
}
#endif /* HAVE_SCM_RIGHTS */
return error;
}