nsprpub/pr/src/md/unix/uxshm.c

Wed, 31 Dec 2014 07:53:36 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:53:36 +0100
branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
permissions
-rw-r--r--

Correct small whitespace inconsistency, lost while renaming variables.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /*
michael@0 7 ** uxshm.c -- Unix Implementations NSPR Named Shared Memory
michael@0 8 **
michael@0 9 **
michael@0 10 ** lth. Jul-1999.
michael@0 11 **
michael@0 12 */
michael@0 13 #include <string.h>
michael@0 14 #include <prshm.h>
michael@0 15 #include <prerr.h>
michael@0 16 #include <prmem.h>
michael@0 17 #include "primpl.h"
michael@0 18 #include <fcntl.h>
michael@0 19
michael@0 20 extern PRLogModuleInfo *_pr_shm_lm;
michael@0 21
michael@0 22
michael@0 23 #define NSPR_IPC_SHM_KEY 'b'
michael@0 24 /*
michael@0 25 ** Implementation for System V
michael@0 26 */
michael@0 27 #if defined PR_HAVE_SYSV_NAMED_SHARED_MEMORY
michael@0 28 #include <sys/ipc.h>
michael@0 29 #include <sys/shm.h>
michael@0 30 #include <sys/types.h>
michael@0 31 #include <sys/stat.h>
michael@0 32
michael@0 33 #define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
michael@0 34 #define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
michael@0 35 #define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
michael@0 36 #define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
michael@0 37 #define _MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory
michael@0 38
michael@0 39 extern PRSharedMemory * _MD_OpenSharedMemory(
michael@0 40 const char *name,
michael@0 41 PRSize size,
michael@0 42 PRIntn flags,
michael@0 43 PRIntn mode
michael@0 44 )
michael@0 45 {
michael@0 46 PRStatus rc = PR_SUCCESS;
michael@0 47 key_t key;
michael@0 48 PRSharedMemory *shm;
michael@0 49 char ipcname[PR_IPC_NAME_SIZE];
michael@0 50
michael@0 51 rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
michael@0 52 if ( PR_FAILURE == rc )
michael@0 53 {
michael@0 54 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 55 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 56 ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
michael@0 57 return( NULL );
michael@0 58 }
michael@0 59
michael@0 60 shm = PR_NEWZAP( PRSharedMemory );
michael@0 61 if ( NULL == shm )
michael@0 62 {
michael@0 63 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
michael@0 64 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory"));
michael@0 65 return( NULL );
michael@0 66 }
michael@0 67
michael@0 68 shm->ipcname = (char*)PR_MALLOC( strlen( ipcname ) + 1 );
michael@0 69 if ( NULL == shm->ipcname )
michael@0 70 {
michael@0 71 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
michael@0 72 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory"));
michael@0 73 PR_DELETE( shm );
michael@0 74 return( NULL );
michael@0 75 }
michael@0 76
michael@0 77 /* copy args to struct */
michael@0 78 strcpy( shm->ipcname, ipcname );
michael@0 79 shm->size = size;
michael@0 80 shm->mode = mode;
michael@0 81 shm->flags = flags;
michael@0 82 shm->ident = _PR_SHM_IDENT;
michael@0 83
michael@0 84 /* create the file first */
michael@0 85 if ( flags & PR_SHM_CREATE ) {
michael@0 86 int osfd = open( shm->ipcname, (O_RDWR | O_CREAT), shm->mode );
michael@0 87 if ( -1 == osfd ) {
michael@0 88 _PR_MD_MAP_OPEN_ERROR( errno );
michael@0 89 PR_FREEIF( shm->ipcname );
michael@0 90 PR_DELETE( shm );
michael@0 91 return( NULL );
michael@0 92 }
michael@0 93 if ( close(osfd) == -1 ) {
michael@0 94 _PR_MD_MAP_CLOSE_ERROR( errno );
michael@0 95 PR_FREEIF( shm->ipcname );
michael@0 96 PR_DELETE( shm );
michael@0 97 return( NULL );
michael@0 98 }
michael@0 99 }
michael@0 100
michael@0 101 /* hash the shm.name to an ID */
michael@0 102 key = ftok( shm->ipcname, NSPR_IPC_SHM_KEY );
michael@0 103 if ( -1 == key )
michael@0 104 {
michael@0 105 rc = PR_FAILURE;
michael@0 106 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 107 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 108 ("_MD_OpenSharedMemory(): ftok() failed on name: %s", shm->ipcname));
michael@0 109 PR_FREEIF( shm->ipcname );
michael@0 110 PR_DELETE( shm );
michael@0 111 return( NULL );
michael@0 112 }
michael@0 113
michael@0 114 /* get the shared memory */
michael@0 115 if ( flags & PR_SHM_CREATE ) {
michael@0 116 shm->id = shmget( key, shm->size, ( shm->mode | IPC_CREAT|IPC_EXCL));
michael@0 117 if ( shm->id >= 0 ) {
michael@0 118 return( shm );
michael@0 119 }
michael@0 120 if ((errno == EEXIST) && (flags & PR_SHM_EXCL)) {
michael@0 121 PR_SetError( PR_FILE_EXISTS_ERROR, errno );
michael@0 122 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 123 ("_MD_OpenSharedMemory(): shmget() exclusive failed, errno: %d", errno));
michael@0 124 PR_FREEIF(shm->ipcname);
michael@0 125 PR_DELETE(shm);
michael@0 126 return(NULL);
michael@0 127 }
michael@0 128 }
michael@0 129
michael@0 130 shm->id = shmget( key, shm->size, shm->mode );
michael@0 131 if ( -1 == shm->id ) {
michael@0 132 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 133 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 134 ("_MD_OpenSharedMemory(): shmget() failed, errno: %d", errno));
michael@0 135 PR_FREEIF(shm->ipcname);
michael@0 136 PR_DELETE(shm);
michael@0 137 return(NULL);
michael@0 138 }
michael@0 139
michael@0 140 return( shm );
michael@0 141 } /* end _MD_OpenSharedMemory() */
michael@0 142
michael@0 143 extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
michael@0 144 {
michael@0 145 void *addr;
michael@0 146 PRUint32 aFlags = shm->mode;
michael@0 147
michael@0 148 PR_ASSERT( shm->ident == _PR_SHM_IDENT );
michael@0 149
michael@0 150 aFlags |= (flags & PR_SHM_READONLY )? SHM_RDONLY : 0;
michael@0 151
michael@0 152 addr = shmat( shm->id, NULL, aFlags );
michael@0 153 if ( (void*)-1 == addr )
michael@0 154 {
michael@0 155 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 156 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 157 ("_MD_AttachSharedMemory(): shmat() failed on name: %s, OsError: %d",
michael@0 158 shm->ipcname, PR_GetOSError() ));
michael@0 159 addr = NULL;
michael@0 160 }
michael@0 161
michael@0 162 return addr;
michael@0 163 }
michael@0 164
michael@0 165 extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
michael@0 166 {
michael@0 167 PRStatus rc = PR_SUCCESS;
michael@0 168 PRIntn urc;
michael@0 169
michael@0 170 PR_ASSERT( shm->ident == _PR_SHM_IDENT );
michael@0 171
michael@0 172 urc = shmdt( addr );
michael@0 173 if ( -1 == urc )
michael@0 174 {
michael@0 175 rc = PR_FAILURE;
michael@0 176 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 177 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 178 ("_MD_DetachSharedMemory(): shmdt() failed on name: %s", shm->ipcname ));
michael@0 179 }
michael@0 180
michael@0 181 return rc;
michael@0 182 }
michael@0 183
michael@0 184 extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
michael@0 185 {
michael@0 186 PR_ASSERT( shm->ident == _PR_SHM_IDENT );
michael@0 187
michael@0 188 PR_FREEIF(shm->ipcname);
michael@0 189 PR_DELETE(shm);
michael@0 190
michael@0 191 return PR_SUCCESS;
michael@0 192 }
michael@0 193
michael@0 194 extern PRStatus _MD_DeleteSharedMemory( const char *name )
michael@0 195 {
michael@0 196 PRStatus rc = PR_SUCCESS;
michael@0 197 key_t key;
michael@0 198 int id;
michael@0 199 PRIntn urc;
michael@0 200 char ipcname[PR_IPC_NAME_SIZE];
michael@0 201
michael@0 202 rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
michael@0 203 if ( PR_FAILURE == rc )
michael@0 204 {
michael@0 205 PR_SetError( PR_UNKNOWN_ERROR , errno );
michael@0 206 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 207 ("_MD_DeleteSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
michael@0 208 return(PR_FAILURE);
michael@0 209 }
michael@0 210
michael@0 211 /* create the file first */
michael@0 212 {
michael@0 213 int osfd = open( ipcname, (O_RDWR | O_CREAT), 0666 );
michael@0 214 if ( -1 == osfd ) {
michael@0 215 _PR_MD_MAP_OPEN_ERROR( errno );
michael@0 216 return( PR_FAILURE );
michael@0 217 }
michael@0 218 if ( close(osfd) == -1 ) {
michael@0 219 _PR_MD_MAP_CLOSE_ERROR( errno );
michael@0 220 return( PR_FAILURE );
michael@0 221 }
michael@0 222 }
michael@0 223
michael@0 224 /* hash the shm.name to an ID */
michael@0 225 key = ftok( ipcname, NSPR_IPC_SHM_KEY );
michael@0 226 if ( -1 == key )
michael@0 227 {
michael@0 228 rc = PR_FAILURE;
michael@0 229 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 230 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 231 ("_MD_DeleteSharedMemory(): ftok() failed on name: %s", ipcname));
michael@0 232 }
michael@0 233
michael@0 234 #ifdef SYMBIAN
michael@0 235 /* In Symbian OS the system imposed minimum is 1 byte, instead of ZERO */
michael@0 236 id = shmget( key, 1, 0 );
michael@0 237 #else
michael@0 238 id = shmget( key, 0, 0 );
michael@0 239 #endif
michael@0 240 if ( -1 == id ) {
michael@0 241 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 242 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 243 ("_MD_DeleteSharedMemory(): shmget() failed, errno: %d", errno));
michael@0 244 return(PR_FAILURE);
michael@0 245 }
michael@0 246
michael@0 247 urc = shmctl( id, IPC_RMID, NULL );
michael@0 248 if ( -1 == urc )
michael@0 249 {
michael@0 250 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 251 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 252 ("_MD_DeleteSharedMemory(): shmctl() failed on name: %s", ipcname ));
michael@0 253 return(PR_FAILURE);
michael@0 254 }
michael@0 255
michael@0 256 urc = unlink( ipcname );
michael@0 257 if ( -1 == urc ) {
michael@0 258 _PR_MD_MAP_UNLINK_ERROR( errno );
michael@0 259 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 260 ("_MD_DeleteSharedMemory(): unlink() failed: %s", ipcname ));
michael@0 261 return(PR_FAILURE);
michael@0 262 }
michael@0 263
michael@0 264 return rc;
michael@0 265 } /* end _MD_DeleteSharedMemory() */
michael@0 266
michael@0 267 /*
michael@0 268 ** Implementation for Posix
michael@0 269 */
michael@0 270 #elif defined PR_HAVE_POSIX_NAMED_SHARED_MEMORY
michael@0 271 #include <sys/mman.h>
michael@0 272
michael@0 273 #define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
michael@0 274 #define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
michael@0 275 #define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
michael@0 276 #define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
michael@0 277 #define _MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory
michael@0 278
michael@0 279 struct _MDSharedMemory {
michael@0 280 int handle;
michael@0 281 };
michael@0 282
michael@0 283 extern PRSharedMemory * _MD_OpenSharedMemory(
michael@0 284 const char *name,
michael@0 285 PRSize size,
michael@0 286 PRIntn flags,
michael@0 287 PRIntn mode
michael@0 288 )
michael@0 289 {
michael@0 290 PRStatus rc = PR_SUCCESS;
michael@0 291 PRInt32 end;
michael@0 292 PRSharedMemory *shm;
michael@0 293 char ipcname[PR_IPC_NAME_SIZE];
michael@0 294
michael@0 295 rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
michael@0 296 if ( PR_FAILURE == rc )
michael@0 297 {
michael@0 298 PR_SetError( PR_UNKNOWN_ERROR , errno );
michael@0 299 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 300 ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
michael@0 301 return( NULL );
michael@0 302 }
michael@0 303
michael@0 304 shm = PR_NEWZAP( PRSharedMemory );
michael@0 305 if ( NULL == shm )
michael@0 306 {
michael@0 307 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
michael@0 308 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory"));
michael@0 309 return( NULL );
michael@0 310 }
michael@0 311
michael@0 312 shm->ipcname = PR_MALLOC( strlen( ipcname ) + 1 );
michael@0 313 if ( NULL == shm->ipcname )
michael@0 314 {
michael@0 315 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
michael@0 316 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory"));
michael@0 317 return( NULL );
michael@0 318 }
michael@0 319
michael@0 320 /* copy args to struct */
michael@0 321 strcpy( shm->ipcname, ipcname );
michael@0 322 shm->size = size;
michael@0 323 shm->mode = mode;
michael@0 324 shm->flags = flags;
michael@0 325 shm->ident = _PR_SHM_IDENT;
michael@0 326
michael@0 327 /*
michael@0 328 ** Create the shared memory
michael@0 329 */
michael@0 330 if ( flags & PR_SHM_CREATE ) {
michael@0 331 int oflag = (O_CREAT | O_RDWR);
michael@0 332
michael@0 333 if ( flags & PR_SHM_EXCL )
michael@0 334 oflag |= O_EXCL;
michael@0 335 shm->id = shm_open( shm->ipcname, oflag, shm->mode );
michael@0 336 } else {
michael@0 337 shm->id = shm_open( shm->ipcname, O_RDWR, shm->mode );
michael@0 338 }
michael@0 339
michael@0 340 if ( -1 == shm->id ) {
michael@0 341 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 342 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
michael@0 343 ("_MD_OpenSharedMemory(): shm_open failed: %s, OSError: %d",
michael@0 344 shm->ipcname, PR_GetOSError()));
michael@0 345 PR_DELETE( shm->ipcname );
michael@0 346 PR_DELETE( shm );
michael@0 347 return(NULL);
michael@0 348 }
michael@0 349
michael@0 350 end = ftruncate( shm->id, shm->size );
michael@0 351 if ( -1 == end ) {
michael@0 352 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 353 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG,
michael@0 354 ("_MD_OpenSharedMemory(): ftruncate failed, OSError: %d",
michael@0 355 PR_GetOSError()));
michael@0 356 PR_DELETE( shm->ipcname );
michael@0 357 PR_DELETE( shm );
michael@0 358 return(NULL);
michael@0 359 }
michael@0 360
michael@0 361 return(shm);
michael@0 362 } /* end _MD_OpenSharedMemory() */
michael@0 363
michael@0 364 extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
michael@0 365 {
michael@0 366 void *addr;
michael@0 367 PRIntn prot = (PROT_READ | PROT_WRITE);
michael@0 368
michael@0 369 PR_ASSERT( shm->ident == _PR_SHM_IDENT );
michael@0 370
michael@0 371 if ( PR_SHM_READONLY == flags)
michael@0 372 prot ^= PROT_WRITE;
michael@0 373
michael@0 374 addr = mmap( (void*)0, shm->size, prot, MAP_SHARED, shm->id, 0 );
michael@0 375 if ((void*)-1 == addr )
michael@0 376 {
michael@0 377 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 378 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 379 ("_MD_AttachSharedMemory(): mmap failed: %s, errno: %d",
michael@0 380 shm->ipcname, PR_GetOSError()));
michael@0 381 addr = NULL;
michael@0 382 } else {
michael@0 383 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 384 ("_MD_AttachSharedMemory(): name: %s, attached at: %p", shm->ipcname, addr));
michael@0 385 }
michael@0 386
michael@0 387 return addr;
michael@0 388 }
michael@0 389
michael@0 390 extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
michael@0 391 {
michael@0 392 PRStatus rc = PR_SUCCESS;
michael@0 393 PRIntn urc;
michael@0 394
michael@0 395 PR_ASSERT( shm->ident == _PR_SHM_IDENT );
michael@0 396
michael@0 397 urc = munmap( addr, shm->size );
michael@0 398 if ( -1 == urc )
michael@0 399 {
michael@0 400 rc = PR_FAILURE;
michael@0 401 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 402 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 403 ("_MD_DetachSharedMemory(): munmap failed: %s, errno: %d",
michael@0 404 shm->ipcname, PR_GetOSError()));
michael@0 405 }
michael@0 406 return rc;
michael@0 407 }
michael@0 408
michael@0 409 extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
michael@0 410 {
michael@0 411 int urc;
michael@0 412
michael@0 413 PR_ASSERT( shm->ident == _PR_SHM_IDENT );
michael@0 414
michael@0 415 urc = close( shm->id );
michael@0 416 if ( -1 == urc ) {
michael@0 417 _PR_MD_MAP_CLOSE_ERROR( errno );
michael@0 418 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 419 ("_MD_CloseSharedMemory(): close() failed, error: %d", PR_GetOSError()));
michael@0 420 return(PR_FAILURE);
michael@0 421 }
michael@0 422 PR_DELETE( shm->ipcname );
michael@0 423 PR_DELETE( shm );
michael@0 424 return PR_SUCCESS;
michael@0 425 }
michael@0 426
michael@0 427 extern PRStatus _MD_DeleteSharedMemory( const char *name )
michael@0 428 {
michael@0 429 PRStatus rc = PR_SUCCESS;
michael@0 430 PRUintn urc;
michael@0 431 char ipcname[PR_IPC_NAME_SIZE];
michael@0 432
michael@0 433 rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
michael@0 434 if ( PR_FAILURE == rc )
michael@0 435 {
michael@0 436 PR_SetError( PR_UNKNOWN_ERROR , errno );
michael@0 437 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 438 ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
michael@0 439 return rc;
michael@0 440 }
michael@0 441
michael@0 442 urc = shm_unlink( ipcname );
michael@0 443 if ( -1 == urc ) {
michael@0 444 rc = PR_FAILURE;
michael@0 445 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 446 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 447 ("_MD_DeleteSharedMemory(): shm_unlink failed: %s, errno: %d",
michael@0 448 ipcname, PR_GetOSError()));
michael@0 449 } else {
michael@0 450 PR_LOG( _pr_shm_lm, PR_LOG_DEBUG,
michael@0 451 ("_MD_DeleteSharedMemory(): %s, success", ipcname));
michael@0 452 }
michael@0 453
michael@0 454 return rc;
michael@0 455 } /* end _MD_DeleteSharedMemory() */
michael@0 456 #endif
michael@0 457
michael@0 458
michael@0 459
michael@0 460 /*
michael@0 461 ** Unix implementation for anonymous memory (file) mapping
michael@0 462 */
michael@0 463 extern PRLogModuleInfo *_pr_shma_lm;
michael@0 464
michael@0 465 #include <unistd.h>
michael@0 466
michael@0 467 extern PRFileMap* _md_OpenAnonFileMap(
michael@0 468 const char *dirName,
michael@0 469 PRSize size,
michael@0 470 PRFileMapProtect prot
michael@0 471 )
michael@0 472 {
michael@0 473 PRFileMap *fm = NULL;
michael@0 474 PRFileDesc *fd;
michael@0 475 int osfd;
michael@0 476 PRIntn urc;
michael@0 477 PRIntn mode = 0600;
michael@0 478 char *genName;
michael@0 479 pid_t pid = getpid(); /* for generating filename */
michael@0 480 PRThread *tid = PR_GetCurrentThread(); /* for generating filename */
michael@0 481 int incr; /* for generating filename */
michael@0 482 const int maxTries = 20; /* maximum # attempts at a unique filename */
michael@0 483 PRInt64 size64; /* 64-bit version of 'size' */
michael@0 484
michael@0 485 /*
michael@0 486 ** generate a filename from input and runtime environment
michael@0 487 ** open the file, unlink the file.
michael@0 488 ** make maxTries number of attempts at uniqueness in the filename
michael@0 489 */
michael@0 490 for ( incr = 0; incr < maxTries ; incr++ ) {
michael@0 491 #if defined(SYMBIAN)
michael@0 492 #define NSPR_AFM_FILENAME "%s\\NSPR-AFM-%d-%p.%d"
michael@0 493 #else
michael@0 494 #define NSPR_AFM_FILENAME "%s/.NSPR-AFM-%d-%p.%d"
michael@0 495 #endif
michael@0 496 genName = PR_smprintf( NSPR_AFM_FILENAME,
michael@0 497 dirName, (int) pid, tid, incr );
michael@0 498 if ( NULL == genName ) {
michael@0 499 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 500 ("_md_OpenAnonFileMap(): PR_snprintf(): failed, generating filename"));
michael@0 501 goto Finished;
michael@0 502 }
michael@0 503
michael@0 504 /* create the file */
michael@0 505 osfd = open( genName, (O_CREAT | O_EXCL | O_RDWR), mode );
michael@0 506 if ( -1 == osfd ) {
michael@0 507 if ( EEXIST == errno ) {
michael@0 508 PR_smprintf_free( genName );
michael@0 509 continue; /* name exists, try again */
michael@0 510 } else {
michael@0 511 _PR_MD_MAP_OPEN_ERROR( errno );
michael@0 512 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 513 ("_md_OpenAnonFileMap(): open(): failed, filename: %s, errno: %d",
michael@0 514 genName, PR_GetOSError()));
michael@0 515 PR_smprintf_free( genName );
michael@0 516 goto Finished;
michael@0 517 }
michael@0 518 }
michael@0 519 break; /* name generation and open successful, break; */
michael@0 520 } /* end for() */
michael@0 521
michael@0 522 if ( incr == maxTries ) {
michael@0 523 PR_ASSERT( -1 == osfd );
michael@0 524 PR_ASSERT( EEXIST == errno );
michael@0 525 _PR_MD_MAP_OPEN_ERROR( errno );
michael@0 526 goto Finished;
michael@0 527 }
michael@0 528
michael@0 529 urc = unlink( genName );
michael@0 530 #if defined(SYMBIAN) && defined(__WINS__)
michael@0 531 /* If it is being used by the system or another process, Symbian OS
michael@0 532 * Emulator(WINS) considers this an error. */
michael@0 533 if ( -1 == urc && EACCES != errno ) {
michael@0 534 #else
michael@0 535 if ( -1 == urc ) {
michael@0 536 #endif
michael@0 537 _PR_MD_MAP_UNLINK_ERROR( errno );
michael@0 538 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 539 ("_md_OpenAnonFileMap(): failed on unlink(), errno: %d", errno));
michael@0 540 PR_smprintf_free( genName );
michael@0 541 close( osfd );
michael@0 542 goto Finished;
michael@0 543 }
michael@0 544 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 545 ("_md_OpenAnonFileMap(): unlink(): %s", genName ));
michael@0 546
michael@0 547 PR_smprintf_free( genName );
michael@0 548
michael@0 549 fd = PR_ImportFile( osfd );
michael@0 550 if ( NULL == fd ) {
michael@0 551 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 552 ("_md_OpenAnonFileMap(): PR_ImportFile(): failed"));
michael@0 553 goto Finished;
michael@0 554 }
michael@0 555 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 556 ("_md_OpenAnonFileMap(): fd: %p", fd ));
michael@0 557
michael@0 558 urc = ftruncate( fd->secret->md.osfd, size );
michael@0 559 if ( -1 == urc ) {
michael@0 560 _PR_MD_MAP_DEFAULT_ERROR( errno );
michael@0 561 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 562 ("_md_OpenAnonFileMap(): failed on ftruncate(), errno: %d", errno));
michael@0 563 PR_Close( fd );
michael@0 564 goto Finished;
michael@0 565 }
michael@0 566 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 567 ("_md_OpenAnonFileMap(): ftruncate(): size: %d", size ));
michael@0 568
michael@0 569 LL_UI2L(size64, size); /* PRSize (size_t) is unsigned */
michael@0 570 fm = PR_CreateFileMap( fd, size64, prot );
michael@0 571 if ( NULL == fm ) {
michael@0 572 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 573 ("PR_OpenAnonFileMap(): failed"));
michael@0 574 PR_Close( fd );
michael@0 575 goto Finished;
michael@0 576 }
michael@0 577 fm->md.isAnonFM = PR_TRUE; /* set fd close */
michael@0 578
michael@0 579 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 580 ("_md_OpenAnonFileMap(): PR_CreateFileMap(): fm: %p", fm ));
michael@0 581
michael@0 582 Finished:
michael@0 583 return(fm);
michael@0 584 } /* end md_OpenAnonFileMap() */
michael@0 585
michael@0 586 /*
michael@0 587 ** _md_ExportFileMapAsString()
michael@0 588 **
michael@0 589 **
michael@0 590 */
michael@0 591 extern PRStatus _md_ExportFileMapAsString(
michael@0 592 PRFileMap *fm,
michael@0 593 PRSize bufSize,
michael@0 594 char *buf
michael@0 595 )
michael@0 596 {
michael@0 597 PRIntn written;
michael@0 598 PRIntn prot = (PRIntn)fm->prot;
michael@0 599
michael@0 600 written = PR_snprintf( buf, bufSize, "%ld:%d",
michael@0 601 fm->fd->secret->md.osfd, prot );
michael@0 602
michael@0 603 return((written == -1)? PR_FAILURE : PR_SUCCESS);
michael@0 604 } /* end _md_ExportFileMapAsString() */
michael@0 605
michael@0 606
michael@0 607 extern PRFileMap * _md_ImportFileMapFromString(
michael@0 608 const char *fmstring
michael@0 609 )
michael@0 610 {
michael@0 611 PRStatus rc;
michael@0 612 PRInt32 osfd;
michael@0 613 PRIntn prot; /* really: a PRFileMapProtect */
michael@0 614 PRFileDesc *fd;
michael@0 615 PRFileMap *fm = NULL; /* default return value */
michael@0 616 PRFileInfo64 info;
michael@0 617
michael@0 618 PR_sscanf( fmstring, "%ld:%d", &osfd, &prot );
michael@0 619
michael@0 620 /* import the os file descriptor */
michael@0 621 fd = PR_ImportFile( osfd );
michael@0 622 if ( NULL == fd ) {
michael@0 623 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 624 ("_md_ImportFileMapFromString(): PR_ImportFile() failed"));
michael@0 625 goto Finished;
michael@0 626 }
michael@0 627
michael@0 628 rc = PR_GetOpenFileInfo64( fd, &info );
michael@0 629 if ( PR_FAILURE == rc ) {
michael@0 630 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 631 ("_md_ImportFileMapFromString(): PR_GetOpenFileInfo64() failed"));
michael@0 632 goto Finished;
michael@0 633 }
michael@0 634
michael@0 635 fm = PR_CreateFileMap( fd, info.size, (PRFileMapProtect)prot );
michael@0 636 if ( NULL == fm ) {
michael@0 637 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
michael@0 638 ("_md_ImportFileMapFromString(): PR_CreateFileMap() failed"));
michael@0 639 }
michael@0 640
michael@0 641 Finished:
michael@0 642 return(fm);
michael@0 643 } /* end _md_ImportFileMapFromString() */

mercurial