/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* * File : nameshm1 . c - - Test Named Shared Memory
* *
* * Description :
* * nameshm1 tests Named Shared Memory . nameshm1 performs two tests of
* * named shared memory .
* *
* * The first test is a basic test . The basic test operates as a single
* * process . The process exercises all the API elements of the facility .
* * This test also attempts to write to all locations in the shared
* * memory .
* *
* * The second test is a client - server test . The client - server test
* * creates a new instance of nameshm1 , passing the - C argument to the
* * new process ; this creates the client - side process . The server - side
* * ( the instance of nameshm1 created from the command line ) and the
* * client - side interact via inter - process semaphores to verify that the
* * shared memory segment can be read and written by both sides in a
* * synchronized maner .
* *
* * Note : Because this test runs in two processes , the log files created
* * by the test are not in chronological sequence ; makes it hard to read .
* * As a temporary circumvention , I changed the definition ( s ) of the
* * _ PUT_LOG ( ) macro in prlog . c to force a flushall ( ) , or equivalent .
* * This causes the log entries to be emitted in true chronological
* * order .
* *
* * Synopsis : nameshm1 [ options ] [ name ]
* *
* * Options :
* * - d Enables debug trace via PR_LOG ( )
* * - v Enables verbose mode debug trace via PR_LOG ( )
* * - w Causes the basic test to attempt to write to the segment
* * mapped as read - only . When this option is specified , the
* * test should crash with a seg - fault ; this is a destructive
* * test and is considered successful when it seg - faults .
* *
* * - C Causes nameshm1 to start as the client - side of a
* * client - server pair of processes . Only the instance
* * of nameshm1 operating as the server - side process should
* * specify the - C option when creating the client - side process ;
* * the - C option should not be specified at the command line .
* * The client - side uses the shared memory segment created by
* * the server - side to communicate with the server - side
* * process .
* *
* * - p < n > Specify the number of iterations the client - server tests
* * should perform . Default : 1000 .
* *
* * - s < n > Size , in KBytes ( 1024 ) , of the shared memory segment .
* * Default : ( 10 * 1024 )
* *
* * - i < n > Number of client - side iterations . Default : 3
* *
* * name specifies the name of the shared memory segment to be used .
* * Default : / tmp / xxxNSPRshm
* *
* *
* * See also : prshm . h
* *
* * / lth . Aug - 1999 .
*/
#include <plgetopt.h>
#include <nspr.h>
#include <stdlib.h>
#include <string.h>
#include <
private /primpl.h>
#ifdef DEBUG
# define SEM_D
"D"
#else
# define SEM_D
#endif
#ifdef IS_64
# define SEM_64
"64"
#else
# define SEM_64
#endif
#define SEM_NAME1
"/tmp/nameshmSEM1" SEM_D SEM_64
#define SEM_NAME2
"/tmp/nameshmSEM2" SEM_D SEM_64
#define OPT_NAME
"/tmp/xxxNSPRshm" SEM_D SEM_64
#define EXE_NAME
"nameshm1"
#define SEM_MODE
0666
#define SHM_MODE
0666
#define NameSize (
1024 )
PRIntn debug =
0 ;
PRIntn failed_already =
0 ;
PRLogModuleLevel msgLevel = PR_LOG_NONE;
PRLogModuleInfo* lm;
/* command line options */
PRIntn optDebug =
0 ;
PRIntn optVerbose =
0 ;
PRUint32 optWriteRO =
0 ;
/* test write to read-only memory. should crash */
PRUint32 optClient =
0 ;
PRUint32 optCreate =
1 ;
PRUint32 optAttachRW =
1 ;
PRUint32 optAttachRO =
1 ;
PRUint32 optClose =
1 ;
PRUint32 optDelete =
1 ;
PRInt32 optPing =
1000 ;
PRUint32 optSize = (
10 *
1024 );
PRInt32 optClientIterations =
3 ;
char optName[NameSize] = OPT_NAME;
char buf[
1024 ] =
"" ;
static void BasicTest(
void ) {
PRSharedMemory* shm;
char* addr;
/* address of shared memory segment */
PRUint32 i;
PRInt32 rc;
PR_LOG(lm, msgLevel, (
"nameshm1: Begin BasicTest" ));
if (PR_FAILURE == PR_DeleteSharedMemory(optName)) {
PR_LOG(lm, msgLevel,
(
"nameshm1: Initial PR_DeleteSharedMemory() failed. No problem" ));
}
else
PR_LOG(lm, msgLevel, (
"nameshm1: Initial PR_DeleteSharedMemory() success" ));
shm = PR_OpenSharedMemory(optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL),
SHM_MODE);
if (NULL == shm) {
PR_LOG(lm, msgLevel,
(
"nameshm1: RW Create: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: RW Create: success: %p" , shm));
addr = PR_AttachSharedMemory(shm,
0 );
if (NULL == addr) {
PR_LOG(lm, msgLevel,
(
"nameshm1: RW Attach: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: RW Attach: success: %p" , addr));
/* fill memory with i */
for (i =
0 ; i < optSize; i++) {
*(addr + i) = i;
}
rc = PR_DetachSharedMemory(shm, addr);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel,
(
"nameshm1: RW Detach: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: RW Detach: success: " ));
rc = PR_CloseSharedMemory(shm);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel,
(
"nameshm1: RW Close: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: RW Close: success: " ));
rc = PR_DeleteSharedMemory(optName);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel,
(
"nameshm1: RW Delete: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: RW Delete: success: " ));
PR_LOG(lm, msgLevel, (
"nameshm1: BasicTest(): Passed" ));
return ;
}
/* end BasicTest() */
static void ReadOnlyTest(
void ) {
PRSharedMemory* shm;
char* roAddr;
/* read-only address of shared memory segment */
PRInt32 rc;
PR_LOG(lm, msgLevel, (
"nameshm1: Begin ReadOnlyTest" ));
shm = PR_OpenSharedMemory(optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL),
SHM_MODE);
if (NULL == shm) {
PR_LOG(lm, msgLevel,
(
"nameshm1: RO Create: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: RO Create: success: %p" , shm));
roAddr = PR_AttachSharedMemory(shm, PR_SHM_READONLY);
if (NULL == roAddr) {
PR_LOG(lm, msgLevel,
(
"nameshm1: RO Attach: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: RO Attach: success: %p" , roAddr));
if (optWriteRO) {
*roAddr =
0 x00;
/* write to read-only memory */
failed_already =
1 ;
PR_LOG(lm, msgLevel, (
"nameshm1: Wrote to read-only memory segment!" ));
return ;
}
rc = PR_DetachSharedMemory(shm, roAddr);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel,
(
"nameshm1: RO Detach: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: RO Detach: success: " ));
rc = PR_CloseSharedMemory(shm);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel,
(
"nameshm1: RO Close: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: RO Close: success: " ));
rc = PR_DeleteSharedMemory(optName);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel,
(
"nameshm1: RO Destroy: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: RO Destroy: success: " ));
PR_LOG(lm, msgLevel, (
"nameshm1: ReadOnlyTest(): Passed" ));
return ;
}
/* end ReadOnlyTest() */
static void DoClient(
void ) {
PRStatus rc;
PRSem *sem1, *sem2;
PRSharedMemory* shm;
PRUint32* addr;
PRInt32 i;
PR_LOG(lm, msgLevel, (
"nameshm1: DoClient(): Starting" ));
sem1 = PR_OpenSemaphore(SEM_NAME1,
0 ,
0 ,
0 );
PR_ASSERT(sem1);
sem2 = PR_OpenSemaphore(SEM_NAME2,
0 ,
0 ,
0 );
PR_ASSERT(sem1);
shm = PR_OpenSharedMemory(optName, optSize,
0 , SHM_MODE);
if (NULL == shm) {
PR_LOG(lm, msgLevel,
(
"nameshm1: DoClient(): Create: Error: %ld. OSError: %ld" ,
PR_GetError(), PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: DoClient(): Create: success: %p" , shm));
addr = PR_AttachSharedMemory(shm,
0 );
if (NULL == addr) {
PR_LOG(lm, msgLevel,
(
"nameshm1: DoClient(): Attach: Error: %ld. OSError: %ld" ,
PR_GetError(), PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: DoClient(): Attach: success: %p" , addr));
PR_LOG(lm, msgLevel, (
"Client found: %s" , addr));
PR_Sleep(PR_SecondsToInterval(
4 ));
for (i =
0 ; i < optPing; i++) {
rc = PR_WaitSemaphore(sem2);
PR_ASSERT(PR_FAILURE != rc);
(*addr)++;
PR_ASSERT((*addr %
2 ) ==
0 );
if (optVerbose)
PR_LOG(lm, msgLevel, (
"nameshm1: Client ping: %d, i: %d" , *addr, i));
rc = PR_PostSemaphore(sem1);
PR_ASSERT(PR_FAILURE != rc);
}
rc = PR_CloseSemaphore(sem1);
PR_ASSERT(PR_FAILURE != rc);
rc = PR_CloseSemaphore(sem2);
PR_ASSERT(PR_FAILURE != rc);
rc = PR_DetachSharedMemory(shm, addr);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel,
(
"nameshm1: DoClient(): Detach: Error: %ld. OSError: %ld" ,
PR_GetError(), PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: DoClient(): Detach: success: " ));
rc = PR_CloseSharedMemory(shm);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel,
(
"nameshm1: DoClient(): Close: Error: %ld. OSError: %ld" ,
PR_GetError(), PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: DoClient(): Close: success: " ));
return ;
}
/* end DoClient() */
static void ClientServerTest(
void ) {
PRStatus rc;
PRSem *sem1, *sem2;
PRProcess* proc;
PRInt32 exit_status;
PRSharedMemory* shm;
PRUint32* addr;
PRInt32 i;
char* child_argv[
8 ];
char buf[
24 ];
PR_LOG(lm, msgLevel, (
"nameshm1: Begin ClientServerTest" ));
rc = PR_DeleteSharedMemory(optName);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel, (
"nameshm1: Server: Destroy: failed. No problem" ));
}
else
PR_LOG(lm, msgLevel, (
"nameshm1: Server: Destroy: success" ));
shm = PR_OpenSharedMemory(optName, optSize, (PR_SHM_CREATE | PR_SHM_EXCL),
SHM_MODE);
if (NULL == shm) {
PR_LOG(lm, msgLevel,
(
"nameshm1: Server: Create: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: Server: Create: success: %p" , shm));
addr = PR_AttachSharedMemory(shm,
0 );
if (NULL == addr) {
PR_LOG(lm, msgLevel,
(
"nameshm1: Server: Attach: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: Server: Attach: success: %p" , addr));
sem1 = PR_OpenSemaphore(SEM_NAME1, PR_SEM_CREATE, SEM_MODE,
0 );
PR_ASSERT(sem1);
sem2 = PR_OpenSemaphore(SEM_NAME2, PR_SEM_CREATE, SEM_MODE,
1 );
PR_ASSERT(sem1);
strcpy((char*)addr,
"FooBar" );
child_argv[
0 ] = EXE_NAME;
child_argv[
1 ] =
"-C" ;
child_argv[
2 ] =
"-p" ;
sprintf(buf,
"%d" , optPing);
child_argv[
3 ] = buf;
child_argv[
4 ] = optName;
child_argv[
5 ] = NULL;
proc = PR_CreateProcess(child_argv[
0 ], child_argv, NULL, NULL);
PR_ASSERT(proc);
PR_Sleep(PR_SecondsToInterval(
4 ));
*addr =
1 ;
for (i =
0 ; i < optPing; i++) {
rc = PR_WaitSemaphore(sem1);
PR_ASSERT(PR_FAILURE != rc);
(*addr)++;
PR_ASSERT((*addr %
2 ) ==
1 );
if (optVerbose)
PR_LOG(lm, msgLevel, (
"nameshm1: Server pong: %d, i: %d" , *addr, i));
rc = PR_PostSemaphore(sem2);
PR_ASSERT(PR_FAILURE != rc);
}
rc = PR_WaitProcess(proc, &exit_status);
PR_ASSERT(PR_FAILURE != rc);
rc = PR_CloseSemaphore(sem1);
PR_ASSERT(PR_FAILURE != rc);
rc = PR_CloseSemaphore(sem2);
PR_ASSERT(PR_FAILURE != rc);
rc = PR_DeleteSemaphore(SEM_NAME1);
PR_ASSERT(PR_FAILURE != rc);
rc = PR_DeleteSemaphore(SEM_NAME2);
PR_ASSERT(PR_FAILURE != rc);
rc = PR_DetachSharedMemory(shm, addr);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel,
(
"nameshm1: Server: Detach: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: Server: Detach: success: " ));
rc = PR_CloseSharedMemory(shm);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel,
(
"nameshm1: Server: Close: Error: %ld. OSError: %ld" , PR_GetError(),
PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: Server: Close: success: " ));
rc = PR_DeleteSharedMemory(optName);
if (PR_FAILURE == rc) {
PR_LOG(lm, msgLevel,
(
"nameshm1: Server: Destroy: Error: %ld. OSError: %ld" ,
PR_GetError(), PR_GetOSError()));
failed_already =
1 ;
return ;
}
PR_LOG(lm, msgLevel, (
"nameshm1: Server: Destroy: success" ));
return ;
}
/* end ClientServerTest() */
int main(int argc, char** argv) {
{
/*
* * Get command line options
*/
PLOptStatus os;
PLOptState* opt = PL_CreateOptState(argc, argv,
"Cdvw:s:p:i:" );
while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
if (PL_OPT_BAD == os) {
continue ;
}
switch (opt->option) {
case 'v' :
/* debug mode */
optVerbose =
1 ;
/* no break! fall into debug option */
case 'd' :
/* debug mode */
debug =
1 ;
msgLevel = PR_LOG_DEBUG;
break ;
case 'w' :
/* try writing to memory mapped read-only */
optWriteRO =
1 ;
break ;
case 'C' :
optClient =
1 ;
break ;
case 's' :
optSize = atol(opt->value) *
1024 ;
break ;
case 'p' :
optPing = atol(opt->value);
break ;
case 'i' :
optClientIterations = atol(opt->value);
break ;
default :
strcpy(optName, opt->value);
break ;
}
}
PL_DestroyOptState(opt);
}
lm = PR_NewLogModule(
"Test" );
/* Initialize logging */
PR_LOG(lm, msgLevel, (
"nameshm1: Starting" ));
if (optClient) {
DoClient();
}
else {
BasicTest();
if (failed_already !=
0 ) {
goto Finished;
}
ReadOnlyTest();
if (failed_already !=
0 ) {
goto Finished;
}
ClientServerTest();
}
Finished:
if (debug) {
printf(
"%s\n" , (failed_already) ?
"FAIL" :
"PASS" );
}
return ((failed_already) ?
1 :
0 );
}
/* main() */
/* end instrumt.c */
Messung V0.5 in Prozent C=97 H=97 G=96
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-08-27)
¤
*© Formatika GbR, Deutschland