1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/src/md/unix/uxshm.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,643 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 +** uxshm.c -- Unix Implementations NSPR Named Shared Memory 1.11 +** 1.12 +** 1.13 +** lth. Jul-1999. 1.14 +** 1.15 +*/ 1.16 +#include <string.h> 1.17 +#include <prshm.h> 1.18 +#include <prerr.h> 1.19 +#include <prmem.h> 1.20 +#include "primpl.h" 1.21 +#include <fcntl.h> 1.22 + 1.23 +extern PRLogModuleInfo *_pr_shm_lm; 1.24 + 1.25 + 1.26 +#define NSPR_IPC_SHM_KEY 'b' 1.27 +/* 1.28 +** Implementation for System V 1.29 +*/ 1.30 +#if defined PR_HAVE_SYSV_NAMED_SHARED_MEMORY 1.31 +#include <sys/ipc.h> 1.32 +#include <sys/shm.h> 1.33 +#include <sys/types.h> 1.34 +#include <sys/stat.h> 1.35 + 1.36 +#define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory 1.37 +#define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory 1.38 +#define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory 1.39 +#define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory 1.40 +#define _MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory 1.41 + 1.42 +extern PRSharedMemory * _MD_OpenSharedMemory( 1.43 + const char *name, 1.44 + PRSize size, 1.45 + PRIntn flags, 1.46 + PRIntn mode 1.47 +) 1.48 +{ 1.49 + PRStatus rc = PR_SUCCESS; 1.50 + key_t key; 1.51 + PRSharedMemory *shm; 1.52 + char ipcname[PR_IPC_NAME_SIZE]; 1.53 + 1.54 + rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); 1.55 + if ( PR_FAILURE == rc ) 1.56 + { 1.57 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.58 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.59 + ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); 1.60 + return( NULL ); 1.61 + } 1.62 + 1.63 + shm = PR_NEWZAP( PRSharedMemory ); 1.64 + if ( NULL == shm ) 1.65 + { 1.66 + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); 1.67 + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); 1.68 + return( NULL ); 1.69 + } 1.70 + 1.71 + shm->ipcname = (char*)PR_MALLOC( strlen( ipcname ) + 1 ); 1.72 + if ( NULL == shm->ipcname ) 1.73 + { 1.74 + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); 1.75 + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); 1.76 + PR_DELETE( shm ); 1.77 + return( NULL ); 1.78 + } 1.79 + 1.80 + /* copy args to struct */ 1.81 + strcpy( shm->ipcname, ipcname ); 1.82 + shm->size = size; 1.83 + shm->mode = mode; 1.84 + shm->flags = flags; 1.85 + shm->ident = _PR_SHM_IDENT; 1.86 + 1.87 + /* create the file first */ 1.88 + if ( flags & PR_SHM_CREATE ) { 1.89 + int osfd = open( shm->ipcname, (O_RDWR | O_CREAT), shm->mode ); 1.90 + if ( -1 == osfd ) { 1.91 + _PR_MD_MAP_OPEN_ERROR( errno ); 1.92 + PR_FREEIF( shm->ipcname ); 1.93 + PR_DELETE( shm ); 1.94 + return( NULL ); 1.95 + } 1.96 + if ( close(osfd) == -1 ) { 1.97 + _PR_MD_MAP_CLOSE_ERROR( errno ); 1.98 + PR_FREEIF( shm->ipcname ); 1.99 + PR_DELETE( shm ); 1.100 + return( NULL ); 1.101 + } 1.102 + } 1.103 + 1.104 + /* hash the shm.name to an ID */ 1.105 + key = ftok( shm->ipcname, NSPR_IPC_SHM_KEY ); 1.106 + if ( -1 == key ) 1.107 + { 1.108 + rc = PR_FAILURE; 1.109 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.110 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.111 + ("_MD_OpenSharedMemory(): ftok() failed on name: %s", shm->ipcname)); 1.112 + PR_FREEIF( shm->ipcname ); 1.113 + PR_DELETE( shm ); 1.114 + return( NULL ); 1.115 + } 1.116 + 1.117 + /* get the shared memory */ 1.118 + if ( flags & PR_SHM_CREATE ) { 1.119 + shm->id = shmget( key, shm->size, ( shm->mode | IPC_CREAT|IPC_EXCL)); 1.120 + if ( shm->id >= 0 ) { 1.121 + return( shm ); 1.122 + } 1.123 + if ((errno == EEXIST) && (flags & PR_SHM_EXCL)) { 1.124 + PR_SetError( PR_FILE_EXISTS_ERROR, errno ); 1.125 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.126 + ("_MD_OpenSharedMemory(): shmget() exclusive failed, errno: %d", errno)); 1.127 + PR_FREEIF(shm->ipcname); 1.128 + PR_DELETE(shm); 1.129 + return(NULL); 1.130 + } 1.131 + } 1.132 + 1.133 + shm->id = shmget( key, shm->size, shm->mode ); 1.134 + if ( -1 == shm->id ) { 1.135 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.136 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.137 + ("_MD_OpenSharedMemory(): shmget() failed, errno: %d", errno)); 1.138 + PR_FREEIF(shm->ipcname); 1.139 + PR_DELETE(shm); 1.140 + return(NULL); 1.141 + } 1.142 + 1.143 + return( shm ); 1.144 +} /* end _MD_OpenSharedMemory() */ 1.145 + 1.146 +extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ) 1.147 +{ 1.148 + void *addr; 1.149 + PRUint32 aFlags = shm->mode; 1.150 + 1.151 + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); 1.152 + 1.153 + aFlags |= (flags & PR_SHM_READONLY )? SHM_RDONLY : 0; 1.154 + 1.155 + addr = shmat( shm->id, NULL, aFlags ); 1.156 + if ( (void*)-1 == addr ) 1.157 + { 1.158 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.159 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.160 + ("_MD_AttachSharedMemory(): shmat() failed on name: %s, OsError: %d", 1.161 + shm->ipcname, PR_GetOSError() )); 1.162 + addr = NULL; 1.163 + } 1.164 + 1.165 + return addr; 1.166 +} 1.167 + 1.168 +extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ) 1.169 +{ 1.170 + PRStatus rc = PR_SUCCESS; 1.171 + PRIntn urc; 1.172 + 1.173 + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); 1.174 + 1.175 + urc = shmdt( addr ); 1.176 + if ( -1 == urc ) 1.177 + { 1.178 + rc = PR_FAILURE; 1.179 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.180 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.181 + ("_MD_DetachSharedMemory(): shmdt() failed on name: %s", shm->ipcname )); 1.182 + } 1.183 + 1.184 + return rc; 1.185 +} 1.186 + 1.187 +extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ) 1.188 +{ 1.189 + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); 1.190 + 1.191 + PR_FREEIF(shm->ipcname); 1.192 + PR_DELETE(shm); 1.193 + 1.194 + return PR_SUCCESS; 1.195 +} 1.196 + 1.197 +extern PRStatus _MD_DeleteSharedMemory( const char *name ) 1.198 +{ 1.199 + PRStatus rc = PR_SUCCESS; 1.200 + key_t key; 1.201 + int id; 1.202 + PRIntn urc; 1.203 + char ipcname[PR_IPC_NAME_SIZE]; 1.204 + 1.205 + rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); 1.206 + if ( PR_FAILURE == rc ) 1.207 + { 1.208 + PR_SetError( PR_UNKNOWN_ERROR , errno ); 1.209 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.210 + ("_MD_DeleteSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); 1.211 + return(PR_FAILURE); 1.212 + } 1.213 + 1.214 + /* create the file first */ 1.215 + { 1.216 + int osfd = open( ipcname, (O_RDWR | O_CREAT), 0666 ); 1.217 + if ( -1 == osfd ) { 1.218 + _PR_MD_MAP_OPEN_ERROR( errno ); 1.219 + return( PR_FAILURE ); 1.220 + } 1.221 + if ( close(osfd) == -1 ) { 1.222 + _PR_MD_MAP_CLOSE_ERROR( errno ); 1.223 + return( PR_FAILURE ); 1.224 + } 1.225 + } 1.226 + 1.227 + /* hash the shm.name to an ID */ 1.228 + key = ftok( ipcname, NSPR_IPC_SHM_KEY ); 1.229 + if ( -1 == key ) 1.230 + { 1.231 + rc = PR_FAILURE; 1.232 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.233 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.234 + ("_MD_DeleteSharedMemory(): ftok() failed on name: %s", ipcname)); 1.235 + } 1.236 + 1.237 +#ifdef SYMBIAN 1.238 + /* In Symbian OS the system imposed minimum is 1 byte, instead of ZERO */ 1.239 + id = shmget( key, 1, 0 ); 1.240 +#else 1.241 + id = shmget( key, 0, 0 ); 1.242 +#endif 1.243 + if ( -1 == id ) { 1.244 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.245 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.246 + ("_MD_DeleteSharedMemory(): shmget() failed, errno: %d", errno)); 1.247 + return(PR_FAILURE); 1.248 + } 1.249 + 1.250 + urc = shmctl( id, IPC_RMID, NULL ); 1.251 + if ( -1 == urc ) 1.252 + { 1.253 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.254 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.255 + ("_MD_DeleteSharedMemory(): shmctl() failed on name: %s", ipcname )); 1.256 + return(PR_FAILURE); 1.257 + } 1.258 + 1.259 + urc = unlink( ipcname ); 1.260 + if ( -1 == urc ) { 1.261 + _PR_MD_MAP_UNLINK_ERROR( errno ); 1.262 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.263 + ("_MD_DeleteSharedMemory(): unlink() failed: %s", ipcname )); 1.264 + return(PR_FAILURE); 1.265 + } 1.266 + 1.267 + return rc; 1.268 +} /* end _MD_DeleteSharedMemory() */ 1.269 + 1.270 +/* 1.271 +** Implementation for Posix 1.272 +*/ 1.273 +#elif defined PR_HAVE_POSIX_NAMED_SHARED_MEMORY 1.274 +#include <sys/mman.h> 1.275 + 1.276 +#define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory 1.277 +#define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory 1.278 +#define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory 1.279 +#define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory 1.280 +#define _MD_DELETE_SHARED_MEMORY _MD_DeleteSharedMemory 1.281 + 1.282 +struct _MDSharedMemory { 1.283 + int handle; 1.284 +}; 1.285 + 1.286 +extern PRSharedMemory * _MD_OpenSharedMemory( 1.287 + const char *name, 1.288 + PRSize size, 1.289 + PRIntn flags, 1.290 + PRIntn mode 1.291 +) 1.292 +{ 1.293 + PRStatus rc = PR_SUCCESS; 1.294 + PRInt32 end; 1.295 + PRSharedMemory *shm; 1.296 + char ipcname[PR_IPC_NAME_SIZE]; 1.297 + 1.298 + rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); 1.299 + if ( PR_FAILURE == rc ) 1.300 + { 1.301 + PR_SetError( PR_UNKNOWN_ERROR , errno ); 1.302 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.303 + ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); 1.304 + return( NULL ); 1.305 + } 1.306 + 1.307 + shm = PR_NEWZAP( PRSharedMemory ); 1.308 + if ( NULL == shm ) 1.309 + { 1.310 + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); 1.311 + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); 1.312 + return( NULL ); 1.313 + } 1.314 + 1.315 + shm->ipcname = PR_MALLOC( strlen( ipcname ) + 1 ); 1.316 + if ( NULL == shm->ipcname ) 1.317 + { 1.318 + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 ); 1.319 + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); 1.320 + return( NULL ); 1.321 + } 1.322 + 1.323 + /* copy args to struct */ 1.324 + strcpy( shm->ipcname, ipcname ); 1.325 + shm->size = size; 1.326 + shm->mode = mode; 1.327 + shm->flags = flags; 1.328 + shm->ident = _PR_SHM_IDENT; 1.329 + 1.330 + /* 1.331 + ** Create the shared memory 1.332 + */ 1.333 + if ( flags & PR_SHM_CREATE ) { 1.334 + int oflag = (O_CREAT | O_RDWR); 1.335 + 1.336 + if ( flags & PR_SHM_EXCL ) 1.337 + oflag |= O_EXCL; 1.338 + shm->id = shm_open( shm->ipcname, oflag, shm->mode ); 1.339 + } else { 1.340 + shm->id = shm_open( shm->ipcname, O_RDWR, shm->mode ); 1.341 + } 1.342 + 1.343 + if ( -1 == shm->id ) { 1.344 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.345 + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 1.346 + ("_MD_OpenSharedMemory(): shm_open failed: %s, OSError: %d", 1.347 + shm->ipcname, PR_GetOSError())); 1.348 + PR_DELETE( shm->ipcname ); 1.349 + PR_DELETE( shm ); 1.350 + return(NULL); 1.351 + } 1.352 + 1.353 + end = ftruncate( shm->id, shm->size ); 1.354 + if ( -1 == end ) { 1.355 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.356 + PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 1.357 + ("_MD_OpenSharedMemory(): ftruncate failed, OSError: %d", 1.358 + PR_GetOSError())); 1.359 + PR_DELETE( shm->ipcname ); 1.360 + PR_DELETE( shm ); 1.361 + return(NULL); 1.362 + } 1.363 + 1.364 + return(shm); 1.365 +} /* end _MD_OpenSharedMemory() */ 1.366 + 1.367 +extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags ) 1.368 +{ 1.369 + void *addr; 1.370 + PRIntn prot = (PROT_READ | PROT_WRITE); 1.371 + 1.372 + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); 1.373 + 1.374 + if ( PR_SHM_READONLY == flags) 1.375 + prot ^= PROT_WRITE; 1.376 + 1.377 + addr = mmap( (void*)0, shm->size, prot, MAP_SHARED, shm->id, 0 ); 1.378 + if ((void*)-1 == addr ) 1.379 + { 1.380 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.381 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.382 + ("_MD_AttachSharedMemory(): mmap failed: %s, errno: %d", 1.383 + shm->ipcname, PR_GetOSError())); 1.384 + addr = NULL; 1.385 + } else { 1.386 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.387 + ("_MD_AttachSharedMemory(): name: %s, attached at: %p", shm->ipcname, addr)); 1.388 + } 1.389 + 1.390 + return addr; 1.391 +} 1.392 + 1.393 +extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr ) 1.394 +{ 1.395 + PRStatus rc = PR_SUCCESS; 1.396 + PRIntn urc; 1.397 + 1.398 + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); 1.399 + 1.400 + urc = munmap( addr, shm->size ); 1.401 + if ( -1 == urc ) 1.402 + { 1.403 + rc = PR_FAILURE; 1.404 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.405 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.406 + ("_MD_DetachSharedMemory(): munmap failed: %s, errno: %d", 1.407 + shm->ipcname, PR_GetOSError())); 1.408 + } 1.409 + return rc; 1.410 +} 1.411 + 1.412 +extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm ) 1.413 +{ 1.414 + int urc; 1.415 + 1.416 + PR_ASSERT( shm->ident == _PR_SHM_IDENT ); 1.417 + 1.418 + urc = close( shm->id ); 1.419 + if ( -1 == urc ) { 1.420 + _PR_MD_MAP_CLOSE_ERROR( errno ); 1.421 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.422 + ("_MD_CloseSharedMemory(): close() failed, error: %d", PR_GetOSError())); 1.423 + return(PR_FAILURE); 1.424 + } 1.425 + PR_DELETE( shm->ipcname ); 1.426 + PR_DELETE( shm ); 1.427 + return PR_SUCCESS; 1.428 +} 1.429 + 1.430 +extern PRStatus _MD_DeleteSharedMemory( const char *name ) 1.431 +{ 1.432 + PRStatus rc = PR_SUCCESS; 1.433 + PRUintn urc; 1.434 + char ipcname[PR_IPC_NAME_SIZE]; 1.435 + 1.436 + rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm ); 1.437 + if ( PR_FAILURE == rc ) 1.438 + { 1.439 + PR_SetError( PR_UNKNOWN_ERROR , errno ); 1.440 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.441 + ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name )); 1.442 + return rc; 1.443 + } 1.444 + 1.445 + urc = shm_unlink( ipcname ); 1.446 + if ( -1 == urc ) { 1.447 + rc = PR_FAILURE; 1.448 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.449 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.450 + ("_MD_DeleteSharedMemory(): shm_unlink failed: %s, errno: %d", 1.451 + ipcname, PR_GetOSError())); 1.452 + } else { 1.453 + PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 1.454 + ("_MD_DeleteSharedMemory(): %s, success", ipcname)); 1.455 + } 1.456 + 1.457 + return rc; 1.458 +} /* end _MD_DeleteSharedMemory() */ 1.459 +#endif 1.460 + 1.461 + 1.462 + 1.463 +/* 1.464 +** Unix implementation for anonymous memory (file) mapping 1.465 +*/ 1.466 +extern PRLogModuleInfo *_pr_shma_lm; 1.467 + 1.468 +#include <unistd.h> 1.469 + 1.470 +extern PRFileMap* _md_OpenAnonFileMap( 1.471 + const char *dirName, 1.472 + PRSize size, 1.473 + PRFileMapProtect prot 1.474 +) 1.475 +{ 1.476 + PRFileMap *fm = NULL; 1.477 + PRFileDesc *fd; 1.478 + int osfd; 1.479 + PRIntn urc; 1.480 + PRIntn mode = 0600; 1.481 + char *genName; 1.482 + pid_t pid = getpid(); /* for generating filename */ 1.483 + PRThread *tid = PR_GetCurrentThread(); /* for generating filename */ 1.484 + int incr; /* for generating filename */ 1.485 + const int maxTries = 20; /* maximum # attempts at a unique filename */ 1.486 + PRInt64 size64; /* 64-bit version of 'size' */ 1.487 + 1.488 + /* 1.489 + ** generate a filename from input and runtime environment 1.490 + ** open the file, unlink the file. 1.491 + ** make maxTries number of attempts at uniqueness in the filename 1.492 + */ 1.493 + for ( incr = 0; incr < maxTries ; incr++ ) { 1.494 +#if defined(SYMBIAN) 1.495 +#define NSPR_AFM_FILENAME "%s\\NSPR-AFM-%d-%p.%d" 1.496 +#else 1.497 +#define NSPR_AFM_FILENAME "%s/.NSPR-AFM-%d-%p.%d" 1.498 +#endif 1.499 + genName = PR_smprintf( NSPR_AFM_FILENAME, 1.500 + dirName, (int) pid, tid, incr ); 1.501 + if ( NULL == genName ) { 1.502 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.503 + ("_md_OpenAnonFileMap(): PR_snprintf(): failed, generating filename")); 1.504 + goto Finished; 1.505 + } 1.506 + 1.507 + /* create the file */ 1.508 + osfd = open( genName, (O_CREAT | O_EXCL | O_RDWR), mode ); 1.509 + if ( -1 == osfd ) { 1.510 + if ( EEXIST == errno ) { 1.511 + PR_smprintf_free( genName ); 1.512 + continue; /* name exists, try again */ 1.513 + } else { 1.514 + _PR_MD_MAP_OPEN_ERROR( errno ); 1.515 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.516 + ("_md_OpenAnonFileMap(): open(): failed, filename: %s, errno: %d", 1.517 + genName, PR_GetOSError())); 1.518 + PR_smprintf_free( genName ); 1.519 + goto Finished; 1.520 + } 1.521 + } 1.522 + break; /* name generation and open successful, break; */ 1.523 + } /* end for() */ 1.524 + 1.525 + if ( incr == maxTries ) { 1.526 + PR_ASSERT( -1 == osfd ); 1.527 + PR_ASSERT( EEXIST == errno ); 1.528 + _PR_MD_MAP_OPEN_ERROR( errno ); 1.529 + goto Finished; 1.530 + } 1.531 + 1.532 + urc = unlink( genName ); 1.533 +#if defined(SYMBIAN) && defined(__WINS__) 1.534 + /* If it is being used by the system or another process, Symbian OS 1.535 + * Emulator(WINS) considers this an error. */ 1.536 + if ( -1 == urc && EACCES != errno ) { 1.537 +#else 1.538 + if ( -1 == urc ) { 1.539 +#endif 1.540 + _PR_MD_MAP_UNLINK_ERROR( errno ); 1.541 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.542 + ("_md_OpenAnonFileMap(): failed on unlink(), errno: %d", errno)); 1.543 + PR_smprintf_free( genName ); 1.544 + close( osfd ); 1.545 + goto Finished; 1.546 + } 1.547 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.548 + ("_md_OpenAnonFileMap(): unlink(): %s", genName )); 1.549 + 1.550 + PR_smprintf_free( genName ); 1.551 + 1.552 + fd = PR_ImportFile( osfd ); 1.553 + if ( NULL == fd ) { 1.554 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.555 + ("_md_OpenAnonFileMap(): PR_ImportFile(): failed")); 1.556 + goto Finished; 1.557 + } 1.558 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.559 + ("_md_OpenAnonFileMap(): fd: %p", fd )); 1.560 + 1.561 + urc = ftruncate( fd->secret->md.osfd, size ); 1.562 + if ( -1 == urc ) { 1.563 + _PR_MD_MAP_DEFAULT_ERROR( errno ); 1.564 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.565 + ("_md_OpenAnonFileMap(): failed on ftruncate(), errno: %d", errno)); 1.566 + PR_Close( fd ); 1.567 + goto Finished; 1.568 + } 1.569 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.570 + ("_md_OpenAnonFileMap(): ftruncate(): size: %d", size )); 1.571 + 1.572 + LL_UI2L(size64, size); /* PRSize (size_t) is unsigned */ 1.573 + fm = PR_CreateFileMap( fd, size64, prot ); 1.574 + if ( NULL == fm ) { 1.575 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.576 + ("PR_OpenAnonFileMap(): failed")); 1.577 + PR_Close( fd ); 1.578 + goto Finished; 1.579 + } 1.580 + fm->md.isAnonFM = PR_TRUE; /* set fd close */ 1.581 + 1.582 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.583 + ("_md_OpenAnonFileMap(): PR_CreateFileMap(): fm: %p", fm )); 1.584 + 1.585 +Finished: 1.586 + return(fm); 1.587 +} /* end md_OpenAnonFileMap() */ 1.588 + 1.589 +/* 1.590 +** _md_ExportFileMapAsString() 1.591 +** 1.592 +** 1.593 +*/ 1.594 +extern PRStatus _md_ExportFileMapAsString( 1.595 + PRFileMap *fm, 1.596 + PRSize bufSize, 1.597 + char *buf 1.598 +) 1.599 +{ 1.600 + PRIntn written; 1.601 + PRIntn prot = (PRIntn)fm->prot; 1.602 + 1.603 + written = PR_snprintf( buf, bufSize, "%ld:%d", 1.604 + fm->fd->secret->md.osfd, prot ); 1.605 + 1.606 + return((written == -1)? PR_FAILURE : PR_SUCCESS); 1.607 +} /* end _md_ExportFileMapAsString() */ 1.608 + 1.609 + 1.610 +extern PRFileMap * _md_ImportFileMapFromString( 1.611 + const char *fmstring 1.612 +) 1.613 +{ 1.614 + PRStatus rc; 1.615 + PRInt32 osfd; 1.616 + PRIntn prot; /* really: a PRFileMapProtect */ 1.617 + PRFileDesc *fd; 1.618 + PRFileMap *fm = NULL; /* default return value */ 1.619 + PRFileInfo64 info; 1.620 + 1.621 + PR_sscanf( fmstring, "%ld:%d", &osfd, &prot ); 1.622 + 1.623 + /* import the os file descriptor */ 1.624 + fd = PR_ImportFile( osfd ); 1.625 + if ( NULL == fd ) { 1.626 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.627 + ("_md_ImportFileMapFromString(): PR_ImportFile() failed")); 1.628 + goto Finished; 1.629 + } 1.630 + 1.631 + rc = PR_GetOpenFileInfo64( fd, &info ); 1.632 + if ( PR_FAILURE == rc ) { 1.633 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.634 + ("_md_ImportFileMapFromString(): PR_GetOpenFileInfo64() failed")); 1.635 + goto Finished; 1.636 + } 1.637 + 1.638 + fm = PR_CreateFileMap( fd, info.size, (PRFileMapProtect)prot ); 1.639 + if ( NULL == fm ) { 1.640 + PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, 1.641 + ("_md_ImportFileMapFromString(): PR_CreateFileMap() failed")); 1.642 + } 1.643 + 1.644 +Finished: 1.645 + return(fm); 1.646 +} /* end _md_ImportFileMapFromString() */