]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Added previously forgotten sources.
authorAlex Rousskov <rousskov@measurement-factory.com>
Sat, 1 May 2010 23:47:46 +0000 (17:47 -0600)
committerAlex Rousskov <rousskov@measurement-factory.com>
Sat, 1 May 2010 23:47:46 +0000 (17:47 -0600)
src/ipc/TypedMsgHdr.cc [new file with mode: 0644]
src/ipc/TypedMsgHdr.h [new file with mode: 0644]

diff --git a/src/ipc/TypedMsgHdr.cc b/src/ipc/TypedMsgHdr.cc
new file mode 100644 (file)
index 0000000..b596b80
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+
+#include "config.h"
+#include <string.h>
+#include "TextException.h"
+#include "ipc/TypedMsgHdr.h"
+
+Ipc::TypedMsgHdr::TypedMsgHdr()
+{
+       xmemset(this, 0, sizeof(*this));
+       sync();
+}
+
+Ipc::TypedMsgHdr::TypedMsgHdr(const TypedMsgHdr &tmh)
+{
+       xmemcpy(this, &tmh, sizeof(*this));
+       sync();
+}
+
+Ipc::TypedMsgHdr &Ipc::TypedMsgHdr::operator =(const TypedMsgHdr &tmh)
+{
+       if (this != &tmh) { // skip assignment to self
+               xmemcpy(this, &tmh, sizeof(*this));
+               sync();
+       }
+       return *this;
+}
+
+// update msghdr and ios pointers based on msghdr counters
+void Ipc::TypedMsgHdr::sync()
+{
+       if (msg_name) { // we have a name
+               msg_name = &name;
+       } else {
+               Must(!msg_namelen && !msg_name);
+       }
+
+       if (msg_iov) { // we have a data component
+               Must(msg_iovlen == 1);
+               msg_iov = ios;
+               ios[0].iov_base = &data;
+               Must(ios[0].iov_len == sizeof(data));
+       } else {
+               Must(!msg_iovlen && !msg_iov);
+       }
+
+       if (msg_control) { // we have a control component
+               Must(msg_controllen > 0);
+               msg_control = &ctrl;
+       } else {
+               Must(!msg_controllen && !msg_control);
+       }
+}
+
+
+
+int
+Ipc::TypedMsgHdr::type() const
+{
+       Must(msg_iovlen == 1);
+       return data.type_;
+}
+
+void
+Ipc::TypedMsgHdr::address(const struct sockaddr_un& addr)
+{
+       allocName();
+       name = addr;
+    msg_name = &name;
+    msg_namelen = SUN_LEN(&name);
+}
+
+void
+Ipc::TypedMsgHdr::getData(int destType, void *raw, size_t size) const
+{
+       Must(type() == destType);
+       Must(size == data.size);
+       xmemcpy(raw, data.raw, size);
+}
+
+void
+Ipc::TypedMsgHdr::putData(int aType, const void *raw, size_t size)
+{
+       Must(size <= sizeof(data.raw));
+       allocData();
+       data.type_ = aType;
+       data.size = size;
+       xmemcpy(data.raw, raw, size);
+}
+
+void
+Ipc::TypedMsgHdr::putFd(int fd)
+{
+       Must(fd >= 0);
+       allocControl();
+
+       const int fdCount = 1;
+
+       struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
+       cmsg->cmsg_level = SOL_SOCKET;
+       cmsg->cmsg_type = SCM_RIGHTS;
+       cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fdCount);
+
+    int *fdStore = reinterpret_cast<int*>(CMSG_DATA(cmsg));
+       xmemcpy(fdStore, &fd, fdCount * sizeof(int));
+    msg_controllen = cmsg->cmsg_len;
+}
+
+int
+Ipc::TypedMsgHdr::getFd() const
+{
+       Must(msg_control && msg_controllen);
+
+       struct cmsghdr *cmsg = CMSG_FIRSTHDR(this);
+       Must(cmsg->cmsg_level == SOL_SOCKET);
+       Must(cmsg->cmsg_type == SCM_RIGHTS);
+
+       const int fdCount = 1;
+    const int *fdStore = reinterpret_cast<const int*>(CMSG_DATA(cmsg));
+       int fd = -1;
+       xmemcpy(&fd, fdStore, fdCount * sizeof(int));
+       return fd;
+}
+
+void
+Ipc::TypedMsgHdr::prepForReading()
+{
+       xmemset(this, 0, sizeof(*this));
+       allocName();
+       allocData();
+       allocControl();
+}
+
+/// initialize io vector with one io record
+void
+Ipc::TypedMsgHdr::allocData()
+{
+       Must(!msg_iovlen && !msg_iov);
+       msg_iovlen = 1;
+       msg_iov = ios;
+       ios[0].iov_base = &data;
+       ios[0].iov_len = sizeof(data);
+       data.type_ = 0;
+       data.size = 0;
+}
+
+void
+Ipc::TypedMsgHdr::allocName()
+{
+       Must(!msg_name && !msg_namelen);
+    msg_name = &name;
+    msg_namelen = sizeof(name); // is that the right size?
+}
+
+void
+Ipc::TypedMsgHdr::allocControl()
+{
+       Must(!msg_control && !msg_controllen);
+       msg_control = &ctrl;
+       msg_controllen = sizeof(ctrl);
+}
diff --git a/src/ipc/TypedMsgHdr.h b/src/ipc/TypedMsgHdr.h
new file mode 100644 (file)
index 0000000..2ed2606
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * DEBUG: section 54    Interprocess Communication
+ *
+ */
+
+#ifndef SQUID_IPC_TYPED_MSG_HDR_H
+#define SQUID_IPC_TYPED_MSG_HDR_H
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
+namespace Ipc
+{
+
+/// struct msghdr with a known type, fixed-size I/O and control buffers
+class TypedMsgHdr: public msghdr
+{
+public:
+    TypedMsgHdr();
+    TypedMsgHdr(const TypedMsgHdr &tmh);
+    TypedMsgHdr &operator =(const TypedMsgHdr &tmh);
+
+    // type-safe access to message details
+    int type() const; ///< returns stored type or zero if none
+    void address(const struct sockaddr_un& addr); ///< sets [dest.] address
+    void getData(int ofType, void *raw, size_t size) const; ///< checks type
+    void putData(int aType, const void *raw, size_t size); ///< stores type
+       void putFd(int aFd); ///< stores descriptor
+       int getFd() const; ///< returns descriptor
+
+    /// raw, type-independent access for I/O
+       void prepForReading(); ///< reset and provide all buffers
+       char *raw() { return reinterpret_cast<char*>(this); }
+       const char *raw() const { return reinterpret_cast<const char*>(this); }
+    size_t size() const { return sizeof(*this); } ///< not true message size
+
+private:
+       void sync();
+       void allocData();
+       void allocName();
+       void allocControl();
+
+private:
+       struct sockaddr_un name; ///< same as .msg_name
+
+       struct iovec ios[1]; ///< same as .msg_iov[]
+
+       struct DataBuffer {
+               int type_; ///< Message kind, uses MessageType values
+               size_t size; ///< actual raw data size (for sanity checks)
+               char raw[250]; ///< buffer with type-specific data
+       } data; ///< same as .msg_iov[0].iov_base
+
+       struct CtrlBuffer {
+               char raw[CMSG_SPACE(sizeof(int))]; ///< control buffer space for one fd
+       } ctrl; ///< same as .msg_control
+};
+
+} // namespace Ipc
+
+#endif /* SQUID_IPC_TYPED_MSG_HDR_H */