123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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: anonfm.c
- ** Description: Test anonymous file map
- **
- ** Synopsis: anonfm [options] [dirName]
- **
- ** Options:
- ** -d enable debug mode
- ** -h display a help message
- ** -s <n> size of the anonymous memory map, in KBytes. default: 100KBytes.
- ** -C 1 Operate this process as ClientOne()
- ** -C 2 Operate this process as ClientTwo()
- **
- ** anonfn.c contains two tests, corresponding to the two protocols for
- ** passing an anonymous file map to a child process.
- **
- ** ServerOne()/ClientOne() tests the passing of "raw" file map; it uses
- ** PR_CreateProcess() [for portability of the test case] to create the
- ** child process, but does not use the PRProcessAttr structure for
- ** passing the file map data.
- **
- ** ServerTwo()/ClientTwo() tests the passing of the file map using the
- ** PRProcessAttr structure.
- **
- */
- #include <plgetopt.h>
- #include <nspr.h>
- #include <private/primpl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- /*
- ** Test harness infrastructure
- */
- PRLogModuleInfo *lm;
- PRLogModuleLevel msgLevel = PR_LOG_NONE;
- PRUint32 failed_already = 0;
- PRIntn debug = 0;
- PRIntn client = 0; /* invoke client, style */
- char dirName[512] = "."; /* directory name to contain anon mapped file */
- PRSize fmSize = (100 * 1024 );
- PRUint32 fmMode = 0600;
- PRFileMapProtect fmProt = PR_PROT_READWRITE;
- const char *fmEnvName = "nsprFileMapEnvVariable";
- /*
- ** Emit help text for this test
- */
- static void Help( void )
- {
- printf("anonfm [options] [dirName]\n");
- printf("-d -- enable debug mode\n");
- printf("dirName is alternate directory name. Default: . (current directory)\n");
- exit(1);
- } /* end Help() */
- /*
- ** ClientOne() --
- */
- static void ClientOne( void )
- {
- PRFileMap *fm;
- char *fmString;
- char *addr;
- PRStatus rc;
- PR_LOG(lm, msgLevel,
- ("ClientOne() starting"));
- fmString = PR_GetEnv( fmEnvName );
- if ( NULL == fmString ) {
- failed_already = 1;
- PR_LOG(lm, msgLevel,
- ("ClientOne(): PR_Getenv() failed"));
- return;
- }
- PR_LOG(lm, msgLevel,
- ("ClientOne(): PR_Getenv(): found: %s", fmString));
- fm = PR_ImportFileMapFromString( fmString );
- if ( NULL == fm ) {
- failed_already = 1;
- PR_LOG(lm, msgLevel,
- ("ClientOne(): PR_ImportFileMapFromString() failed"));
- return;
- }
- PR_LOG(lm, msgLevel,
- ("ClientOne(): PR_ImportFileMapFromString(): fm: %p", fm ));
- addr = PR_MemMap( fm, LL_ZERO, fmSize );
- if ( NULL == addr ) {
- failed_already = 1;
- PR_LOG(lm, msgLevel,
- ("ClientOne(): PR_MemMap() failed, OSError: %d", PR_GetOSError() ));
- return;
- }
- PR_LOG(lm, msgLevel,
- ("ClientOne(): PR_MemMap(): addr: %p", addr ));
- /* write to memory map to release server */
- *addr = 1;
- rc = PR_MemUnmap( addr, fmSize );
- PR_ASSERT( rc == PR_SUCCESS );
- PR_LOG(lm, msgLevel,
- ("ClientOne(): PR_MemUnap(): success" ));
- rc = PR_CloseFileMap( fm );
- if ( PR_FAILURE == rc ) {
- failed_already = 1;
- PR_LOG(lm, msgLevel,
- ("ClientOne(): PR_MemUnap() failed, OSError: %d", PR_GetOSError() ));
- return;
- }
- PR_LOG(lm, msgLevel,
- ("ClientOne(): PR_CloseFileMap(): success" ));
- return;
- } /* end ClientOne() */
- /*
- ** ClientTwo() --
- */
- static void ClientTwo( void )
- {
- failed_already = 1;
- } /* end ClientTwo() */
- /*
- ** ServerOne() --
- */
- static void ServerOne( void )
- {
- PRFileMap *fm;
- PRStatus rc;
- PRIntn i;
- char *addr;
- char fmString[256];
- char envBuf[256];
- char *child_argv[8];
- PRProcess *proc;
- PRInt32 exit_status;
- PR_LOG(lm, msgLevel,
- ("ServerOne() starting"));
- fm = PR_OpenAnonFileMap( dirName, fmSize, fmProt );
- if ( NULL == fm ) {
- failed_already = 1;
- PR_LOG(lm, msgLevel,
- ("PR_OpenAnonFileMap() failed"));
- return;
- }
- PR_LOG(lm, msgLevel,
- ("ServerOne(): FileMap: %p", fm ));
- rc = PR_ExportFileMapAsString( fm, sizeof(fmString), fmString );
- if ( PR_FAILURE == rc ) {
- failed_already = 1;
- PR_LOG(lm, msgLevel,
- ("PR_ExportFileMap() failed"));
- return;
- }
- /*
- ** put the string into the environment
- */
- PR_snprintf( envBuf, sizeof(envBuf), "%s=%s", fmEnvName, fmString);
- putenv( envBuf );
- addr = PR_MemMap( fm, LL_ZERO, fmSize );
- if ( NULL == addr ) {
- failed_already = 1;
- PR_LOG(lm, msgLevel,
- ("PR_MemMap() failed"));
- return;
- }
- /* set initial value for client */
- for (i = 0; i < (PRIntn)fmSize ; i++ ) {
- *(addr+i) = 0x00;
- }
- PR_LOG(lm, msgLevel,
- ("ServerOne(): PR_MemMap(): addr: %p", addr ));
- /*
- ** set arguments for child process
- */
- child_argv[0] = "anonfm";
- child_argv[1] = "-C";
- child_argv[2] = "1";
- child_argv[3] = NULL;
- proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
- PR_ASSERT( proc );
- PR_LOG(lm, msgLevel,
- ("ServerOne(): PR_CreateProcess(): proc: %x", proc ));
- /*
- ** ClientOne() will set the memory to 1
- */
- PR_LOG(lm, msgLevel,
- ("ServerOne(): waiting on Client, *addr: %x", *addr ));
- while( *addr == 0x00 ) {
- if ( debug ) {
- fprintf(stderr, ".");
- }
- PR_Sleep(PR_MillisecondsToInterval(300));
- }
- if ( debug ) {
- fprintf(stderr, "\n");
- }
- PR_LOG(lm, msgLevel,
- ("ServerOne(): Client responded" ));
- rc = PR_WaitProcess( proc, &exit_status );
- PR_ASSERT( PR_FAILURE != rc );
- rc = PR_MemUnmap( addr, fmSize);
- if ( PR_FAILURE == rc ) {
- failed_already = 1;
- PR_LOG(lm, msgLevel,
- ("PR_MemUnmap() failed"));
- return;
- }
- PR_LOG(lm, msgLevel,
- ("ServerOne(): PR_MemUnmap(): success" ));
- rc = PR_CloseFileMap(fm);
- if ( PR_FAILURE == rc ) {
- failed_already = 1;
- PR_LOG(lm, msgLevel,
- ("PR_CloseFileMap() failed"));
- return;
- }
- PR_LOG(lm, msgLevel,
- ("ServerOne(): PR_CloseFileMap() success" ));
- return;
- } /* end ServerOne() */
- /*
- ** ServerTwo() --
- */
- static void ServerTwo( void )
- {
- PR_LOG(lm, msgLevel,
- ("ServerTwo(): Not implemented yet" ));
- } /* end ServerTwo() */
- int main(int argc, char **argv)
- {
- {
- /*
- ** Get command line options
- */
- PLOptStatus os;
- PLOptState *opt = PL_CreateOptState(argc, argv, "hdC:");
- while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
- {
- if (PL_OPT_BAD == os) {
- continue;
- }
- switch (opt->option)
- {
- case 'C': /* Client style */
- client = atol(opt->value);
- break;
- case 's': /* file size */
- fmSize = atol( opt->value ) * 1024;
- break;
- case 'd': /* debug */
- debug = 1;
- msgLevel = PR_LOG_DEBUG;
- break;
- case 'h': /* help message */
- Help();
- break;
- default:
- strcpy(dirName, opt->value);
- break;
- }
- }
- PL_DestroyOptState(opt);
- }
- lm = PR_NewLogModule("Test"); /* Initialize logging */
- if ( client == 1 ) {
- ClientOne();
- } else if ( client == 2 ) {
- ClientTwo();
- } else {
- ServerOne();
- if ( failed_already ) {
- goto Finished;
- }
- ServerTwo();
- }
- Finished:
- if ( debug ) {
- printf("%s\n", (failed_already)? "FAIL" : "PASS");
- }
- return( (failed_already == PR_TRUE )? 1 : 0 );
- } /* main() */
- /* end anonfm.c */
|