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