Wed, 31 Dec 2014 06:09:35 +0100
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 */