]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ipc/mem/Segment.cc
Moved ipc/SharedMemory to ipc/mem/ and renamed it to Ipc::Mem::Segment.
[thirdparty/squid.git] / src / ipc / mem / Segment.cc
1 /*
2 * $Id$
3 *
4 * DEBUG: section 54 Interprocess Communication
5 *
6 */
7
8 #include "config.h"
9
10 #include "ipc/mem/Segment.h"
11 #include "protos.h"
12
13 #include <fcntl.h>
14 #include <sys/mman.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 #include <unistd.h>
18
19 Ipc::Mem::Segment::Segment(const char *const id):
20 theName(GenerateName(id)), theFD(-1), theSize(-1), theMem(NULL)
21 {
22 }
23
24 Ipc::Mem::Segment::~Segment() {
25 if (theFD >= 0) {
26 detach();
27 if (close(theFD) != 0)
28 debugs(54, 5, HERE << "close: " << xstrerror());
29 }
30 }
31
32 void
33 Ipc::Mem::Segment::create(const int aSize)
34 {
35 assert(aSize > 0);
36 assert(theFD < 0);
37
38 theFD = shm_open(theName.termedBuf(), O_CREAT | O_RDWR | O_TRUNC,
39 S_IRUSR | S_IWUSR);
40 if (theFD < 0) {
41 debugs(54, 5, HERE << "shm_open: " << xstrerror());
42 fatal("Ipc::Mem::Segment::create failed to shm_open");
43 }
44
45 if (ftruncate(theFD, aSize)) {
46 debugs(54, 5, HERE << "ftruncate: " << xstrerror());
47 fatal("Ipc::Mem::Segment::create failed to ftruncate");
48 }
49
50 theSize = aSize;
51
52 attach();
53 }
54
55 void
56 Ipc::Mem::Segment::open()
57 {
58 assert(theFD < 0);
59
60 theFD = shm_open(theName.termedBuf(), O_RDWR, 0);
61 if (theFD < 0) {
62 debugs(54, 5, HERE << "shm_open: " << xstrerror());
63 String s = "Ipc::Mem::Segment::open failed to shm_open";
64 s.append(theName);
65 fatal(s.termedBuf());
66 }
67
68 {
69 struct stat s;
70 memset(&s, 0, sizeof(s));
71 if (fstat(theFD, &s)) {
72 debugs(54, 5, HERE << "fstat: " << xstrerror());
73 String s = "Ipc::Mem::Segment::open failed to fstat";
74 s.append(theName);
75 fatal(s.termedBuf());
76 }
77
78 theSize = s.st_size;
79 }
80
81 attach();
82 }
83
84 /// Map the shared memory segment to the process memory space.
85 void
86 Ipc::Mem::Segment::attach()
87 {
88 assert(theFD >= 0);
89 assert(theSize >= 0);
90 assert(!theMem);
91
92 void *const p =
93 mmap(NULL, theSize, PROT_READ | PROT_WRITE, MAP_SHARED, theFD, 0);
94 if (p == MAP_FAILED) {
95 debugs(54, 5, HERE << "mmap: " << xstrerror());
96 fatal("Ipc::Mem::Segment::attach failed to mmap");
97 }
98 theMem = p;
99 }
100
101 /// Unmap the shared memory segment from the process memory space.
102 void
103 Ipc::Mem::Segment::detach()
104 {
105 if (!theMem)
106 return;
107
108 if (munmap(theMem, theSize)) {
109 debugs(54, 5, HERE << "munmap: " << xstrerror());
110 fatal("Ipc::Mem::Segment::detach failed to munmap");
111 }
112 theMem = 0;
113 }
114
115 /// Generate name for shared memory segment. Replaces all slashes with dots.
116 String
117 Ipc::Mem::Segment::GenerateName(const char *id)
118 {
119 String name("/squid-");
120 for (const char *slash = strchr(id, '/'); slash; slash = strchr(id, '/')) {
121 if (id != slash) {
122 name.append(id, slash - id);
123 name.append('.');
124 }
125 id = slash + 1;
126 }
127 name.append(id);
128 return name;
129 }