]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/fdmover.cpp
Security-163.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / fdmover.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // ip++ - C++ layer for IP socket and address management
21 //
22 // [Also see comments in header file.]
23 //
24 #include "fdmover.h"
25 #include <iterator>
26 #include <Security/debugging.h>
27
28
29 namespace Security {
30 namespace IPPlusPlus {
31
32
33 void *FdMover::Element::operator new (size_t base, size_t more)
34 {
35 Element *element = (Element *)::malloc(CMSG_SPACE(more));
36 element->cmsg_len = CMSG_LEN(more);
37 return element;
38 }
39
40 void FdMover::Element::operator delete (void *data, size_t base)
41 {
42 ::free(data);
43 }
44
45 FdMover::Element::Element(int level, int type)
46 {
47 cmsg_level = level;
48 cmsg_type = type;
49 }
50
51
52 FdMover::Message::Message(const void *data, size_t length)
53 : iovec(data, length)
54 {
55 msg_name = NULL;
56 msg_namelen = 0;
57 msg_iov = &iovec;
58 msg_iovlen = 1;
59 msg_control = NULL;
60 msg_controllen = 0;
61 msg_flags = 0;
62 }
63
64 void FdMover::Message::set(Element *elem)
65 {
66 msg_control = (caddr_t)elem;
67 msg_controllen = elem->cmsg_len;
68 }
69
70
71 size_t FdMover::send(const void *data, size_t length, const FdVector &fds)
72 {
73 auto_ptr<Element> elem(new (fds.size() * sizeof(int)) Element (SOL_SOCKET, SCM_RIGHTS));
74 copy(fds.begin(), fds.end(), &elem.get()->payload<int>());
75 Message msg(data, length);
76 msg.set(elem.get());
77 ssize_t rc = ::sendmsg(fd(), &msg, 0);
78 checkError(rc);
79 return rc;
80 }
81
82
83 size_t FdMover::receive(void *data, size_t length, FdVector &fds)
84 {
85 static const int maxFds = 20; // arbitrary limit
86 Message msg(data, length);
87 auto_ptr<Element> elem(new (maxFds * sizeof(int)) Element);
88 msg.set(elem.get());
89 ssize_t rc = ::recvmsg(fd(), &msg, 0);
90 checkError(rc);
91 unsigned count = elem.get()->payloadSize() / sizeof(int);
92 FdVector result;
93 copy(&elem.get()->payload<int>(), &elem.get()->payload<int>() + count, back_inserter(result));
94 swap(fds, result);
95 return rc;
96 }
97
98
99 } // end namespace IPPlusPlus
100 } // end namespace Security