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