]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/TypedMsgHdr.cc
2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 54 Interprocess Communication */
12 #include "base/TextException.h"
13 #include "ipc/TypedMsgHdr.h"
14 #include "SquidString.h"
19 Ipc::TypedMsgHdr::TypedMsgHdr()
25 Ipc::TypedMsgHdr::TypedMsgHdr(const TypedMsgHdr
&tmh
)
31 Ipc::TypedMsgHdr
&Ipc::TypedMsgHdr::operator =(const TypedMsgHdr
&tmh
)
33 if (this != &tmh
) { // skip assignment to self
34 memcpy(static_cast<msghdr
*>(this), static_cast<const msghdr
*>(&tmh
), sizeof(msghdr
));
36 memcpy(&ios
, &tmh
.ios
, sizeof(ios
));
46 Ipc::TypedMsgHdr::clear()
48 // may be called from the constructor, with object fields uninitialized
49 memset(static_cast<msghdr
*>(this), 0, sizeof(msghdr
));
50 memset(&name
, 0, sizeof(name
));
51 memset(&ios
, 0, sizeof(ios
));
57 // update msghdr and ios pointers based on msghdr counters
58 void Ipc::TypedMsgHdr::sync()
60 if (msg_name
) { // we have a name
63 Must(!msg_namelen
&& !msg_name
);
66 if (msg_iov
) { // we have a data component
67 Must(msg_iovlen
== 1);
69 ios
[0].iov_base
= &data
;
70 Must(ios
[0].iov_len
== sizeof(data
));
72 Must(!msg_iovlen
&& !msg_iov
);
75 if (msg_control
) { // we have a control component
76 Must(msg_controllen
> 0);
79 Must(!msg_controllen
&& !msg_control
);
85 Ipc::TypedMsgHdr::type() const
87 Must(msg_iovlen
== 1);
92 Ipc::TypedMsgHdr::address(const struct sockaddr_un
& addr
)
97 msg_namelen
= SUN_LEN(&name
);
101 Ipc::TypedMsgHdr::checkType(int destType
) const
103 Must(type() == destType
);
107 Ipc::TypedMsgHdr::setType(int aType
)
110 Must(data
.type_
== aType
);
118 Ipc::TypedMsgHdr::getInt() const
126 Ipc::TypedMsgHdr::putInt(const int n
)
132 Ipc::TypedMsgHdr::getString(String
&s
) const
134 const int length
= getInt();
136 // String uses memcpy uncoditionally; TODO: SBuf eliminates this check
142 Must(length
<= maxSize
);
143 // TODO: use SBuf.reserve() instead of a temporary buffer
145 getRaw(&buf
, length
);
146 s
.assign(buf
, length
);
150 Ipc::TypedMsgHdr::putString(const String
&s
)
152 Must(s
.psize() <= maxSize
);
154 putRaw(s
.rawBuf(), s
.psize());
158 Ipc::TypedMsgHdr::getFixed(void *rawBuf
, size_t rawSize
) const
160 // no need to load size because it is constant
161 getRaw(rawBuf
, rawSize
);
165 Ipc::TypedMsgHdr::putFixed(const void *rawBuf
, size_t rawSize
)
167 // no need to store size because it is constant
168 putRaw(rawBuf
, rawSize
);
171 /// low-level loading of exactly size bytes of raw data
173 Ipc::TypedMsgHdr::getRaw(void *rawBuf
, size_t rawSize
) const
176 Must(rawSize
<= data
.size
- offset
);
177 memcpy(rawBuf
, data
.raw
+ offset
, rawSize
);
182 /// low-level storage of exactly size bytes of raw data
184 Ipc::TypedMsgHdr::putRaw(const void *rawBuf
, size_t rawSize
)
187 Must(rawSize
<= sizeof(data
.raw
) - data
.size
);
188 memcpy(data
.raw
+ data
.size
, rawBuf
, rawSize
);
189 data
.size
+= rawSize
;
194 Ipc::TypedMsgHdr::hasFd() const
196 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(this);
198 cmsg
->cmsg_level
== SOL_SOCKET
&&
199 cmsg
->cmsg_type
== SCM_RIGHTS
;
203 Ipc::TypedMsgHdr::putFd(int fd
)
209 const int fdCount
= 1;
211 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(this);
212 cmsg
->cmsg_level
= SOL_SOCKET
;
213 cmsg
->cmsg_type
= SCM_RIGHTS
;
214 cmsg
->cmsg_len
= CMSG_LEN(sizeof(int) * fdCount
);
216 int *fdStore
= reinterpret_cast<int*>(SQUID_CMSG_DATA(cmsg
));
217 memcpy(fdStore
, &fd
, fdCount
* sizeof(int));
218 msg_controllen
= cmsg
->cmsg_len
;
224 Ipc::TypedMsgHdr::getFd() const
226 Must(msg_control
&& msg_controllen
);
229 struct cmsghdr
*cmsg
= CMSG_FIRSTHDR(this);
230 Must(cmsg
->cmsg_level
== SOL_SOCKET
);
231 Must(cmsg
->cmsg_type
== SCM_RIGHTS
);
233 const int fdCount
= 1;
234 const int *fdStore
= reinterpret_cast<const int*>(SQUID_CMSG_DATA(cmsg
));
236 memcpy(&fd
, fdStore
, fdCount
* sizeof(int));
241 Ipc::TypedMsgHdr::prepForReading()
244 // no sync() like other clear() calls because the
245 // alloc*() below "sync()" the parts they allocate.
251 /// initialize io vector with one io record
253 Ipc::TypedMsgHdr::allocData()
255 Must(!msg_iovlen
&& !msg_iov
);
258 ios
[0].iov_base
= &data
;
259 ios
[0].iov_len
= sizeof(data
);
265 Ipc::TypedMsgHdr::allocName()
267 Must(!msg_name
&& !msg_namelen
);
269 msg_namelen
= sizeof(name
); // is that the right size?
273 Ipc::TypedMsgHdr::allocControl()
275 Must(!msg_control
&& !msg_controllen
);
277 msg_controllen
= sizeof(ctrl
);