/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Netscape Portable Runtime (NSPR).
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
** 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>
/* command line options */
static void BasicTest( void )
{
PRUint32 i;
( "nameshm1: Begin BasicTest" ));
("nameshm1: Initial PR_DeleteSharedMemory() failed. No problem"));
} else
("nameshm1: Initial PR_DeleteSharedMemory() success"));
{
failed_already = 1;
return;
}
( "nameshm1: RW Create: success: %p", shm ));
{
failed_already = 1;
return;
}
( "nameshm1: RW Attach: success: %p", addr ));
/* fill memory with i */
for ( i = 0; i < optSize ; i++ )
{
*(addr + i) = i;
}
if ( PR_FAILURE == rc )
{
failed_already = 1;
return;
}
( "nameshm1: RW Detach: success: " ));
if ( PR_FAILURE == rc )
{
failed_already = 1;
return;
}
( "nameshm1: RW Close: success: " ));
if ( PR_FAILURE == rc )
{
failed_already = 1;
return;
}
( "nameshm1: RW Delete: success: " ));
("nameshm1: BasicTest(): Passed"));
return;
} /* end BasicTest() */
static void ReadOnlyTest( void )
{
( "nameshm1: Begin ReadOnlyTest" ));
{
failed_already = 1;
return;
}
( "nameshm1: RO Create: success: %p", shm ));
{
failed_already = 1;
return;
}
( "nameshm1: RO Attach: success: %p", roAddr ));
if ( optWriteRO )
{
failed_already = 1;
return;
}
if ( PR_FAILURE == rc )
{
failed_already = 1;
return;
}
( "nameshm1: RO Detach: success: " ));
if ( PR_FAILURE == rc )
{
failed_already = 1;
return;
}
( "nameshm1: RO Close: success: " ));
if ( PR_FAILURE == rc )
{
failed_already = 1;
return;
}
( "nameshm1: RO Destroy: success: " ));
("nameshm1: ReadOnlyTest(): Passed"));
return;
} /* end ReadOnlyTest() */
static void DoClient( void )
{
PRInt32 i;
("nameshm1: DoClient(): Starting"));
{
( "nameshm1: DoClient(): Create: Error: %ld. OSError: %ld",
PR_GetError(), PR_GetOSError()));
failed_already = 1;
return;
}
( "nameshm1: DoClient(): Create: success: %p", shm ));
{
( "nameshm1: DoClient(): Attach: Error: %ld. OSError: %ld",
PR_GetError(), PR_GetOSError()));
failed_already = 1;
return;
}
( "nameshm1: DoClient(): Attach: success: %p", addr ));
( "Client found: %s", addr));
for ( i = 0 ; i < optPing ; i++ )
{
(*addr)++;
if ( optVerbose )
( "nameshm1: Client ping: %d, i: %d", *addr, i));
}
if ( PR_FAILURE == rc )
{
( "nameshm1: DoClient(): Detach: Error: %ld. OSError: %ld",
PR_GetError(), PR_GetOSError()));
failed_already = 1;
return;
}
( "nameshm1: DoClient(): Detach: success: " ));
if ( PR_FAILURE == rc )
{
( "nameshm1: DoClient(): Close: Error: %ld. OSError: %ld",
PR_GetError(), PR_GetOSError()));
failed_already = 1;
return;
}
( "nameshm1: DoClient(): Close: success: " ));
return;
} /* end DoClient() */
static void ClientServerTest( void )
{
PRInt32 i;
( "nameshm1: Begin ClientServerTest" ));
if ( PR_FAILURE == rc )
{
( "nameshm1: Server: Destroy: failed. No problem"));
} else
( "nameshm1: Server: Destroy: success" ));
{
failed_already = 1;
return;
}
( "nameshm1: Server: Create: success: %p", shm ));
{
failed_already = 1;
return;
}
( "nameshm1: Server: Attach: success: %p", addr ));
child_argv[0] = "nameshm1";
*addr = 1;
for ( i = 0 ; i < optPing ; i++ )
{
(*addr)++;
if ( optVerbose )
( "nameshm1: Server pong: %d, i: %d", *addr, i));
}
if ( PR_FAILURE == rc )
{
( "nameshm1: Server: Detach: Error: %ld. OSError: %ld",
PR_GetError(), PR_GetOSError()));
failed_already = 1;
return;
}
( "nameshm1: Server: Detach: success: " ));
if ( PR_FAILURE == rc )
{
( "nameshm1: Server: Close: Error: %ld. OSError: %ld",
PR_GetError(), PR_GetOSError()));
failed_already = 1;
return;
}
( "nameshm1: Server: Close: success: " ));
if ( PR_FAILURE == rc )
{
( "nameshm1: Server: Destroy: Error: %ld. OSError: %ld",
PR_GetError(), PR_GetOSError()));
failed_already = 1;
return;
}
( "nameshm1: Server: Destroy: success" ));
return;
} /* end ClientServerTest() */
{
{
/*
** Get command line options
*/
{
if (PL_OPT_BAD == os) continue;
{
case 'v': /* debug mode */
optVerbose = 1;
/* no break! fall into debug option */
case 'd': /* debug mode */
debug = 1;
break;
case 'w': /* try writing to memory mapped read-only */
optWriteRO = 1;
break;
case 'C':
optClient = 1;
break;
case 's':
break;
case 'p':
break;
case 'i':
break;
default:
break;
}
}
}
( "nameshm1: Starting" ));
if ( optClient )
{
DoClient();
} else {
BasicTest();
if ( failed_already != 0 )
goto Finished;
ReadOnlyTest();
if ( failed_already != 0 )
goto Finished;
}
return( (failed_already)? 1 : 0 );
} /* main() */
/* end instrumt.c */