This source file includes following definitions.
- create_shm
- open_shm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <limits.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/file.h>
27 #include <sys/mman.h>
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31
32 #include "../simh/sim_defs.h"
33 #include "shm.h"
34
35 #if defined(USE_FLOCK) && defined(USE_FCNTL)
36 # if !defined(USE_BFLOCK)
37 # define USE_BFLOCK
38 # endif
39 #endif
40
41 #if !defined(TRUE)
42 # define TRUE 1
43 #endif
44
45 #if !defined(FALSE)
46 # define FALSE 0
47 #endif
48
49 extern int sim_randstate;
50 extern int sim_randompst;
51 extern int sim_nostate;
52 extern int sim_iglock;
53 extern int sim_nolock;
54
55 const char *xstrerror_l(int errnum);
56
57 void *
58 create_shm(char *key, size_t shm_size)
59 {
60 void *p;
61 char buf[256];
62
63 #if defined(USE_BFLOCK)
64 char lck[260];
65 #endif
66
67 (void)sprintf (buf, "dps8m.%s", key);
68
69 #if defined(USE_BFLOCK)
70 (void)sprintf (lck, ".%s", buf);
71
72 int lck_fd = open(lck, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
73 if (lck_fd == -1)
74 {
75 (void)fprintf(stderr, "%s(): Failed to open \"%s\": %s (Error %d)\r\n",
76 __func__, lck, xstrerror_l(errno), errno);
77 return NULL;
78 }
79
80 if (sim_randstate && !sim_randompst)
81 {
82 unlink(lck);
83 }
84
85 #endif
86
87 int fd = open(buf, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
88 if (fd == -1)
89 {
90 (void)fprintf(stderr, "%s(): Failed to open \"%s\": %s (Error %d)\r\n",
91 __func__, buf, xstrerror_l(errno), errno);
92 #if defined(USE_BFLOCK)
93 (void)close(lck_fd);
94 #endif
95 return NULL;
96 }
97
98 if (sim_randstate && !sim_randompst)
99 {
100 unlink(buf);
101 }
102
103 #if defined(USE_BFLOCK)
104 # define SPIDLEN 128
105
106 # if !defined(HOST_NAME_MAX)
107 # if defined(_POSIX_HOST_NAME_MAX)
108 # define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
109 # else
110 # define HOST_NAME_MAX 255
111 # endif
112 # endif
113
114 struct flock bflock;
115 (void)memset(&bflock, 0, sizeof ( bflock ));
116 bflock.l_type = F_WRLCK;
117 int brc = 0;
118 if (!sim_nolock)
119 {
120 brc = fcntl(lck_fd, F_SETLK, &bflock);
121 }
122
123 int fct = 0;
124 char spid[SPIDLEN];
125 unsigned long lkpid = 0;
126 char sthostname[HOST_NAME_MAX + 1];
127 char shostname[HOST_NAME_MAX * 2];
128
129 int pch = 0;
130 int ypch = 0;
131 int lck_ftr = 0;
132 FILE *lck_fp;
133 if (brc < 0)
134 {
135 (void)fprintf(stderr, "%s(): Failed to lock \"%s\": %s (Error %d)\r\n",
136 __func__, lck, xstrerror_l(errno), errno);
137 if (!sim_nolock)
138 {
139 if (fcntl(lck_fd, F_GETLK, &bflock) == 0 && bflock.l_pid > 0)
140 {
141 lkpid = (unsigned long)bflock.l_pid;
142 }
143 }
144
145 # if !defined(__clang_analyzer__)
146 (void)close(lck_fd);
147 lck_ftr = 1;
148 lck_fp = fopen(lck, "r");
149 (void)fprintf(stderr, "\r\n*** Is another simulator running");
150 if (lck_fp != NULL)
151 {
152 while (( pch = fgetc(lck_fp)) != EOF || fct < SPIDLEN)
153 {
154 if (!( pch < 32 || pch > 126 ))
155 {
156 ypch++;
157 if (ypch == 1)
158 {
159 (void)fprintf(stderr, " as PID ");
160 }
161
162 (void)fprintf(stderr, "%c", pch);
163 }
164
165 fct++;
166 }
167 (void)fclose(lck_fp);
168 }
169 # endif
170
171 if (lkpid != 0 && ypch == 0)
172 {
173 (void)fprintf(stderr, " as PID %lu", lkpid);
174 }
175
176 (void)fprintf(stderr, "? ***\r\n\r\n");
177 if (!sim_iglock)
178 {
179 (void)close(fd);
180 return NULL;
181 }
182 }
183
184 if (!lck_ftr && (ftruncate(lck_fd, (off_t)0) == -1))
185 {
186 (void)fprintf(stderr, "%s(): Failed to clear \"%s\": %s (Error %d)\r\n",
187 __func__, lck, xstrerror_l(errno), errno);
188 if (!sim_iglock)
189 {
190 return NULL;
191 }
192 }
193
194 (void)snprintf(spid, SPIDLEN, "%ld ", (long)getpid());
195
196 (void)memset(&sthostname, 0, sizeof ( sthostname ));
197 int hrc = gethostname(sthostname, HOST_NAME_MAX + 1);
198 if (hrc != 0)
199 {
200 (void)sprintf (sthostname, "(unknown)");
201 }
202
203 (void)sprintf (shostname, "on %s\n", sthostname);
204 if (!lck_ftr && (write(lck_fd, spid, strlen(spid)) != strlen(spid)))
205 {
206 (void)fprintf(stderr, "%s(): Failed to save PID to \"%s\": %s (Error %d)\r\n",
207 __func__, lck, xstrerror_l(errno), errno);
208 if (!sim_iglock)
209 {
210 (void)close(fd);
211 (void)close(lck_fd);
212 return NULL;
213 }
214 }
215
216 if (!lck_ftr && !(sim_nostate))
217 (void)fsync(lck_fd);
218
219 if (!lck_ftr && (write(lck_fd, shostname, strlen(shostname)) != strlen(shostname)))
220 {
221 (void)fprintf(stderr, "%s(): Failed to save host to \"%s\": %s (Error %d)\r\n",
222 __func__, lck, xstrerror_l(errno), errno);
223 if (!sim_iglock)
224 {
225 (void)close(fd);
226 return NULL;
227 }
228 }
229
230 if (!lck_ftr && !(sim_nostate))
231 (void)fsync(lck_fd);
232 #endif
233
234 #if defined(USE_FLOCK)
235 int rc = 0;
236 if (!sim_nolock)
237 {
238 rc = flock(fd, LOCK_EX | LOCK_NB);
239 }
240
241 if (rc < 0)
242 {
243 (void)fprintf(stderr, "%s(): Failed to lock \"%s\": %s (Error %d)\r\n",
244 __func__, buf, xstrerror_l(errno), errno);
245 if (!sim_iglock)
246 {
247 return NULL;
248 }
249 }
250
251 #elif USE_FCNTL
252 struct flock lock;
253 (void)memset(&lock, 0, sizeof ( lock ));
254 lock.l_type = F_WRLCK;
255 int rc = 0;
256 if (!sim_nolock)
257 {
258 rc = fcntl(fd, F_SETLK, &lock);
259 }
260
261 if (rc < 0)
262 {
263 (void)fprintf(stderr, "%s(): Failed to lock \"%s\": %s (Error %d)\r\n",
264 __func__, buf, xstrerror_l(errno), errno);
265 if (fcntl(fd, F_GETLK, &lock) == FALSE && lock.l_pid > 0)
266 {
267 (void)fprintf(stderr,
268 "\r\n*** Is another simulator running as PID %lu? ***\r\n\r\n",
269 (unsigned long)lock.l_pid);
270 }
271 if (!sim_iglock)
272 {
273 return NULL;
274 }
275 }
276 #endif
277
278 if (ftruncate(fd, (off_t)shm_size) == -1)
279 {
280 (void)fprintf(stderr, "%s(): Failed to initialize \"%s\": %s (Error %d)\r\n",
281 __func__, buf, xstrerror_l(errno), errno);
282 return NULL;
283 }
284
285 p = mmap(NULL, shm_size, PROT_READ | PROT_WRITE,
286 #if defined(MAP_NOSYNC)
287 MAP_NOSYNC |
288 #endif
289 MAP_SHARED, fd, 0);
290 if (p == MAP_FAILED)
291 {
292 (void)fprintf(stderr, "%s(): Failed to memory map \"%s\": %s (Error %d)\r\n",
293 __func__, buf, xstrerror_l(errno), errno);
294 return NULL;
295 }
296
297 return p;
298 }
299
300 #if defined(API)
301 void *
302 open_shm(char *key, size_t shm_size)
303 {
304 void *p;
305 char buf[256];
306
307 # if defined(USE_BFLOCK)
308 char lck[260];
309 # endif
310
311 (void)sprintf (buf, "dps8m.%s", key);
312
313 # if defined(USE_BFLOCK)
314 (void)sprintf (lck, ".%s", buf);
315
316 int lck_fd = open(lck, O_RDWR, 0);
317 if (lck_fd == -1)
318 {
319 (void)fprintf(stderr, "%s(): Failed to open \"%s\": %s (Error %d)\r\n",
320 __func__, lck, xstrerror_l(errno), errno);
321 return NULL;
322 }
323 # endif
324
325 int fd = open(buf, O_RDWR, 0);
326 if (fd == -1)
327 {
328 (void)fprintf(stderr, "%s(); Failed to open \"%s\": %s (Error %d)\r\n",
329 __func__, buf, xstrerror_l(errno), errno);
330 return NULL;
331 }
332
333 # if defined(USE_BFLOCK)
334 struct flock bflock;
335 (void)memset(&bflock, 0, sizeof ( bflock ));
336 bflock.l_type = F_WRLCK;
337 int brc = 0;
338 if (!sim_nolock)
339 {
340 brc = fcntl(lck_fd, F_SETLK, &bflock);
341 }
342
343 if (brc < 0)
344 {
345 (void)fprintf(stderr, "%s(): Failed to lock \"%s\": %s (Error %d)\r\n",
346 __func__, lck, xstrerror_l(errno), errno);
347 if (!sim_iglock)
348 {
349 return NULL;
350 }
351 }
352 # endif
353
354 # if defined(USE_FLOCK)
355 int rc = 0;
356 if (!sim_nolock)
357 {
358 rc = flock(fd, LOCK_EX | LOCK_NB);
359 }
360
361 if (rc < 0)
362 {
363 (void)fprintf(stderr, "%s(): Failed to lock \"%s\": %s (Error %d)\r\n",
364 __func__, buf, xstrerror_l(errno), errno);
365 if(!sim_iglock) return NULL;
366 }
367
368 # elif defined(USE_FCNTL)
369 struct flock lock;
370 (void)memset(&lock, 0, sizeof ( lock ));
371 lock.l_type = F_WRLCK;
372 int rc = 0;
373 if (!sim_nolock)
374 {
375 rc = fcntl(fd, F_SETLK, &lock);
376 }
377
378 if (rc < 0)
379 {
380 (void)fprintf(stderr, "%s(): Failed to lock \"%s\": %s (Error %d)\r\n",
381 __func__, buf, xstrerror_l(errno), errno);
382 if (!sim_iglock)
383 {
384 return NULL;
385 }
386 }
387 # endif
388
389 p = mmap(NULL, size, PROT_READ | PROT_WRITE,
390 # if defined(MAP_NOSYNC)
391 MAP_NOSYNC |
392 # endif
393 MAP_SHARED, fd, 0);
394 if (p == MAP_FAILED)
395 {
396 # if defined(USE_FCNTL)
397 lock.l_type = F_UNLCK;
398 if (!sim_nolock)
399 {
400 (void)fcntl(fd, F_SETLK, &lock);
401 }
402
403 if ( !(sim_nostate) )
404 (void)fsync(fd);
405 (void)close(fd);
406 # endif
407
408 # if defined(USE_BFLOCK)
409 bflock.l_type = F_UNLCK;
410 if (!sim_nolock)
411 {
412 (void)fcntl(lck_fd, F_SETLK, &bflock);
413 }
414
415 if ( !(sim_nostate) )
416 (void)fsync(lck_fd);
417 (void)close(lck_fd);
418 # endif
419
420 (void)fprintf(stderr, "%s(): Failed to memory map \"%s\": %s (Error %d)\r\n",
421 __func__, buf, xstrerror_l(errno), errno);
422 return NULL;
423 }
424
425 return p;
426 }
427 #endif