LCOV - code coverage report
Current view: directory - nsprpub/pr/src/md/unix - uxshm.c (source / functions) Found Hit Coverage
Test: app.info Lines: 196 0 0.0 %
Date: 2012-06-02 Functions: 8 0 0.0 %

       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() */

Generated by: LCOV version 1.7