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