00001 #include "rcs_defs.hh"
00002 #include "_shm.h"
00003 #include "rcs_prnt.hh"
00004 #include "dbg_mem.h"
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifdef WIN32
00016
00017 #include <windows.h>
00018
00019 #ifndef NO_STDIO
00020 #include <stdio.h>
00021 #endif
00022
00023 #ifdef UNDER_CE
00024 #include "rcs_ce.h"
00025 #endif
00026
00027 shm_t *
00028 rcs_shm_open (key_t key, size_t size, int oflag, ...)
00029 {
00030 shm_t *shm;
00031 char name[64];
00032 #ifdef UNICODE
00033 wchar_t wname[64];
00034 #endif
00035 #ifndef UNDER_CE
00036 SECURITY_ATTRIBUTES sa;
00037 SECURITY_DESCRIPTOR sd;
00038 #endif
00039
00040 rcs_print_debug (PRINT_SHARED_MEMORY_ACTIVITY,
00041 "rcs_shm_open(key=%d(0x%X),size=%d(0x%X),oflag=%d)\n",
00042 key, key, size, size, oflag);
00043
00044 if (key < 1)
00045 {
00046 rcs_print_error ("rcs_shm_open(%d(0x%X), %d(0x%X), %d(0x%X)): error\n",
00047 key, key, size, size, oflag, oflag);
00048 rcs_print_error ("RCS Shared Memory key may not be zero.\n");
00049 return NULL;
00050 }
00051 #ifndef UNDER_CE
00052 if (FALSE ==
00053 InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION))
00054 {
00055 rcs_print_error
00056 ("Can not initailize security descriptor.(Error = %d)\n",
00057 GetLastError ());
00058 return NULL;
00059 }
00060 sa.nLength = sizeof (SECURITY_ATTRIBUTES);
00061 sa.lpSecurityDescriptor = &sd;
00062 sa.bInheritHandle = TRUE;
00063 #endif
00064
00065 #ifndef NO_STDIO
00066 sprintf (name, "shm%d", key);
00067 #else
00068 strcpy (name, "shm");
00069 _itoa (key, name + 3, 10);
00070 #endif
00071
00072
00073 shm = (shm_t *) DEBUG_MALLOC (sizeof (shm_t));
00074 if (NULL == shm)
00075 {
00076 rcs_print_error ("Out of memory.\n");
00077 return NULL;
00078 }
00079 memset (shm, 0, sizeof (shm_t));
00080 if (oflag)
00081 {
00082 shm->created = 1;
00083 #ifdef UNDER_CE
00084 #ifdef UNICODE
00085 RCS_CE_ASCII_TO_UNICODE (wname, name, 64);
00086 shm->hFileMap =
00087 CreateFileMapping ((HANDLE) (0xFFFFFFFF), NULL, PAGE_READWRITE, 0,
00088 size, wname);
00089 #else
00090 shm->hFileMap =
00091 CreateFileMapping ((HANDLE) (0xFFFFFFFF), NULL, PAGE_READWRITE, 0,
00092 size, name);
00093 #endif
00094 #else
00095 shm->hFileMap =
00096 CreateFileMapping ((HANDLE) (0xFFFFFFFF), &sa, PAGE_READWRITE, 0,
00097 size, name);
00098 #endif
00099 if (NULL == shm->hFileMap)
00100 {
00101 rcs_print_error ("CreateFileMapping( failed!! (Error = %d)\n",
00102 GetLastError ());
00103 DEBUG_FREE (shm);
00104 return NULL;
00105 }
00106 if ((shm->hFileMap != NULL) &&
00107 (GetLastError () == ERROR_ALREADY_EXISTS))
00108 {
00109 rcs_print_error ("File mapping name conflict, name = %s\n", name);;
00110 CloseHandle (shm->hFileMap);
00111 DEBUG_FREE (shm);
00112 return NULL;
00113 }
00114 }
00115 else
00116 {
00117 #ifdef UNDER_CE
00118 #ifdef UNICODE
00119 RCS_CE_ASCII_TO_UNICODE (wname, name, 64);
00120 shm->hFileMap =
00121 CreateFileMapping ((HANDLE) (0xFFFFFFFF), NULL, PAGE_READWRITE, 0,
00122 size, wname);
00123 #else
00124 shm->hFileMap =
00125 CreateFileMapping ((HANDLE) (0xFFFFFFFF), NULL, PAGE_READWRITE, 0,
00126 size, name);
00127 #endif
00128 if (NULL == shm->hFileMap)
00129 {
00130 rcs_print_error ("CreateFileMapping( failed!! (Error = %d)\n",
00131 GetLastError ());
00132 DEBUG_FREE (shm);
00133 return NULL;
00134 }
00135 #else
00136 shm->hFileMap = OpenFileMapping (FILE_MAP_ALL_ACCESS, TRUE, name);
00137 if (NULL == shm->hFileMap)
00138 {
00139 rcs_print_error ("OpenFileMapping failed!! (Error = %d)\n",
00140 GetLastError ());
00141 DEBUG_FREE (shm);
00142 return NULL;
00143 }
00144 #endif
00145 }
00146
00147 shm->addr = MapViewOfFile (shm->hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, size);
00148 if (NULL == shm->addr)
00149 {
00150 rcs_print_error ("MapViewOfFile failed!! (Error = %d)\n",
00151 GetLastError ());
00152 CloseHandle (shm->hFileMap);
00153 DEBUG_FREE (shm);
00154 return NULL;
00155 }
00156 return shm;
00157 }
00158
00159
00160 int
00161 rcs_shm_close (shm_t * shm)
00162 {
00163 rcs_print_debug (PRINT_SHARED_MEMORY_ACTIVITY,
00164 "rcs_shm_close(shm->key=%d(0x%X),shm->size=%d(0x%X),shm->addr=0x%X)\n",
00165 shm->key, shm->key, shm->size, shm->size, shm->addr);
00166
00167 if (shm != NULL)
00168 {
00169 if (shm->hFileMap != NULL)
00170 {
00171 UnmapViewOfFile (shm->addr);
00172 CloseHandle (shm->hFileMap);
00173 shm->addr = NULL;
00174 shm->hFileMap = NULL;
00175 }
00176 }
00177 return 0;
00178 }
00179
00180 int
00181 rcs_shm_delete (shm_t * shm)
00182 {
00183 return rcs_shm_close (shm);
00184 }
00185
00186
00187
00188 int
00189 rcs_shm_nattch (shm_t * shm)
00190 {
00191
00192
00193
00194 return 1;
00195 }
00196
00197
00198
00199
00200
00201
00202 #else
00203
00204
00205 #if defined (VXWORKS)
00206
00207
00208
00209 #include <vxWorks.h>
00210 #include <taskLib.h>
00211
00212 #ifndef NO_STDIO
00213 #include <stdio.h>
00214 #endif
00215 #include <stdlib.h>
00216 #include "_table.h"
00217
00218
00219
00220 _RCS_TABLE rcs_shm_table;
00221 int rcs_shm_table_inited = 0;
00222 int task_lock_shm_stuff = 1;
00223 int print_rcs_shm_warnings = 0;
00224
00225
00226
00227
00228
00229 void
00230 rcs_shm_table_print ()
00231 {
00232 if (!rcs_shm_table_inited)
00233 {
00234 printf ("RCS Shared Memory table NOT initialized.\n");
00235 return;
00236 }
00237 table_print (&rcs_shm_table);
00238 printf ("\t\tid\tkey\taddr\terrno\tsize\tcount\n");
00239 }
00240
00241 void
00242 rcs_shm_table_clear ()
00243 {
00244 if (task_lock_shm_stuff)
00245 taskLock ();
00246 rcs_shm_table_inited = 0;
00247 table_clearall (&rcs_shm_table);
00248 if (task_lock_shm_stuff)
00249 taskUnlock ();
00250 }
00251
00252
00253
00254 shm_t *
00255 rcs_shm_open (key_t key, size_t size, int oflag, ...)
00256 {
00257 int tid = taskIdSelf ();
00258 shm_t *shm;
00259
00260 rcs_print_debug (PRINT_SHARED_MEMORY_ACTIVITY,
00261 "rcs_shm_open(key=%d(0x%X),size=%d(0x%X),oflag=%d)\n",
00262 key, key, size, size, oflag);
00263
00264 if (task_lock_shm_stuff)
00265 taskLock ();
00266
00267
00268
00269 if (key == 0)
00270 {
00271 if (task_lock_shm_stuff)
00272 taskUnlock ();
00273 rcs_print_error ("rcs_shm_open(%d(0x%X), %d(0x%X), %d(0x%X)): error\n",
00274 key, key, size, size, oflag, oflag);
00275 rcs_print_error ("RCS Shared Memory key is zero.\n");
00276 return NULL;
00277 }
00278
00279
00280 shm = (shm_t *) DEBUG_CALLOC (sizeof (shm_t), 1);
00281 shm->id = (int) key;
00282 shm->addr = NULL;
00283 shm->size = -1;
00284 shm->created = 0;
00285
00286
00287 if (oflag)
00288 {
00289 if (rcs_shm_table_inited)
00290 {
00291 if (table_get (&rcs_shm_table, key, shm) >= 0)
00292 {
00293
00294 if (shm->id != key)
00295 {
00296 if (task_lock_shm_stuff)
00297 taskUnlock ();
00298 rcs_print_error
00299 ("Shared Memory Key retrieved from table does not match. (%d) != (%d).\n",
00300 key, shm->id);
00301 return NULL;
00302 }
00303 if (shm->addr <= 0)
00304 {
00305 if (task_lock_shm_stuff)
00306 taskUnlock ();
00307 return NULL;
00308 }
00309 shm->count++;
00310 table_add (&rcs_shm_table, key, shm);
00311 if (task_lock_shm_stuff)
00312 taskUnlock ();
00313 if (shm->size < size)
00314 {
00315 rcs_print_error
00316 ("This process(%d(0x%X)) was configured to create a shared memory area with key = (%d(0x%X)) and size=(%d(0x%X)\n",
00317 tid, tid, key, key, size, size);
00318 rcs_print_error
00319 (" but a shared memory area with this key and a size of only (%d(0x%X)) already exists.",
00320 shm->size, shm->size);
00321 return NULL;
00322 }
00323 if (print_rcs_shm_warnings)
00324 {
00325 rcs_print_error
00326 ("Warning: This process(%d(0x%X)) was configured to create a shared memory area with key = (%d(0x%X)), and size=(%d(0x%X)\n",
00327 tid, tid, key, key, size, size);
00328 rcs_print_error
00329 ("Warning: but a shared memory area with this key has already been created.\n");
00330 rcs_print_error ("\n");
00331 }
00332 return shm;
00333 }
00334 }
00335 shm->addr = (void *) DEBUG_MALLOC (size);
00336 shm->size = size;
00337 shm->id = key;
00338 shm->count = 1;
00339 shm->created = 1;
00340 if (!rcs_shm_table_inited)
00341 {
00342
00343 table_new (&rcs_shm_table, sizeof (shm_t));
00344 rcs_shm_table_inited = 1;
00345 }
00346 table_add (&rcs_shm_table, key, shm);
00347 }
00348 else
00349 {
00350
00351 if (!rcs_shm_table_inited)
00352 {
00353 #if 0
00354 shm->addr = (void *) DEBUG_CALLOC (size, 1);
00355 shm->size = size;
00356 shm->count = 1;
00357 shm->id = key;
00358 if (!rcs_shm_table_inited)
00359 {
00360
00361 table_new (&rcs_shm_table, sizeof (shm_t));
00362 rcs_shm_table_inited = 1;
00363 }
00364 table_add (&rcs_shm_table, key, shm);
00365 if (task_lock_shm_stuff)
00366 taskUnlock ();
00367
00368 if (print_rcs_shm_warnings)
00369 {
00370 rcs_print_error
00371 ("Warning: RCS Shared Memory Area table contains no entry for (%d(0x%X)), creating one.\n",
00372 key, key);
00373 }
00374 #endif
00375 shm->create_errno = ENOENT;
00376 return shm;
00377 }
00378 else
00379 {
00380 if (table_get (&rcs_shm_table, key, shm) < 0)
00381 {
00382 #if 0
00383 shm->addr = (void *) DEBUG_CALLOC (size, 1);
00384 shm->size = size;
00385 shm->count = 1;
00386 shm->id = key;
00387 if (!rcs_shm_table_inited)
00388 {
00389
00390 table_new (&rcs_shm_table, sizeof (shm_t));
00391 rcs_shm_table_inited = 1;
00392 }
00393 table_add (&rcs_shm_table, key, shm);
00394 if (task_lock_shm_stuff)
00395 taskUnlock ();
00396
00397 if (print_rcs_shm_warnings)
00398 {
00399 rcs_print_error
00400 ("Warning: RCS Shared Memory Area table contains no entry for (%d(0x%X)), creating one.\n",
00401 key, key);
00402 }
00403 #endif
00404 shm->create_errno = ENOENT;
00405 return shm;
00406 }
00407 if (shm->id != key)
00408 {
00409 if (task_lock_shm_stuff)
00410 taskUnlock ();
00411 rcs_print_error
00412 ("Shared Memory Key retrieved from table does not match. (%d) != (%d).\n",
00413 key, shm->id);
00414 return NULL;
00415 }
00416 if (shm->addr <= 0)
00417 {
00418 if (task_lock_shm_stuff)
00419 taskUnlock ();
00420 return NULL;
00421 }
00422 if (shm->size < size)
00423 {
00424 if (task_lock_shm_stuff)
00425 taskUnlock ();
00426 rcs_print_error
00427 ("This process(%d(0x%X)) was configured to connect a shared memory area with key = (%d(0x%X)) and size=(%d(0x%X)\n",
00428 tid, tid, key, key, size, size);
00429 rcs_print_error
00430 (" but a shared memory area with this key and a size of only (%d(0x%X)) already exists.",
00431 shm->size, shm->size);
00432 return NULL;
00433 }
00434 shm->count++;
00435 table_add (&rcs_shm_table, key, shm);
00436
00437 }
00438 }
00439
00440 if (task_lock_shm_stuff)
00441 taskUnlock ();
00442
00443 return shm;
00444 }
00445
00446 int
00447 rcs_shm_close (shm_t * shm)
00448 {
00449 shm_t entry;
00450
00451 rcs_print_debug (PRINT_SHARED_MEMORY_ACTIVITY,
00452 "rcs_shm_close(shm->key=%d(0x%X),shm->size=%d(0x%X),shm->addr=0x%X)\n",
00453 shm->key, shm->key, shm->size, shm->size, shm->addr);
00454
00455 if (task_lock_shm_stuff)
00456 taskLock ();
00457
00458
00459
00460
00461 table_get (&rcs_shm_table, shm->id, &entry);
00462 entry.count--;
00463 if (entry.count == 0 && entry.addr != NULL)
00464 {
00465 DEBUG_FREE (entry.addr);
00466 entry.addr = NULL;
00467 shm->addr = NULL;
00468 table_clear (&rcs_shm_table, shm->id);
00469 }
00470 else
00471 {
00472
00473 table_add (&rcs_shm_table, shm->id, &entry);
00474 }
00475
00476 if (task_lock_shm_stuff)
00477 taskUnlock ();
00478 DEBUG_FREE (shm);
00479 return 0;
00480 }
00481
00482 int
00483 rcs_shm_delete (shm_t * shm)
00484 {
00485 shm_t entry;
00486
00487 if (task_lock_shm_stuff)
00488 taskLock ();
00489
00490
00491
00492 table_get (&rcs_shm_table, shm->id, &entry);
00493 entry.count--;
00494 if (entry.addr != NULL)
00495 {
00496 DEBUG_FREE (entry.addr);
00497 entry.addr = NULL;
00498 shm->addr = NULL;
00499 table_clear (&rcs_shm_table, shm->id);
00500 }
00501 else
00502 {
00503
00504 table_add (&rcs_shm_table, shm->id, &entry);
00505 }
00506
00507 if (task_lock_shm_stuff)
00508 taskUnlock ();
00509
00510 DEBUG_FREE (shm);
00511 return 0;
00512 }
00513
00514 int
00515 rcs_shm_nattch (shm_t * shm)
00516 {
00517 shm_t entry;
00518
00519 if (task_lock_shm_stuff)
00520 taskLock ();
00521
00522 table_get (&rcs_shm_table, shm->id, &entry);
00523 shm->count = entry.count;
00524 if (task_lock_shm_stuff)
00525 taskUnlock ();
00526 return shm->count;
00527 }
00528
00529 #else
00530
00531
00532
00533 #ifndef NO_STDIO
00534 #include <stdio.h>
00535 #endif
00536
00537 #ifdef linux_2_4
00538 #include <linux/posix_types.h>
00539 #endif
00540
00541 #include <stdlib.h>
00542 #ifdef __CENTERLINE__
00543 #define USING_VARARGS
00544 #include <varargs.h>
00545 #else
00546 #include <stdarg.h>
00547 #endif
00548 #include <errno.h>
00549 #include <stddef.h>
00550 #include <sys/types.h>
00551 #include <unistd.h>
00552 #include <sys/ipc.h>
00553 #if defined(qnx) && !defined(USE_POSIX_SHAREDMEM)
00554 #define USE_POSIX_SHAREDMEM 1
00555 #endif
00556 #ifdef USE_POSIX_SHAREDMEM
00557 #include <fcntl.h>
00558 #include <sys/mman.h>
00559 #else
00560 #include <sys/shm.h>
00561 #endif
00562 #include <string.h>
00563
00564 static int shmems_created_list[100];
00565 static int shmems_created_list_initialized = 0;
00566
00567 shm_t *
00568 rcs_shm_open (key_t key, size_t size, int oflag, ...)
00569 {
00570 va_list ap;
00571 int mode;
00572 int shmflg = 0;
00573 shm_t *shm;
00574 #ifdef USE_POSIX_SHAREDMEM
00575 int existed_before = 0;
00576 rcs_print_debug (PRINT_SHARED_MEMORY_ACTIVITY,
00577 "rcs_shm_open(key=%d(0x%X),size=%d(0x%X),oflag=%d)\n",
00578 key, key, size, size, oflag);
00579
00580 if (key == 0)
00581 {
00582 rcs_print_error ("rcs_shm_open(%d(0x%X), %d(0x%X), %d(0x%X)): error\n",
00583 key, key, size, size, oflag, oflag);
00584 rcs_print_error ("RCS Shared Memory key may not be zero.\n");
00585 return NULL;
00586 }
00587
00588 shm = (shm_t *) DEBUG_CALLOC (sizeof (shm_t), 1);
00589 if (NULL == shm)
00590 {
00591 rcs_print_error ("rcs_shm_open: calloc failed\n");
00592 return NULL;
00593 }
00594 shm->create_errno = 0;
00595 shm->addr = NULL;
00596 shm->key = key;
00597 shm->size = size;
00598 sprintf (shm->name, "/rcs_shm%d", key);
00599 shm->id = 0;
00600 errno = 0;
00601
00602
00603 #if defined(IPC_CREAT)
00604 #if O_CREAT != IPC_CREAT
00605 if ((oflag & IPC_CREAT) && !(oflag & O_CREAT))
00606 {
00607 oflag &= ~(IPC_CREAT);
00608 oflag |= O_CREAT;
00609 }
00610 #endif
00611 #endif
00612
00613 if ((oflag & O_CREAT))
00614 {
00615 shm->id = shm_open (shm->name, O_RDWR, mode);
00616 if (shm->id > 0)
00617 {
00618 shm->created = 0;
00619 existed_before = 1;
00620 }
00621 }
00622
00623
00624 if (shm->id <= 0)
00625 {
00626 shm->id = shm_open (shm->name, oflag | O_RDWR, mode);
00627 if (shm->id == -1)
00628 {
00629 rcs_print_error ("shm_open(%s,%d(0x%X),%d(0x%X)) failed:%s %d\n",
00630 shm->name, oflag | O_RDWR, oflag | O_RDWR,
00631 mode, mode, strerror (errno), errno);
00632 shm->create_errno = errno;
00633 return shm;
00634 }
00635 shm->created = 1;
00636 existed_before = 0;
00637 }
00638
00639
00640 if (ftruncate (shm->id, size + 16) == -1)
00641 {
00642 rcs_print_error ("ftruncate(%d,%d): %s %d\n",
00643 shm->id, size, strerror (errno), errno);
00644 shm->create_errno = errno;
00645 return shm;
00646 }
00647
00648
00649 shm->addr = mmap (0, size + 16,
00650 PROT_READ | PROT_WRITE, MAP_SHARED, shm->id, 0);
00651 if (shm->addr == MAP_FAILED)
00652 {
00653 rcs_print_error
00654 ("mmap(0,%d,PROT_READ | PROT_WRITE, MAP_SHARED,%d,0) failed: %s %d\n",
00655 shm->id, size, strerror (errno), errno);
00656 shm->create_errno = errno;
00657 }
00658 if (oflag & O_CREAT && !existed_before)
00659 {
00660 *((int *) ((char *) shm->addr + size)) = 0;
00661 }
00662 else
00663 {
00664 (*((int *) ((char *) shm->addr + size)))++;
00665 }
00666
00667 return (shm);
00668 #else
00669
00670 struct shmid_ds shared_mem_info;
00671 int pid;
00672 int i;
00673
00674 rcs_print_debug (PRINT_SHARED_MEMORY_ACTIVITY,
00675 "rcs_shm_open(key=%d(0x%X),size=%d(0x%X),oflag=%d)\n",
00676 key, key, size, size, oflag);
00677
00678 if (key == 0)
00679 {
00680 rcs_print_error ("rcs_shm_open(%d(0x%X), %d(0x%X), %d(0x%X)): error\n",
00681 key, key, size, size, oflag, oflag);
00682 rcs_print_error ("RCS Shared Memory key may not be zero.\n");
00683 return NULL;
00684 }
00685
00686 #if defined(O_CREAT)
00687 #if O_CREAT != IPC_CREAT
00688 if ((oflag & O_CREAT) && !(oflag & IPC_CREAT))
00689 {
00690 oflag &= ~(O_CREAT);
00691 oflag |= IPC_CREAT;
00692 }
00693 #endif
00694 #endif
00695
00696 if (oflag)
00697 {
00698 shmflg |= IPC_CREAT;
00699 }
00700 if (shmflg & IPC_CREAT)
00701 {
00702 #ifdef USING_VARARGS
00703 va_start (ap);
00704 #else
00705 va_start (ap, oflag);
00706 #endif
00707 mode = va_arg (ap, int);
00708 shmflg |= mode;
00709 }
00710
00711 shm = (shm_t *) DEBUG_CALLOC (sizeof (shm_t), 1);
00712 if (NULL == shm)
00713 {
00714 rcs_print_error ("rcs_shm_open: calloc failed\n");
00715 return NULL;
00716 }
00717 shm->create_errno = 0;
00718 shm->addr = NULL;
00719 shm->key = key;
00720 errno = 0;
00721
00722 if ((shm->id = shmget (key, (int) size, shmflg)) == -1)
00723 {
00724 shm->create_errno = errno;
00725 rcs_print_error ("shmget(%d(0x%X),%d,%d) failed: (errno = %d): %s\n",
00726 key, key, size, shmflg, errno, strerror (errno));
00727 switch (errno)
00728 {
00729 case EEXIST:
00730 rcs_print_error
00731 ("A shared memory buffer for this key already exists.\n");
00732 break;
00733
00734 case EINVAL:
00735 rcs_print_error
00736 ("Either the size is too big or the shared memory buffer already exists but is of the wrong size.\n");
00737 break;
00738
00739 case ENOSPC:
00740 rcs_print_error
00741 ("The system imposed limit on the maximum number of shared memory segments has been exceeded.\n");
00742 break;
00743 }
00744 return (shm);
00745 }
00746
00747
00748 shmflg = 0;
00749 shmflg &= ~SHM_RDONLY;
00750 if ((shm->addr = (void *) shmat (shm->id, 0, shmflg)) == (void *) -1)
00751 {
00752 shm->create_errno = errno;
00753 rcs_print_error ("shmat(%d,0,%d) failed:(errno = %d): %s\n", shm->id,
00754 shmflg, errno, strerror (errno));
00755 rcs_print_error ("key = %d (0x%X)\n", key, key);
00756 shm->addr = NULL;
00757 return (shm);
00758 }
00759
00760
00761 if (shmctl (shm->id, IPC_STAT, &shared_mem_info) < 0)
00762 {
00763 rcs_print_error ("shmctl error: %d %s\n", errno, strerror (errno));
00764 return shm;
00765 }
00766
00767
00768 if (!oflag)
00769 {
00770 return shm;
00771 }
00772
00773 if (!shmems_created_list_initialized)
00774 {
00775 memset (shmems_created_list, 0, 100 * sizeof (int));
00776 shmems_created_list_initialized = 1;
00777 }
00778 else
00779 {
00780 for (i = 0; i < 100; i++)
00781 {
00782 if (shmems_created_list[i] == key)
00783 {
00784 return shm;
00785 }
00786 }
00787 }
00788
00789 pid = (int) getpid ();
00790 if (pid <= 0)
00791 {
00792 rcs_print_error ("getpid error: %d %s\n", errno, strerror (errno));
00793 return shm;
00794 }
00795 shm->created = (shared_mem_info.shm_cpid == pid);
00796 #if defined(darwin) || defined(linux_2_4_0)
00797 shm->created = 1;
00798 #endif
00799
00800 if (shm->created)
00801 {
00802 for (i = 0; i < 100; i++)
00803 {
00804 if (shmems_created_list[i] <= 0)
00805 {
00806 shmems_created_list[i] = shm->key;
00807 break;
00808 }
00809 }
00810 }
00811 return shm;
00812 #endif
00813 }
00814
00815 int
00816 rcs_shm_close (shm_t * shm)
00817 {
00818 #ifdef USE_POSIX_SHAREDMEM
00819 if (shm == 0)
00820 {
00821 return -1;
00822 }
00823 if (shm->addr > 0)
00824 {
00825 (*((int *) ((char *) shm->addr + shm->size)))--;
00826 if (munmap (shm->addr, shm->size + 16) == -1)
00827 {
00828 rcs_print_error ("munmap(%p,%d) failed. %s %d\n",
00829 shm->addr, shm->size, strerror (errno), errno);
00830 return -1;
00831 }
00832 shm->addr = NULL;
00833 if (shm->id > 0)
00834 {
00835 if (close (shm->id) == -1)
00836 {
00837 rcs_print_error ("close(%d) failed. %s %d\n",
00838 shm->id, strerror (errno), errno);
00839 }
00840 }
00841 shm->id = 0;
00842 }
00843 #else
00844 struct shmid_ds shm_ds;
00845 int i;
00846
00847
00848 if (shm == NULL)
00849 return -1;
00850
00851 rcs_print_debug (PRINT_SHARED_MEMORY_ACTIVITY,
00852 "rcs_shm_close(shm->key=%d(0x%X),shm->size=%d(0x%X),shm->addr=0x%X)\n",
00853 shm->key, shm->key, shm->size, shm->size, shm->addr);
00854
00855
00856 shmdt ((char *) shm->addr);
00857
00858
00859 if (rcs_shm_nattch (shm) == 0)
00860 {
00861 shmctl (shm->id, IPC_RMID, &shm_ds);
00862 }
00863
00864 if (shm->created && shmems_created_list_initialized)
00865 {
00866 for (i = 0; i < 100; i++)
00867 {
00868 if (shmems_created_list[i] == shm->key)
00869 {
00870 shmems_created_list[i] = 0;
00871 break;
00872 }
00873 }
00874 }
00875
00876 #endif
00877
00878
00879 #ifdef sparcworks_sun4
00880
00881 DEBUG_FREE ((char *) shm);
00882 #else
00883 DEBUG_FREE (shm);
00884 #endif
00885
00886 return 0;
00887 }
00888
00889 int
00890 rcs_shm_delete (shm_t * shm)
00891 {
00892 #ifdef USE_POSIX_SHAREDMEM
00893 if (shm == 0)
00894 {
00895 return -1;
00896 }
00897 if (shm->addr > 0)
00898 {
00899 (*((int *) ((char *) shm->addr + shm->size)))--;
00900 if (munmap (shm->addr, shm->size + 16) == -1)
00901 {
00902 rcs_print_error ("munmap(%p,%d) failed. %s %d\n",
00903 shm->addr, shm->size, strerror (errno), errno);
00904 return -1;
00905 }
00906 shm->addr = NULL;
00907 if (shm->id > 0)
00908 {
00909 if (close (shm->id) == -1)
00910 {
00911 rcs_print_error ("close(%d) failed. %s %d\n",
00912 shm->id, strerror (errno), errno);
00913 }
00914 }
00915 shm->id = 0;
00916 }
00917 shm_unlink (shm->name);
00918 #else
00919 struct shmid_ds shm_ds;
00920
00921
00922 if (shm == NULL)
00923 return -1;
00924
00925
00926 shmdt ((char *) shm->addr);
00927
00928
00929 shmctl (shm->id, IPC_RMID, &shm_ds);
00930 #endif
00931
00932
00933 #ifdef sparcworks_sun4
00934
00935 DEBUG_FREE ((char *) shm);
00936 #else
00937 DEBUG_FREE (shm);
00938 #endif
00939
00940 return 0;
00941 }
00942
00943 int
00944 rcs_shm_nattch (shm_t * shm)
00945 {
00946 #ifdef USE_POSIX_SHAREDMEM
00947 if (shm == 0)
00948 {
00949 return -1;
00950 }
00951 if (shm->addr == 0)
00952 {
00953 return -1;
00954 }
00955 return *((int *) (((char *) shm->addr) + shm->size));
00956 #else
00957 struct shmid_ds shm_ds;
00958
00959
00960 if (shm == NULL)
00961 return -1;
00962
00963
00964 shmctl (shm->id, IPC_STAT, &shm_ds);
00965
00966 return shm_ds.shm_nattch;
00967 #endif
00968
00969 }
00970
00971 #endif
00972
00973 #endif