Back to index

lightning-sunbird  0.9+nobinonly
uxshm.c
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /*
00039 ** uxshm.c -- Unix Implementations NSPR Named Shared Memory
00040 **
00041 **
00042 ** lth. Jul-1999.
00043 **
00044 */
00045 #include <string.h>
00046 #include <prshm.h>
00047 #include <prerr.h>
00048 #include <prmem.h>
00049 #include "primpl.h"       
00050 #include <fcntl.h>
00051 
00052 extern PRLogModuleInfo *_pr_shm_lm;
00053 
00054 
00055 #define NSPR_IPC_SHM_KEY 'b'
00056 /*
00057 ** Implementation for System V
00058 */
00059 #if defined PR_HAVE_SYSV_NAMED_SHARED_MEMORY
00060 #include <sys/ipc.h>
00061 #include <sys/shm.h>
00062 #include <sys/types.h>
00063 #include <sys/stat.h>
00064 
00065 #define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
00066 #define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
00067 #define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
00068 #define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
00069 #define _MD_DELETE_SHARED_MEMORY  _MD_DeleteSharedMemory
00070 
00071 extern PRSharedMemory * _MD_OpenSharedMemory( 
00072     const char *name,
00073     PRSize      size,
00074     PRIntn      flags,
00075     PRIntn      mode
00076 )
00077 {
00078     PRStatus rc = PR_SUCCESS;
00079     key_t   key;
00080     PRSharedMemory *shm;
00081     char        ipcname[PR_IPC_NAME_SIZE];
00082 
00083     rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
00084     if ( PR_FAILURE == rc )
00085     {
00086         _PR_MD_MAP_DEFAULT_ERROR( errno );
00087         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00088             ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
00089         return( NULL );
00090     }
00091 
00092     shm = PR_NEWZAP( PRSharedMemory );
00093     if ( NULL == shm ) 
00094     {
00095         PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
00096         PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); 
00097         return( NULL );
00098     }
00099 
00100     shm->ipcname = (char*)PR_MALLOC( strlen( ipcname ) + 1 );
00101     if ( NULL == shm->ipcname )
00102     {
00103         PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
00104         PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); 
00105         return( NULL );
00106     }
00107 
00108     /* copy args to struct */
00109     strcpy( shm->ipcname, ipcname );
00110     shm->size = size; 
00111     shm->mode = mode; 
00112     shm->flags = flags;
00113     shm->ident = _PR_SHM_IDENT;
00114 
00115     /* create the file first */
00116     if ( flags & PR_SHM_CREATE )  {
00117         int osfd = open( shm->ipcname, (O_RDWR | O_CREAT), shm->mode );
00118         if ( -1 == osfd ) {
00119             _PR_MD_MAP_OPEN_ERROR( errno );
00120             PR_FREEIF( shm->ipcname );
00121             PR_DELETE( shm );
00122             return( NULL );
00123         } 
00124         if ( close(osfd) == -1 ) {
00125             _PR_MD_MAP_CLOSE_ERROR( errno );
00126             PR_FREEIF( shm->ipcname );
00127             PR_DELETE( shm );
00128             return( NULL );
00129         }
00130     }
00131 
00132     /* hash the shm.name to an ID */
00133     key = ftok( shm->ipcname, NSPR_IPC_SHM_KEY );
00134     if ( -1 == key )
00135     {
00136         rc = PR_FAILURE;
00137         _PR_MD_MAP_DEFAULT_ERROR( errno );
00138         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00139             ("_MD_OpenSharedMemory(): ftok() failed on name: %s", shm->ipcname));
00140         PR_FREEIF( shm->ipcname );
00141         PR_DELETE( shm );
00142         return( NULL );
00143     }
00144 
00145     /* get the shared memory */
00146     if ( flags & PR_SHM_CREATE )  {
00147         shm->id = shmget( key, shm->size, ( shm->mode | IPC_CREAT|IPC_EXCL));
00148         if ( shm->id >= 0 ) {
00149             return( shm );
00150         }
00151         if ((errno == EEXIST) && (flags & PR_SHM_EXCL)) {
00152             PR_SetError( PR_FILE_EXISTS_ERROR, errno );
00153             PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00154                 ("_MD_OpenSharedMemory(): shmget() exclusive failed, errno: %d", errno));
00155             PR_FREEIF(shm->ipcname);
00156             PR_DELETE(shm);
00157             return(NULL);
00158         }
00159     } 
00160 
00161     shm->id = shmget( key, shm->size, shm->mode );
00162     if ( -1 == shm->id ) {
00163         _PR_MD_MAP_DEFAULT_ERROR( errno );
00164         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00165             ("_MD_OpenSharedMemory(): shmget() failed, errno: %d", errno));
00166         PR_FREEIF(shm->ipcname);
00167         PR_DELETE(shm);
00168         return(NULL);
00169     }
00170 
00171     return( shm );
00172 } /* end _MD_OpenSharedMemory() */
00173 
00174 extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
00175 {
00176     void        *addr;
00177     PRUint32    aFlags = shm->mode;
00178 
00179     PR_ASSERT( shm->ident == _PR_SHM_IDENT );
00180 
00181     aFlags |= (flags & PR_SHM_READONLY )? SHM_RDONLY : 0;
00182 
00183     addr = shmat( shm->id, NULL, aFlags );
00184     if ( (void*)-1 == addr )
00185     {
00186         _PR_MD_MAP_DEFAULT_ERROR( errno );
00187         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00188             ("_MD_AttachSharedMemory(): shmat() failed on name: %s, OsError: %d", 
00189                 shm->ipcname, PR_GetOSError() ));
00190         addr = NULL;
00191     }
00192 
00193     return addr;
00194 }    
00195 
00196 extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
00197 {
00198     PRStatus rc = PR_SUCCESS;
00199     PRIntn   urc;
00200 
00201     PR_ASSERT( shm->ident == _PR_SHM_IDENT );
00202 
00203     urc = shmdt( addr );
00204     if ( -1 == urc )
00205     {
00206         rc = PR_FAILURE;
00207         _PR_MD_MAP_DEFAULT_ERROR( errno );
00208         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00209             ("_MD_DetachSharedMemory(): shmdt() failed on name: %s", shm->ipcname ));
00210     }
00211 
00212     return rc;
00213 }    
00214 
00215 extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
00216 {
00217     PR_ASSERT( shm->ident == _PR_SHM_IDENT );
00218 
00219     PR_FREEIF(shm->ipcname);
00220     PR_DELETE(shm);
00221 
00222     return PR_SUCCESS;
00223 }    
00224 
00225 extern PRStatus _MD_DeleteSharedMemory( const char *name )
00226 {
00227     PRStatus rc = PR_SUCCESS;
00228     key_t   key;
00229     int     id;
00230     PRIntn  urc;
00231     char        ipcname[PR_IPC_NAME_SIZE];
00232 
00233     rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
00234     if ( PR_FAILURE == rc )
00235     {
00236         PR_SetError( PR_UNKNOWN_ERROR , errno );
00237         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00238             ("_MD_DeleteSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
00239         return(PR_FAILURE);
00240     }
00241 
00242     /* create the file first */ 
00243     {
00244         int osfd = open( ipcname, (O_RDWR | O_CREAT), 0666 );
00245         if ( -1 == osfd ) {
00246             _PR_MD_MAP_OPEN_ERROR( errno );
00247             return( PR_FAILURE );
00248         } 
00249         if ( close(osfd) == -1 ) {
00250             _PR_MD_MAP_CLOSE_ERROR( errno );
00251             return( PR_FAILURE );
00252         }
00253     }
00254 
00255     /* hash the shm.name to an ID */
00256     key = ftok( ipcname, NSPR_IPC_SHM_KEY );
00257     if ( -1 == key )
00258     {
00259         rc = PR_FAILURE;
00260         _PR_MD_MAP_DEFAULT_ERROR( errno );
00261         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00262             ("_MD_DeleteSharedMemory(): ftok() failed on name: %s", ipcname));
00263     }
00264 
00265     id = shmget( key, 0, 0 );
00266     if ( -1 == id ) {
00267         _PR_MD_MAP_DEFAULT_ERROR( errno );
00268         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00269             ("_MD_DeleteSharedMemory(): shmget() failed, errno: %d", errno));
00270         return(PR_FAILURE);
00271     }
00272 
00273     urc = shmctl( id, IPC_RMID, NULL );
00274     if ( -1 == urc )
00275     {
00276         _PR_MD_MAP_DEFAULT_ERROR( errno );
00277         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00278             ("_MD_DeleteSharedMemory(): shmctl() failed on name: %s", ipcname ));
00279         return(PR_FAILURE);
00280     }
00281 
00282     urc = unlink( ipcname );
00283     if ( -1 == urc ) {
00284         _PR_MD_MAP_UNLINK_ERROR( errno );
00285         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00286             ("_MD_DeleteSharedMemory(): unlink() failed: %s", ipcname ));
00287         return(PR_FAILURE);
00288     }
00289 
00290     return rc;
00291 }  /* end _MD_DeleteSharedMemory() */
00292 
00293 /*
00294 ** Implementation for Posix
00295 */
00296 #elif defined PR_HAVE_POSIX_NAMED_SHARED_MEMORY
00297 #include <sys/mman.h>
00298 
00299 #define _MD_OPEN_SHARED_MEMORY _MD_OpenSharedMemory
00300 #define _MD_ATTACH_SHARED_MEMORY _MD_AttachSharedMemory
00301 #define _MD_DETACH_SHARED_MEMORY _MD_DetachSharedMemory
00302 #define _MD_CLOSE_SHARED_MEMORY _MD_CloseSharedMemory
00303 #define _MD_DELETE_SHARED_MEMORY  _MD_DeleteSharedMemory
00304 
00305 struct _MDSharedMemory {
00306     int     handle;
00307 };
00308 
00309 extern PRSharedMemory * _MD_OpenSharedMemory( 
00310     const char *name,
00311     PRSize      size,
00312     PRIntn      flags,
00313     PRIntn      mode
00314 )
00315 {
00316     PRStatus    rc = PR_SUCCESS;
00317     PRInt32     end;
00318     PRSharedMemory *shm;
00319     char        ipcname[PR_IPC_NAME_SIZE];
00320 
00321     rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
00322     if ( PR_FAILURE == rc )
00323     {
00324         PR_SetError( PR_UNKNOWN_ERROR , errno );
00325         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00326             ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
00327         return( NULL );
00328     }
00329 
00330     shm = PR_NEWZAP( PRSharedMemory );
00331     if ( NULL == shm ) 
00332     {
00333         PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
00334         PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New PRSharedMemory out of memory")); 
00335         return( NULL );
00336     }
00337 
00338     shm->ipcname = PR_MALLOC( strlen( ipcname ) + 1 );
00339     if ( NULL == shm->ipcname )
00340     {
00341         PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0 );
00342         PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: New shm->ipcname out of memory")); 
00343         return( NULL );
00344     }
00345 
00346     /* copy args to struct */
00347     strcpy( shm->ipcname, ipcname );
00348     shm->size = size; 
00349     shm->mode = mode;
00350     shm->flags = flags;
00351     shm->ident = _PR_SHM_IDENT;
00352 
00353     /*
00354     ** Create the shared memory
00355     */
00356     if ( flags & PR_SHM_CREATE )  {
00357         int oflag = (O_CREAT | O_RDWR);
00358         
00359         if ( flags & PR_SHM_EXCL )
00360             oflag |= O_EXCL;
00361         shm->id = shm_open( shm->ipcname, oflag, shm->mode );
00362     } else {
00363         shm->id = shm_open( shm->ipcname, O_RDWR, shm->mode );
00364     }
00365 
00366     if ( -1 == shm->id )  {
00367         _PR_MD_MAP_DEFAULT_ERROR( errno );
00368         PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
00369             ("_MD_OpenSharedMemory(): shm_open failed: %s, OSError: %d",
00370                 shm->ipcname, PR_GetOSError())); 
00371         PR_DELETE( shm->ipcname );
00372         PR_DELETE( shm );
00373         return(NULL);
00374     }
00375 
00376     end = ftruncate( shm->id, shm->size );
00377     if ( -1 == end ) {
00378         _PR_MD_MAP_DEFAULT_ERROR( errno );
00379         PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
00380             ("_MD_OpenSharedMemory(): ftruncate failed, OSError: %d",
00381                 PR_GetOSError()));
00382         PR_DELETE( shm->ipcname );
00383         PR_DELETE( shm );
00384         return(NULL);
00385     }
00386 
00387     return(shm);
00388 } /* end _MD_OpenSharedMemory() */
00389 
00390 extern void * _MD_AttachSharedMemory( PRSharedMemory *shm, PRIntn flags )
00391 {
00392     void        *addr;
00393     PRIntn      prot = (PROT_READ | PROT_WRITE);
00394 
00395     PR_ASSERT( shm->ident == _PR_SHM_IDENT );
00396 
00397     if ( PR_SHM_READONLY == flags)
00398         prot ^= PROT_WRITE;
00399 
00400     addr = mmap( (void*)0, shm->size, prot, MAP_SHARED, shm->id, 0 );
00401     if ((void*)-1 == addr )
00402     {
00403         _PR_MD_MAP_DEFAULT_ERROR( errno );
00404         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00405             ("_MD_AttachSharedMemory(): mmap failed: %s, errno: %d",
00406                 shm->ipcname, PR_GetOSError()));
00407         addr = NULL;
00408     } else {
00409         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00410             ("_MD_AttachSharedMemory(): name: %s, attached at: %p", shm->ipcname, addr));
00411     }
00412     
00413     return addr;
00414 }    
00415 
00416 extern PRStatus _MD_DetachSharedMemory( PRSharedMemory *shm, void *addr )
00417 {
00418     PRStatus    rc = PR_SUCCESS;
00419     PRIntn      urc;
00420 
00421     PR_ASSERT( shm->ident == _PR_SHM_IDENT );
00422 
00423     urc = munmap( addr, shm->size );
00424     if ( -1 == urc )
00425     {
00426         rc = PR_FAILURE;
00427         _PR_MD_MAP_DEFAULT_ERROR( errno );
00428         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00429             ("_MD_DetachSharedMemory(): munmap failed: %s, errno: %d", 
00430                 shm->ipcname, PR_GetOSError()));
00431     }
00432     return rc;
00433 }    
00434 
00435 extern PRStatus _MD_CloseSharedMemory( PRSharedMemory *shm )
00436 {
00437     int urc;
00438     
00439     PR_ASSERT( shm->ident == _PR_SHM_IDENT );
00440 
00441     urc = close( shm->id );
00442     if ( -1 == urc ) {
00443         _PR_MD_MAP_CLOSE_ERROR( errno );
00444         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00445             ("_MD_CloseSharedMemory(): close() failed, error: %d", PR_GetOSError()));
00446         return(PR_FAILURE);
00447     }
00448     PR_DELETE( shm->ipcname );
00449     PR_DELETE( shm );
00450     return PR_SUCCESS;
00451 }    
00452 
00453 extern PRStatus _MD_DeleteSharedMemory( const char *name )
00454 {
00455     PRStatus    rc = PR_SUCCESS;
00456     PRUintn     urc;
00457     char        ipcname[PR_IPC_NAME_SIZE];
00458 
00459     rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
00460     if ( PR_FAILURE == rc )
00461     {
00462         PR_SetError( PR_UNKNOWN_ERROR , errno );
00463         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00464             ("_MD_OpenSharedMemory(): _PR_MakeNativeIPCName() failed: %s", name ));
00465         return rc;
00466     }
00467 
00468     urc = shm_unlink( ipcname );
00469     if ( -1 == urc ) {
00470         rc = PR_FAILURE;
00471         _PR_MD_MAP_DEFAULT_ERROR( errno );
00472         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00473             ("_MD_DeleteSharedMemory(): shm_unlink failed: %s, errno: %d", 
00474                 ipcname, PR_GetOSError()));
00475     } else {
00476         PR_LOG( _pr_shm_lm, PR_LOG_DEBUG, 
00477             ("_MD_DeleteSharedMemory(): %s, success", ipcname));
00478     }
00479 
00480     return rc;
00481 } /* end _MD_DeleteSharedMemory() */
00482 #endif
00483 
00484 
00485 
00486 /*
00487 ** Unix implementation for anonymous memory (file) mapping
00488 */
00489 extern PRLogModuleInfo *_pr_shma_lm;
00490 
00491 #include <unistd.h>
00492 
00493 extern PRFileMap* _md_OpenAnonFileMap( 
00494     const char *dirName,
00495     PRSize      size,
00496     PRFileMapProtect prot
00497 )
00498 {
00499     PRFileMap   *fm = NULL;
00500     PRFileDesc  *fd;
00501     int         osfd;
00502     PRIntn      urc;
00503     PRIntn      mode = 0600;
00504     char        *genName;
00505     pid_t       pid = getpid(); /* for generating filename */
00506     PRThread    *tid = PR_GetCurrentThread(); /* for generating filename */
00507     int         incr; /* for generating filename */
00508     const int   maxTries = 20; /* maximum # attempts at a unique filename */
00509     PRInt64     size64; /* 64-bit version of 'size' */
00510 
00511     /*
00512     ** generate a filename from input and runtime environment
00513     ** open the file, unlink the file.
00514     ** make maxTries number of attempts at uniqueness in the filename
00515     */
00516     for ( incr = 0; incr < maxTries ; incr++ ) {
00517         genName = PR_smprintf( "%s/.NSPR-AFM-%d-%p.%d", 
00518             dirName, (int) pid, tid, incr );
00519         if ( NULL == genName ) {
00520             PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00521                 ("_md_OpenAnonFileMap(): PR_snprintf(): failed, generating filename"));
00522             goto Finished;
00523         }
00524         
00525         /* create the file */
00526         osfd = open( genName, (O_CREAT | O_EXCL | O_RDWR), mode );
00527         if ( -1 == osfd ) {
00528             if ( EEXIST == errno )  {
00529                 PR_smprintf_free( genName );
00530                 continue; /* name exists, try again */
00531             } else {
00532                 _PR_MD_MAP_OPEN_ERROR( errno );
00533                 PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00534                     ("_md_OpenAnonFileMap(): open(): failed, filename: %s, errno: %d", 
00535                         genName, PR_GetOSError()));
00536                 PR_smprintf_free( genName );
00537                 goto Finished;
00538             }
00539         }
00540         break; /* name generation and open successful, break; */
00541     } /* end for() */
00542 
00543     if ( incr == maxTries ) {
00544         PR_ASSERT( -1 == osfd );
00545         PR_ASSERT( EEXIST == errno );
00546         _PR_MD_MAP_OPEN_ERROR( errno );
00547         goto Finished;
00548     }
00549 
00550     urc = unlink( genName );
00551     if ( -1 == urc ) {
00552         _PR_MD_MAP_UNLINK_ERROR( errno );
00553         PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00554             ("_md_OpenAnonFileMap(): failed on unlink(), errno: %d", errno));
00555         PR_smprintf_free( genName );
00556         close( osfd );
00557         goto Finished;        
00558     }
00559     PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00560         ("_md_OpenAnonFileMap(): unlink(): %s", genName ));
00561 
00562     PR_smprintf_free( genName );
00563 
00564     fd = PR_ImportFile( osfd );
00565     if ( NULL == fd ) {
00566         PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00567             ("_md_OpenAnonFileMap(): PR_ImportFile(): failed"));
00568         goto Finished;        
00569     }
00570     PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00571         ("_md_OpenAnonFileMap(): fd: %p", fd ));
00572 
00573     urc = ftruncate( fd->secret->md.osfd, size );
00574     if ( -1 == urc ) {
00575         _PR_MD_MAP_DEFAULT_ERROR( errno );
00576         PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00577             ("_md_OpenAnonFileMap(): failed on ftruncate(), errno: %d", errno));
00578         PR_Close( fd );
00579         goto Finished;        
00580     }
00581     PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00582         ("_md_OpenAnonFileMap(): ftruncate(): size: %d", size ));
00583 
00584     LL_UI2L(size64, size);  /* PRSize (size_t) is unsigned */
00585     fm = PR_CreateFileMap( fd, size64, prot );
00586     if ( NULL == fm )  {
00587         PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00588             ("PR_OpenAnonFileMap(): failed"));
00589         PR_Close( fd );
00590         goto Finished;        
00591     }
00592     fm->md.isAnonFM = PR_TRUE; /* set fd close */
00593 
00594     PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00595         ("_md_OpenAnonFileMap(): PR_CreateFileMap(): fm: %p", fm ));
00596 
00597 Finished:    
00598     return(fm);
00599 } /* end md_OpenAnonFileMap() */
00600 
00601 /*
00602 ** _md_ExportFileMapAsString()
00603 **
00604 **
00605 */
00606 extern PRStatus _md_ExportFileMapAsString(
00607     PRFileMap *fm,
00608     PRSize    bufSize,
00609     char      *buf
00610 )
00611 {
00612     PRIntn  written;
00613     PRIntn  prot = (PRIntn)fm->prot;
00614     
00615     written = PR_snprintf( buf, bufSize, "%ld:%d",
00616         fm->fd->secret->md.osfd, prot );
00617         
00618     return((written == -1)? PR_FAILURE : PR_SUCCESS);
00619 } /* end _md_ExportFileMapAsString() */
00620 
00621 
00622 extern PRFileMap * _md_ImportFileMapFromString(
00623     const char *fmstring
00624 )
00625 {
00626     PRStatus    rc;
00627     PRInt32     osfd;
00628     PRIntn      prot; /* really: a PRFileMapProtect */
00629     PRFileDesc  *fd;
00630     PRFileMap   *fm = NULL; /* default return value */
00631     PRFileInfo64 info;
00632 
00633     PR_sscanf( fmstring, "%ld:%d", &osfd, &prot );
00634 
00635     /* import the os file descriptor */
00636     fd = PR_ImportFile( osfd );
00637     if ( NULL == fd ) {
00638         PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00639             ("_md_ImportFileMapFromString(): PR_ImportFile() failed"));
00640         goto Finished;
00641     }
00642 
00643     rc = PR_GetOpenFileInfo64( fd, &info );
00644     if ( PR_FAILURE == rc )  {
00645         PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00646             ("_md_ImportFileMapFromString(): PR_GetOpenFileInfo64() failed"));    
00647         goto Finished;
00648     }
00649 
00650     fm = PR_CreateFileMap( fd, info.size, (PRFileMapProtect)prot );
00651     if ( NULL == fm ) {
00652         PR_LOG( _pr_shma_lm, PR_LOG_DEBUG,
00653             ("_md_ImportFileMapFromString(): PR_CreateFileMap() failed"));    
00654     }
00655 
00656 Finished:
00657     return(fm);
00658 } /* end _md_ImportFileMapFromString() */