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