anonfm.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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/. */
  5. /*
  6. ** File: anonfm.c
  7. ** Description: Test anonymous file map
  8. **
  9. ** Synopsis: anonfm [options] [dirName]
  10. **
  11. ** Options:
  12. ** -d enable debug mode
  13. ** -h display a help message
  14. ** -s <n> size of the anonymous memory map, in KBytes. default: 100KBytes.
  15. ** -C 1 Operate this process as ClientOne()
  16. ** -C 2 Operate this process as ClientTwo()
  17. **
  18. ** anonfn.c contains two tests, corresponding to the two protocols for
  19. ** passing an anonymous file map to a child process.
  20. **
  21. ** ServerOne()/ClientOne() tests the passing of "raw" file map; it uses
  22. ** PR_CreateProcess() [for portability of the test case] to create the
  23. ** child process, but does not use the PRProcessAttr structure for
  24. ** passing the file map data.
  25. **
  26. ** ServerTwo()/ClientTwo() tests the passing of the file map using the
  27. ** PRProcessAttr structure.
  28. **
  29. */
  30. #include <plgetopt.h>
  31. #include <nspr.h>
  32. #include <private/primpl.h>
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. /*
  37. ** Test harness infrastructure
  38. */
  39. PRLogModuleInfo *lm;
  40. PRLogModuleLevel msgLevel = PR_LOG_NONE;
  41. PRUint32 failed_already = 0;
  42. PRIntn debug = 0;
  43. PRIntn client = 0; /* invoke client, style */
  44. char dirName[512] = "."; /* directory name to contain anon mapped file */
  45. PRSize fmSize = (100 * 1024 );
  46. PRUint32 fmMode = 0600;
  47. PRFileMapProtect fmProt = PR_PROT_READWRITE;
  48. const char *fmEnvName = "nsprFileMapEnvVariable";
  49. /*
  50. ** Emit help text for this test
  51. */
  52. static void Help( void )
  53. {
  54. printf("anonfm [options] [dirName]\n");
  55. printf("-d -- enable debug mode\n");
  56. printf("dirName is alternate directory name. Default: . (current directory)\n");
  57. exit(1);
  58. } /* end Help() */
  59. /*
  60. ** ClientOne() --
  61. */
  62. static void ClientOne( void )
  63. {
  64. PRFileMap *fm;
  65. char *fmString;
  66. char *addr;
  67. PRStatus rc;
  68. PR_LOG(lm, msgLevel,
  69. ("ClientOne() starting"));
  70. fmString = PR_GetEnv( fmEnvName );
  71. if ( NULL == fmString ) {
  72. failed_already = 1;
  73. PR_LOG(lm, msgLevel,
  74. ("ClientOne(): PR_Getenv() failed"));
  75. return;
  76. }
  77. PR_LOG(lm, msgLevel,
  78. ("ClientOne(): PR_Getenv(): found: %s", fmString));
  79. fm = PR_ImportFileMapFromString( fmString );
  80. if ( NULL == fm ) {
  81. failed_already = 1;
  82. PR_LOG(lm, msgLevel,
  83. ("ClientOne(): PR_ImportFileMapFromString() failed"));
  84. return;
  85. }
  86. PR_LOG(lm, msgLevel,
  87. ("ClientOne(): PR_ImportFileMapFromString(): fm: %p", fm ));
  88. addr = PR_MemMap( fm, LL_ZERO, fmSize );
  89. if ( NULL == addr ) {
  90. failed_already = 1;
  91. PR_LOG(lm, msgLevel,
  92. ("ClientOne(): PR_MemMap() failed, OSError: %d", PR_GetOSError() ));
  93. return;
  94. }
  95. PR_LOG(lm, msgLevel,
  96. ("ClientOne(): PR_MemMap(): addr: %p", addr ));
  97. /* write to memory map to release server */
  98. *addr = 1;
  99. rc = PR_MemUnmap( addr, fmSize );
  100. PR_ASSERT( rc == PR_SUCCESS );
  101. PR_LOG(lm, msgLevel,
  102. ("ClientOne(): PR_MemUnap(): success" ));
  103. rc = PR_CloseFileMap( fm );
  104. if ( PR_FAILURE == rc ) {
  105. failed_already = 1;
  106. PR_LOG(lm, msgLevel,
  107. ("ClientOne(): PR_MemUnap() failed, OSError: %d", PR_GetOSError() ));
  108. return;
  109. }
  110. PR_LOG(lm, msgLevel,
  111. ("ClientOne(): PR_CloseFileMap(): success" ));
  112. return;
  113. } /* end ClientOne() */
  114. /*
  115. ** ClientTwo() --
  116. */
  117. static void ClientTwo( void )
  118. {
  119. failed_already = 1;
  120. } /* end ClientTwo() */
  121. /*
  122. ** ServerOne() --
  123. */
  124. static void ServerOne( void )
  125. {
  126. PRFileMap *fm;
  127. PRStatus rc;
  128. PRIntn i;
  129. char *addr;
  130. char fmString[256];
  131. char envBuf[256];
  132. char *child_argv[8];
  133. PRProcess *proc;
  134. PRInt32 exit_status;
  135. PR_LOG(lm, msgLevel,
  136. ("ServerOne() starting"));
  137. fm = PR_OpenAnonFileMap( dirName, fmSize, fmProt );
  138. if ( NULL == fm ) {
  139. failed_already = 1;
  140. PR_LOG(lm, msgLevel,
  141. ("PR_OpenAnonFileMap() failed"));
  142. return;
  143. }
  144. PR_LOG(lm, msgLevel,
  145. ("ServerOne(): FileMap: %p", fm ));
  146. rc = PR_ExportFileMapAsString( fm, sizeof(fmString), fmString );
  147. if ( PR_FAILURE == rc ) {
  148. failed_already = 1;
  149. PR_LOG(lm, msgLevel,
  150. ("PR_ExportFileMap() failed"));
  151. return;
  152. }
  153. /*
  154. ** put the string into the environment
  155. */
  156. PR_snprintf( envBuf, sizeof(envBuf), "%s=%s", fmEnvName, fmString);
  157. putenv( envBuf );
  158. addr = PR_MemMap( fm, LL_ZERO, fmSize );
  159. if ( NULL == addr ) {
  160. failed_already = 1;
  161. PR_LOG(lm, msgLevel,
  162. ("PR_MemMap() failed"));
  163. return;
  164. }
  165. /* set initial value for client */
  166. for (i = 0; i < (PRIntn)fmSize ; i++ ) {
  167. *(addr+i) = 0x00;
  168. }
  169. PR_LOG(lm, msgLevel,
  170. ("ServerOne(): PR_MemMap(): addr: %p", addr ));
  171. /*
  172. ** set arguments for child process
  173. */
  174. child_argv[0] = "anonfm";
  175. child_argv[1] = "-C";
  176. child_argv[2] = "1";
  177. child_argv[3] = NULL;
  178. proc = PR_CreateProcess(child_argv[0], child_argv, NULL, NULL);
  179. PR_ASSERT( proc );
  180. PR_LOG(lm, msgLevel,
  181. ("ServerOne(): PR_CreateProcess(): proc: %x", proc ));
  182. /*
  183. ** ClientOne() will set the memory to 1
  184. */
  185. PR_LOG(lm, msgLevel,
  186. ("ServerOne(): waiting on Client, *addr: %x", *addr ));
  187. while( *addr == 0x00 ) {
  188. if ( debug ) {
  189. fprintf(stderr, ".");
  190. }
  191. PR_Sleep(PR_MillisecondsToInterval(300));
  192. }
  193. if ( debug ) {
  194. fprintf(stderr, "\n");
  195. }
  196. PR_LOG(lm, msgLevel,
  197. ("ServerOne(): Client responded" ));
  198. rc = PR_WaitProcess( proc, &exit_status );
  199. PR_ASSERT( PR_FAILURE != rc );
  200. rc = PR_MemUnmap( addr, fmSize);
  201. if ( PR_FAILURE == rc ) {
  202. failed_already = 1;
  203. PR_LOG(lm, msgLevel,
  204. ("PR_MemUnmap() failed"));
  205. return;
  206. }
  207. PR_LOG(lm, msgLevel,
  208. ("ServerOne(): PR_MemUnmap(): success" ));
  209. rc = PR_CloseFileMap(fm);
  210. if ( PR_FAILURE == rc ) {
  211. failed_already = 1;
  212. PR_LOG(lm, msgLevel,
  213. ("PR_CloseFileMap() failed"));
  214. return;
  215. }
  216. PR_LOG(lm, msgLevel,
  217. ("ServerOne(): PR_CloseFileMap() success" ));
  218. return;
  219. } /* end ServerOne() */
  220. /*
  221. ** ServerTwo() --
  222. */
  223. static void ServerTwo( void )
  224. {
  225. PR_LOG(lm, msgLevel,
  226. ("ServerTwo(): Not implemented yet" ));
  227. } /* end ServerTwo() */
  228. int main(int argc, char **argv)
  229. {
  230. {
  231. /*
  232. ** Get command line options
  233. */
  234. PLOptStatus os;
  235. PLOptState *opt = PL_CreateOptState(argc, argv, "hdC:");
  236. while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
  237. {
  238. if (PL_OPT_BAD == os) {
  239. continue;
  240. }
  241. switch (opt->option)
  242. {
  243. case 'C': /* Client style */
  244. client = atol(opt->value);
  245. break;
  246. case 's': /* file size */
  247. fmSize = atol( opt->value ) * 1024;
  248. break;
  249. case 'd': /* debug */
  250. debug = 1;
  251. msgLevel = PR_LOG_DEBUG;
  252. break;
  253. case 'h': /* help message */
  254. Help();
  255. break;
  256. default:
  257. strcpy(dirName, opt->value);
  258. break;
  259. }
  260. }
  261. PL_DestroyOptState(opt);
  262. }
  263. lm = PR_NewLogModule("Test"); /* Initialize logging */
  264. if ( client == 1 ) {
  265. ClientOne();
  266. } else if ( client == 2 ) {
  267. ClientTwo();
  268. } else {
  269. ServerOne();
  270. if ( failed_already ) {
  271. goto Finished;
  272. }
  273. ServerTwo();
  274. }
  275. Finished:
  276. if ( debug ) {
  277. printf("%s\n", (failed_already)? "FAIL" : "PASS");
  278. }
  279. return( (failed_already == PR_TRUE )? 1 : 0 );
  280. } /* main() */
  281. /* end anonfm.c */