]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/TypedMsgHdr.cc
Merge from trunk. Remove dead files and fluff changes
[thirdparty/squid.git] / src / ipc / TypedMsgHdr.cc
1 /*
2 * $Id$
3 *
4 * DEBUG: section 54 Interprocess Communication
5 *
6 */
7
8
9 #include "config.h"
10 #include <string.h>
11 #include "protos.h"
12 #include "base/TextException.h"
13 #include "ipc/TypedMsgHdr.h"
14
15 Ipc::TypedMsgHdr::TypedMsgHdr()
16 {
17 xmemset(this, 0, sizeof(*this));
18 sync();
19 }
20
21 Ipc::TypedMsgHdr::TypedMsgHdr(const TypedMsgHdr &tmh)
22 {
23 memcpy(this, &tmh, sizeof(*this));
24 sync();
25 }
26
27 Ipc::TypedMsgHdr &Ipc::TypedMsgHdr::operator =(const TypedMsgHdr &tmh)
28 {
29 if (this != &tmh) { // skip assignment to self
30 memcpy(this, &tmh, sizeof(*this));
31 sync();
32 }
33 return *this;
34 }
35
36 // update msghdr and ios pointers based on msghdr counters
37 void Ipc::TypedMsgHdr::sync()
38 {
39 if (msg_name) { // we have a name
40 msg_name = &name;
41 } else {
42 Must(!msg_namelen && !msg_name);
43 }
44
45 if (msg_iov) { // we have a data component
46 Must(msg_iovlen == 1);
47 msg_iov = ios;
48 ios[0].iov_base = &data;
49 Must(ios[0].iov_len == sizeof(data));
50 } else {
51 Must(!msg_iovlen && !msg_iov);
52 }
53
54 if (msg_control) { // we have a control component
55 Must(msg_controllen > 0);
56 msg_control = &ctrl;
57 } else {
58 Must(!msg_controllen && !msg_control);
59 }
60 offset = 0;
61 }
62
63
64
65 int
66 Ipc::TypedMsgHdr::type() const
67 {
68 Must(msg_iovlen == 1);
69 return data.type_;
70 }
71
72 void
73 Ipc::TypedMsgHdr::address(const struct sockaddr_un& addr)
74 {
75 allocName();
76 name = addr;
77 msg_name = &name;
78 msg_namelen = SUN_LEN(&name);
79 }
80
81 void
82 Ipc::TypedMsgHdr::checkType(int destType) const
83 {
84 Must(type() == destType);
85 }
86
87 void
88 Ipc::TypedMsgHdr::setType(int aType)
89 {
90 if (data.type_) {
91 Must(data.type_ == aType);
92 } else {
93 allocData();
94 data.type_ = aType;
95 }
96 }
97
98 int
99 Ipc::TypedMsgHdr::getInt() const
100 {
101 int n = 0;
102 getPod(n);
103 return n;
104 }
105
106 void
107 Ipc::TypedMsgHdr::putInt(const int n)
108 {
109 putPod(n);
110 }
111
112 void
113 Ipc::TypedMsgHdr::getString(String &s) const
114 {
115 const int length = getInt();
116 Must(length >= 0);
117 // String uses memcpy uncoditionally; TODO: SBuf eliminates this check
118 if (!length) {
119 s.clean();
120 return;
121 }
122
123 Must(length <= maxSize);
124 // TODO: use SBuf.reserve() instead of a temporary buffer
125 char buf[maxSize];
126 getRaw(&buf, length);
127 s.limitInit(buf, length);
128 }
129
130 void
131 Ipc::TypedMsgHdr::putString(const String &s)
132 {
133 Must(s.psize() <= maxSize);
134 putInt(s.psize());
135 putRaw(s.rawBuf(), s.psize());
136 }
137
138 void
139 Ipc::TypedMsgHdr::getFixed(void *raw, size_t size) const
140 {
141 // no need to load size because it is constant
142 getRaw(raw, size);
143 }
144
145 void
146 Ipc::TypedMsgHdr::putFixed(const void *raw, size_t size)
147 {
148 // no need to store size because it is constant
149 putRaw(raw, size);
150 }
151
152 /// low-level loading of exactly size bytes of raw data
153 void
154 Ipc::TypedMsgHdr::getRaw(void *raw, size_t size) const
155 {
156 if (size > 0) {
157 Must(size <= data.size - offset);
158 memcpy(raw, data.raw + offset, size);
159 offset += size;
160 }
161 }
162
163 /// low-level storage of exactly size bytes of raw data
164 void
165 Ipc::TypedMsgHdr::putRaw(const void *raw, size_t size)
166 {
167 if (size > 0) {
168 Must(size <= sizeof(data.raw) - data.size);
169 memcpy(data.raw + data.size, raw, size);
170 data.size += size;
171 }
172 }
173
174 void
175 Ipc::TypedMsgHdr::putFd(int fd)
176 {
177 Must(fd >= 0);
178 allocControl();
179
180 const int fdCount = 1;
181
182 struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
183 cmsg->cmsg_level = SOL_SOCKET;
184 cmsg->cmsg_type = SCM_RIGHTS;
185 cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fdCount);
186
187 int *fdStore = reinterpret_cast<int*>(CMSG_DATA(cmsg));
188 memcpy(fdStore, &fd, fdCount * sizeof(int));
189 msg_controllen = cmsg->cmsg_len;
190 }
191
192 int
193 Ipc::TypedMsgHdr::getFd() const
194 {
195 Must(msg_control && msg_controllen);
196
197 struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
198 Must(cmsg->cmsg_level == SOL_SOCKET);
199 Must(cmsg->cmsg_type == SCM_RIGHTS);
200
201 const int fdCount = 1;
202 const int *fdStore = reinterpret_cast<const int*>(CMSG_DATA(cmsg));
203 int fd = -1;
204 memcpy(&fd, fdStore, fdCount * sizeof(int));
205 return fd;
206 }
207
208 void
209 Ipc::TypedMsgHdr::prepForReading()
210 {
211 xmemset(this, 0, sizeof(*this));
212 allocName();
213 allocData();
214 allocControl();
215 }
216
217 /// initialize io vector with one io record
218 void
219 Ipc::TypedMsgHdr::allocData()
220 {
221 Must(!msg_iovlen && !msg_iov);
222 msg_iovlen = 1;
223 msg_iov = ios;
224 ios[0].iov_base = &data;
225 ios[0].iov_len = sizeof(data);
226 data.type_ = 0;
227 data.size = 0;
228 }
229
230 void
231 Ipc::TypedMsgHdr::allocName()
232 {
233 Must(!msg_name && !msg_namelen);
234 msg_name = &name;
235 msg_namelen = sizeof(name); // is that the right size?
236 }
237
238 void
239 Ipc::TypedMsgHdr::allocControl()
240 {
241 Must(!msg_control && !msg_controllen);
242 msg_control = &ctrl;
243 msg_controllen = sizeof(ctrl);
244 }