]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ipc/TypedMsgHdr.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / src / ipc / TypedMsgHdr.cc
CommitLineData
98d9bd29
AR
1/*
2 * $Id$
3 *
4 * DEBUG: section 54 Interprocess Communication
5 *
6 */
7
8
f7f3304a 9#include "squid.h"
98d9bd29 10#include <string.h>
a67d2b2e
AR
11#include "protos.h"
12#include "base/TextException.h"
98d9bd29
AR
13#include "ipc/TypedMsgHdr.h"
14
15Ipc::TypedMsgHdr::TypedMsgHdr()
16{
5667a628
AR
17 xmemset(this, 0, sizeof(*this));
18 sync();
98d9bd29
AR
19}
20
21Ipc::TypedMsgHdr::TypedMsgHdr(const TypedMsgHdr &tmh)
22{
41d00cd3 23 memcpy(this, &tmh, sizeof(*this));
5667a628 24 sync();
98d9bd29
AR
25}
26
27Ipc::TypedMsgHdr &Ipc::TypedMsgHdr::operator =(const TypedMsgHdr &tmh)
28{
5667a628 29 if (this != &tmh) { // skip assignment to self
41d00cd3 30 memcpy(this, &tmh, sizeof(*this));
5667a628
AR
31 sync();
32 }
33 return *this;
98d9bd29
AR
34}
35
36// update msghdr and ios pointers based on msghdr counters
37void Ipc::TypedMsgHdr::sync()
38{
5667a628
AR
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 }
8822ebee 60 offset = 0;
98d9bd29
AR
61}
62
63
64
65int
66Ipc::TypedMsgHdr::type() const
67{
5667a628
AR
68 Must(msg_iovlen == 1);
69 return data.type_;
98d9bd29
AR
70}
71
72void
73Ipc::TypedMsgHdr::address(const struct sockaddr_un& addr)
74{
5667a628
AR
75 allocName();
76 name = addr;
98d9bd29
AR
77 msg_name = &name;
78 msg_namelen = SUN_LEN(&name);
79}
80
81void
8822ebee 82Ipc::TypedMsgHdr::checkType(int destType) const
98d9bd29 83{
5667a628 84 Must(type() == destType);
98d9bd29
AR
85}
86
87void
8822ebee 88Ipc::TypedMsgHdr::setType(int aType)
98d9bd29 89{
8822ebee
AR
90 if (data.type_) {
91 Must(data.type_ == aType);
92 } else {
93 allocData();
94 data.type_ = aType;
95 }
96}
97
98int
99Ipc::TypedMsgHdr::getInt() const
100{
101 int n = 0;
102 getPod(n);
103 return n;
104}
105
106void
107Ipc::TypedMsgHdr::putInt(const int n)
108{
109 putPod(n);
110}
111
112void
113Ipc::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
f867ba6b 125 char buf[maxSize];
8822ebee
AR
126 getRaw(&buf, length);
127 s.limitInit(buf, length);
128}
129
130void
131Ipc::TypedMsgHdr::putString(const String &s)
132{
133 Must(s.psize() <= maxSize);
134 putInt(s.psize());
135 putRaw(s.rawBuf(), s.psize());
136}
137
138void
139Ipc::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
145void
146Ipc::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
153void
154Ipc::TypedMsgHdr::getRaw(void *raw, size_t size) const
155{
8822ebee
AR
156 if (size > 0) {
157 Must(size <= data.size - offset);
41d00cd3 158 memcpy(raw, data.raw + offset, size);
8822ebee
AR
159 offset += size;
160 }
161}
162
163/// low-level storage of exactly size bytes of raw data
164void
165Ipc::TypedMsgHdr::putRaw(const void *raw, size_t size)
166{
8822ebee
AR
167 if (size > 0) {
168 Must(size <= sizeof(data.raw) - data.size);
41d00cd3 169 memcpy(data.raw + data.size, raw, size);
8822ebee
AR
170 data.size += size;
171 }
98d9bd29
AR
172}
173
174void
175Ipc::TypedMsgHdr::putFd(int fd)
176{
5667a628
AR
177 Must(fd >= 0);
178 allocControl();
98d9bd29 179
5667a628 180 const int fdCount = 1;
98d9bd29 181
5667a628
AR
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);
98d9bd29
AR
186
187 int *fdStore = reinterpret_cast<int*>(CMSG_DATA(cmsg));
41d00cd3 188 memcpy(fdStore, &fd, fdCount * sizeof(int));
98d9bd29
AR
189 msg_controllen = cmsg->cmsg_len;
190}
191
192int
193Ipc::TypedMsgHdr::getFd() const
194{
5667a628 195 Must(msg_control && msg_controllen);
98d9bd29 196
5667a628
AR
197 struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
198 Must(cmsg->cmsg_level == SOL_SOCKET);
199 Must(cmsg->cmsg_type == SCM_RIGHTS);
98d9bd29 200
5667a628 201 const int fdCount = 1;
98d9bd29 202 const int *fdStore = reinterpret_cast<const int*>(CMSG_DATA(cmsg));
5667a628 203 int fd = -1;
41d00cd3 204 memcpy(&fd, fdStore, fdCount * sizeof(int));
5667a628 205 return fd;
98d9bd29
AR
206}
207
208void
209Ipc::TypedMsgHdr::prepForReading()
210{
5667a628
AR
211 xmemset(this, 0, sizeof(*this));
212 allocName();
213 allocData();
214 allocControl();
98d9bd29
AR
215}
216
217/// initialize io vector with one io record
218void
219Ipc::TypedMsgHdr::allocData()
220{
5667a628
AR
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;
98d9bd29
AR
228}
229
230void
231Ipc::TypedMsgHdr::allocName()
232{
5667a628 233 Must(!msg_name && !msg_namelen);
98d9bd29
AR
234 msg_name = &name;
235 msg_namelen = sizeof(name); // is that the right size?
236}
237
238void
239Ipc::TypedMsgHdr::allocControl()
240{
5667a628
AR
241 Must(!msg_control && !msg_controllen);
242 msg_control = &ctrl;
243 msg_controllen = sizeof(ctrl);
98d9bd29 244}