nsprpub/pr/tests/nameshm1.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     6 /*
     7 ** File: nameshm1.c -- Test Named Shared Memory
     8 **
     9 ** Description: 
    10 ** nameshm1 tests Named Shared Memory. nameshm1 performs two tests of
    11 ** named shared memory. 
    12 ** 
    13 ** The first test is a basic test. The basic test operates as a single
    14 ** process. The process exercises all the API elements of the facility.
    15 ** This test also attempts to write to all locations in the shared
    16 ** memory.
    17 **
    18 ** The second test is a client-server test. The client-server test
    19 ** creates a new instance of nameshm1, passing the -C argument to the
    20 ** new process; this creates the client-side process. The server-side
    21 ** (the instance of nameshm1 created from the command line) and the
    22 ** client-side interact via inter-process semaphores to verify that the
    23 ** shared memory segment can be read and written by both sides in a
    24 ** synchronized maner.
    25 **
    26 ** Note: Because this test runs in two processes, the log files created
    27 ** by the test are not in chronological sequence; makes it hard to read.
    28 ** As a temporary circumvention, I changed the definition(s) of the
    29 ** _PUT_LOG() macro in prlog.c to force a flushall(), or equivalent.
    30 ** This causes the log entries to be emitted in true chronological
    31 ** order.
    32 **
    33 ** Synopsis: nameshm1 [options] [name]
    34 ** 
    35 ** Options:
    36 ** -d       Enables debug trace via PR_LOG()
    37 ** -v       Enables verbose mode debug trace via PR_LOG()
    38 ** -w       Causes the basic test to attempt to write to the segment
    39 **          mapped as read-only. When this option is specified, the
    40 **          test should crash with a seg-fault; this is a destructive
    41 **          test and is considered successful when it seg-faults.
    42 ** 
    43 ** -C       Causes nameshm1 to start as the client-side of a
    44 **          client-server pair of processes. Only the instance
    45 **          of nameshm1 operating as the server-side process should
    46 **          specify the -C option when creating the client-side process;
    47 **          the -C option should not be specified at the command line.
    48 **          The client-side uses the shared memory segment created by
    49 **          the server-side to communicate with the server-side
    50 **          process.
    51 **          
    52 ** -p <n>   Specify the number of iterations the client-server tests
    53 **          should perform. Default: 1000.
    54 **
    55 ** -s <n>   Size, in KBytes (1024), of the shared memory segment.
    56 **          Default: (10 * 1024)
    57 **
    58 ** -i <n>   Number of client-side iterations. Default: 3
    59 **
    60 ** name     specifies the name of the shared memory segment to be used.
    61 **          Default: /tmp/xxxNSPRshm
    62 **
    63 **
    64 ** See also: prshm.h
    65 **
    66 ** /lth. Aug-1999.
    67 */
    69 #include <plgetopt.h> 
    70 #include <nspr.h>
    71 #include <stdlib.h>
    72 #include <string.h>
    73 #include <private/primpl.h>
    75 #ifdef SYMBIAN
    76 #define SEM_NAME1 "c:\\data\\nameshmSEM1"
    77 #define SEM_NAME2 "c:\\data\\nameshmSEM2"
    78 #define OPT_NAME "c:\\data\\xxxNSPRshm"
    79 #define EXE_NAME "nspr_tests_nameshm1.exe"
    80 #else
    81 #define SEM_NAME1 "/tmp/nameshmSEM1"
    82 #define SEM_NAME2 "/tmp/nameshmSEM2"
    83 #define OPT_NAME "/tmp/xxxNSPRshm"
    84 #define EXE_NAME "nameshm1"
    85 #endif
    86 #define SEM_MODE  0666
    87 #define SHM_MODE  0666
    89 #define NameSize (1024)
    91 PRIntn  debug = 0;
    92 PRIntn  failed_already = 0;
    93 PRLogModuleLevel msgLevel = PR_LOG_NONE;
    94 PRLogModuleInfo *lm;
    96 /* command line options */
    97 PRIntn      optDebug = 0;
    98 PRIntn      optVerbose = 0;
    99 PRUint32    optWriteRO = 0;     /* test write to read-only memory. should crash  */
   100 PRUint32    optClient = 0;
   101 PRUint32    optCreate = 1;
   102 PRUint32    optAttachRW = 1;
   103 PRUint32    optAttachRO = 1;
   104 PRUint32    optClose = 1;
   105 PRUint32    optDelete = 1;
   106 PRInt32     optPing = 1000;
   107 PRUint32    optSize = (10 * 1024 );
   108 PRInt32     optClientIterations = 3;
   109 char        optName[NameSize] = OPT_NAME;
   111 char buf[1024] = "";
   114 static void BasicTest( void ) 
   115 {
   116     PRSharedMemory  *shm;
   117     char *addr; /* address of shared memory segment */
   118     PRUint32  i;
   119     PRInt32 rc;
   121     PR_LOG( lm, msgLevel,
   122              ( "nameshm1: Begin BasicTest" ));
   124     if ( PR_FAILURE == PR_DeleteSharedMemory( optName )) {
   125         PR_LOG( lm, msgLevel,
   126             ("nameshm1: Initial PR_DeleteSharedMemory() failed. No problem"));
   127     } else
   128         PR_LOG( lm, msgLevel,
   129             ("nameshm1: Initial PR_DeleteSharedMemory() success"));
   132     shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE );
   133     if ( NULL == shm )
   134     {
   135         PR_LOG( lm, msgLevel,
   136                  ( "nameshm1: RW Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   137         failed_already = 1;
   138         return;
   139     }
   140     PR_LOG( lm, msgLevel,
   141              ( "nameshm1: RW Create: success: %p", shm ));
   143     addr = PR_AttachSharedMemory( shm , 0 );
   144     if ( NULL == addr ) 
   145     {
   146         PR_LOG( lm, msgLevel,
   147                  ( "nameshm1: RW Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   148         failed_already = 1;
   149         return;
   150     }
   151     PR_LOG( lm, msgLevel,
   152              ( "nameshm1: RW Attach: success: %p", addr ));
   154     /* fill memory with i */
   155     for ( i = 0; i < optSize ;  i++ )
   156     {
   157          *(addr + i) = i;
   158     }
   160     rc = PR_DetachSharedMemory( shm, addr );
   161     if ( PR_FAILURE == rc )
   162     {
   163         PR_LOG( lm, msgLevel,
   164                  ( "nameshm1: RW Detach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   165         failed_already = 1;
   166         return;
   167     }
   168     PR_LOG( lm, msgLevel,
   169              ( "nameshm1: RW Detach: success: " ));
   171     rc = PR_CloseSharedMemory( shm );
   172     if ( PR_FAILURE == rc )
   173     {
   174         PR_LOG( lm, msgLevel,
   175                  ( "nameshm1: RW Close: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   176         failed_already = 1;
   177         return;
   178     }
   179     PR_LOG( lm, msgLevel,
   180              ( "nameshm1: RW Close: success: " ));
   182     rc = PR_DeleteSharedMemory( optName );
   183     if ( PR_FAILURE == rc )
   184     {
   185         PR_LOG( lm, msgLevel,
   186                  ( "nameshm1: RW Delete: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   187         failed_already = 1;
   188         return;
   189     }
   190     PR_LOG( lm, msgLevel,
   191              ( "nameshm1: RW Delete: success: " ));
   193     PR_LOG( lm, msgLevel,
   194             ("nameshm1: BasicTest(): Passed"));
   196     return;
   197 } /* end BasicTest() */
   199 static void ReadOnlyTest( void )
   200 {
   201     PRSharedMemory  *shm;
   202     char *roAddr; /* read-only address of shared memory segment */
   203     PRInt32 rc;
   205     PR_LOG( lm, msgLevel,
   206              ( "nameshm1: Begin ReadOnlyTest" ));
   208     shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE);
   209     if ( NULL == shm )
   210     {
   211         PR_LOG( lm, msgLevel,
   212                  ( "nameshm1: RO Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   213         failed_already = 1;
   214         return;
   215     }
   216     PR_LOG( lm, msgLevel,
   217              ( "nameshm1: RO Create: success: %p", shm ));
   220     roAddr = PR_AttachSharedMemory( shm , PR_SHM_READONLY );
   221     if ( NULL == roAddr ) 
   222     {
   223         PR_LOG( lm, msgLevel,
   224                  ( "nameshm1: RO Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   225         failed_already = 1;
   226         return;
   227     }
   228     PR_LOG( lm, msgLevel,
   229              ( "nameshm1: RO Attach: success: %p", roAddr ));
   231     if ( optWriteRO )
   232     {
   233         *roAddr = 0x00; /* write to read-only memory */
   234         failed_already = 1;
   235         PR_LOG( lm, msgLevel, ("nameshm1: Wrote to read-only memory segment!"));
   236         return;
   237     }
   239     rc = PR_DetachSharedMemory( shm, roAddr );
   240     if ( PR_FAILURE == rc )
   241     {
   242         PR_LOG( lm, msgLevel,
   243                  ( "nameshm1: RO Detach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   244         failed_already = 1;
   245         return;
   246     }
   247     PR_LOG( lm, msgLevel,
   248              ( "nameshm1: RO Detach: success: " ));
   250     rc = PR_CloseSharedMemory( shm );
   251     if ( PR_FAILURE == rc )
   252     {
   253         PR_LOG( lm, msgLevel,
   254                  ( "nameshm1: RO Close: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   255         failed_already = 1;
   256         return;
   257     }
   258     PR_LOG( lm, msgLevel,
   259              ( "nameshm1: RO Close: success: " ));
   261     rc = PR_DeleteSharedMemory( optName );
   262     if ( PR_FAILURE == rc )
   263     {
   264         PR_LOG( lm, msgLevel,
   265                  ( "nameshm1: RO Destroy: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   266         failed_already = 1;
   267         return;
   268     }
   269     PR_LOG( lm, msgLevel,
   270              ( "nameshm1: RO Destroy: success: " ));
   272     PR_LOG( lm, msgLevel,
   273         ("nameshm1: ReadOnlyTest(): Passed"));
   275     return;
   276 } /* end ReadOnlyTest() */
   278 static void DoClient( void )
   279 {
   280     PRStatus rc;
   281     PRSem *sem1, *sem2;
   282     PRSharedMemory  *shm;
   283     PRUint32 *addr; 
   284     PRInt32 i;
   286     PR_LOG( lm, msgLevel,
   287             ("nameshm1: DoClient(): Starting"));
   289     sem1 = PR_OpenSemaphore( SEM_NAME1, 0, 0, 0 );
   290     PR_ASSERT( sem1 );
   292     sem2 = PR_OpenSemaphore( SEM_NAME2, 0, 0, 0 );
   293     PR_ASSERT( sem1 );
   295     shm = PR_OpenSharedMemory( optName, optSize, 0, SHM_MODE );
   296     if ( NULL == shm )
   297     {
   298         PR_LOG( lm, msgLevel,
   299             ( "nameshm1: DoClient(): Create: Error: %ld. OSError: %ld", 
   300                 PR_GetError(), PR_GetOSError()));
   301         failed_already = 1;
   302         return;
   303     }
   304     PR_LOG( lm, msgLevel,
   305              ( "nameshm1: DoClient(): Create: success: %p", shm ));
   307     addr = PR_AttachSharedMemory( shm , 0 );
   308     if ( NULL == addr ) 
   309     {
   310         PR_LOG( lm, msgLevel,
   311             ( "nameshm1: DoClient(): Attach: Error: %ld. OSError: %ld", 
   312                 PR_GetError(), PR_GetOSError()));
   313         failed_already = 1;
   314         return;
   315     }
   316     PR_LOG( lm, msgLevel,
   317              ( "nameshm1: DoClient(): Attach: success: %p", addr ));
   319     PR_LOG( lm, msgLevel,
   320         ( "Client found: %s", addr));
   322     PR_Sleep(PR_SecondsToInterval(4));
   323     for ( i = 0 ; i < optPing ; i++ )
   324     {
   325         rc = PR_WaitSemaphore( sem2 );
   326         PR_ASSERT( PR_FAILURE != rc );
   328         (*addr)++;
   329         PR_ASSERT( (*addr % 2) == 0 );        
   330         if ( optVerbose )
   331             PR_LOG( lm, msgLevel,
   332                  ( "nameshm1: Client ping: %d, i: %d", *addr, i));
   334         rc = PR_PostSemaphore( sem1 );
   335         PR_ASSERT( PR_FAILURE != rc );
   336     }
   338     rc = PR_CloseSemaphore( sem1 );
   339     PR_ASSERT( PR_FAILURE != rc );
   341     rc = PR_CloseSemaphore( sem2 );
   342     PR_ASSERT( PR_FAILURE != rc );
   344     rc = PR_DetachSharedMemory( shm, addr );
   345     if ( PR_FAILURE == rc )
   346     {
   347         PR_LOG( lm, msgLevel,
   348             ( "nameshm1: DoClient(): Detach: Error: %ld. OSError: %ld", 
   349                 PR_GetError(), PR_GetOSError()));
   350         failed_already = 1;
   351         return;
   352     }
   353     PR_LOG( lm, msgLevel,
   354              ( "nameshm1: DoClient(): Detach: success: " ));
   356     rc = PR_CloseSharedMemory( shm );
   357     if ( PR_FAILURE == rc )
   358     {
   359         PR_LOG( lm, msgLevel,
   360             ( "nameshm1: DoClient(): Close: Error: %ld. OSError: %ld", 
   361                 PR_GetError(), PR_GetOSError()));
   362         failed_already = 1;
   363         return;
   364     }
   365     PR_LOG( lm, msgLevel,
   366              ( "nameshm1: DoClient(): Close: success: " ));
   368     return;
   369 }    /* end DoClient() */
   371 static void ClientServerTest( void )
   372 {
   373     PRStatus rc;
   374     PRSem *sem1, *sem2;
   375     PRProcess *proc;
   376     PRInt32 exit_status;
   377     PRSharedMemory  *shm;
   378     PRUint32 *addr; 
   379     PRInt32 i;
   380     char *child_argv[8];
   381     char buf[24];
   383     PR_LOG( lm, msgLevel,
   384              ( "nameshm1: Begin ClientServerTest" ));
   386     rc = PR_DeleteSharedMemory( optName );
   387     if ( PR_FAILURE == rc )
   388     {
   389         PR_LOG( lm, msgLevel,
   390             ( "nameshm1: Server: Destroy: failed. No problem"));
   391     } else
   392         PR_LOG( lm, msgLevel,
   393             ( "nameshm1: Server: Destroy: success" ));
   396     shm = PR_OpenSharedMemory( optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL), SHM_MODE);
   397     if ( NULL == shm )
   398     {
   399         PR_LOG( lm, msgLevel,
   400                  ( "nameshm1: Server: Create: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   401         failed_already = 1;
   402         return;
   403     }
   404     PR_LOG( lm, msgLevel,
   405              ( "nameshm1: Server: Create: success: %p", shm ));
   407     addr = PR_AttachSharedMemory( shm , 0 );
   408     if ( NULL == addr ) 
   409     {
   410         PR_LOG( lm, msgLevel,
   411                  ( "nameshm1: Server: Attach: Error: %ld. OSError: %ld", PR_GetError(), PR_GetOSError()));
   412         failed_already = 1;
   413         return;
   414     }
   415     PR_LOG( lm, msgLevel,
   416              ( "nameshm1: Server: Attach: success: %p", addr ));
   418     sem1 = PR_OpenSemaphore( SEM_NAME1, PR_SEM_CREATE, SEM_MODE, 0 );
   419     PR_ASSERT( sem1 );
   421     sem2 = PR_OpenSemaphore( SEM_NAME2, PR_SEM_CREATE, SEM_MODE, 1 );
   422     PR_ASSERT( sem1 );
   424     strcpy( (char*)addr, "FooBar" );
   426     child_argv[0] = EXE_NAME;
   427     child_argv[1] = "-C";
   428     child_argv[2] = "-p";
   429     sprintf( buf, "%d", optPing );
   430     child_argv[3] = buf;
   431     child_argv[4] = optName;
   432     child_argv[5] = NULL;
   434     proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
   435     PR_ASSERT( proc );
   437     PR_Sleep( PR_SecondsToInterval(4));
   439     *addr = 1;
   440     for ( i = 0 ; i < optPing ; i++ )
   441     { 
   442         rc = PR_WaitSemaphore( sem1 );
   443         PR_ASSERT( PR_FAILURE != rc );
   445         (*addr)++;
   446         PR_ASSERT( (*addr % 2) == 1 );
   447         if ( optVerbose )
   448             PR_LOG( lm, msgLevel,
   449                  ( "nameshm1: Server pong: %d, i: %d", *addr, i));
   452         rc = PR_PostSemaphore( sem2 );
   453         PR_ASSERT( PR_FAILURE != rc );
   454     }
   456     rc = PR_WaitProcess( proc, &exit_status );
   457     PR_ASSERT( PR_FAILURE != rc );
   459     rc = PR_CloseSemaphore( sem1 );
   460     PR_ASSERT( PR_FAILURE != rc );
   462     rc = PR_CloseSemaphore( sem2 );
   463     PR_ASSERT( PR_FAILURE != rc );
   465     rc = PR_DeleteSemaphore( SEM_NAME1 );
   466     PR_ASSERT( PR_FAILURE != rc );
   468     rc = PR_DeleteSemaphore( SEM_NAME2 );
   469     PR_ASSERT( PR_FAILURE != rc );
   471     rc = PR_DetachSharedMemory( shm, addr );
   472     if ( PR_FAILURE == rc )
   473     {
   474         PR_LOG( lm, msgLevel,
   475             ( "nameshm1: Server: Detach: Error: %ld. OSError: %ld", 
   476                 PR_GetError(), PR_GetOSError()));
   477         failed_already = 1;
   478         return;
   479     }
   480     PR_LOG( lm, msgLevel,
   481              ( "nameshm1: Server: Detach: success: " ));
   483     rc = PR_CloseSharedMemory( shm );
   484     if ( PR_FAILURE == rc )
   485     {
   486         PR_LOG( lm, msgLevel,
   487             ( "nameshm1: Server: Close: Error: %ld. OSError: %ld", 
   488                 PR_GetError(), PR_GetOSError()));
   489         failed_already = 1;
   490         return;
   491     }
   492     PR_LOG( lm, msgLevel,
   493         ( "nameshm1: Server: Close: success: " ));
   495     rc = PR_DeleteSharedMemory( optName );
   496     if ( PR_FAILURE == rc )
   497     {
   498         PR_LOG( lm, msgLevel,
   499             ( "nameshm1: Server: Destroy: Error: %ld. OSError: %ld", 
   500                 PR_GetError(), PR_GetOSError()));
   501         failed_already = 1;
   502         return;
   503     }
   504     PR_LOG( lm, msgLevel,
   505         ( "nameshm1: Server: Destroy: success" ));
   507     return;
   508 } /* end ClientServerTest() */
   510 int main(int argc, char **argv)
   511 {
   512     {
   513         /*
   514         ** Get command line options
   515         */
   516         PLOptStatus os;
   517         PLOptState *opt = PL_CreateOptState(argc, argv, "Cdvw:s:p:i:");
   519 	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
   520         {
   521 		    if (PL_OPT_BAD == os) continue;
   522             switch (opt->option)
   523             {
   524             case 'v':  /* debug mode */
   525                 optVerbose = 1;
   526                 /* no break! fall into debug option */
   527             case 'd':  /* debug mode */
   528                 debug = 1;
   529 			    msgLevel = PR_LOG_DEBUG;
   530                 break;
   531             case 'w':  /* try writing to memory mapped read-only */
   532                 optWriteRO = 1;
   533                 break;
   534             case 'C':
   535                 optClient = 1;
   536                 break;
   537             case 's':
   538                 optSize = atol(opt->value) * 1024;
   539                 break;
   540             case 'p':
   541                 optPing = atol(opt->value);
   542                 break;
   543             case 'i':
   544                 optClientIterations = atol(opt->value);
   545                 break;
   546             default:
   547                 strcpy( optName, opt->value );
   548                 break;
   549             }
   550         }
   551 	    PL_DestroyOptState(opt);
   552     }
   554     lm = PR_NewLogModule("Test");       /* Initialize logging */
   556     PR_LOG( lm, msgLevel,
   557              ( "nameshm1: Starting" ));
   559     if ( optClient )
   560     {
   561         DoClient();
   562     } else {
   563         BasicTest();
   564         if ( failed_already != 0 )
   565             goto Finished;
   566         ReadOnlyTest();
   567         if ( failed_already != 0 )
   568             goto Finished;
   569         ClientServerTest();
   570     }
   572 Finished:
   573     if ( debug ) printf("%s\n", (failed_already)? "FAIL" : "PASS" );
   574     return( (failed_already)? 1 : 0 );
   575 }  /* main() */
   576 /* end instrumt.c */

mercurial