parent.c (3008B)
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 /* 7 ** file: parent.c 8 ** description: test the process machinery 9 */ 10 11 #include "prmem.h" 12 #include "prprf.h" 13 #include "prinit.h" 14 #include "prproces.h" 15 #include "prinrval.h" 16 17 typedef struct Child { 18 const char* name; 19 char** argv; 20 PRProcess* process; 21 PRProcessAttr* attr; 22 } Child; 23 24 /* for the default test 'cvar -c 2000' */ 25 static char* default_argv[] = {"cvar", "-c", "2000", NULL}; 26 27 static void PrintUsage(void) { 28 PR_fprintf(PR_GetSpecialFD(PR_StandardError), 29 "Usage: parent [-d] child [options]\n"); 30 } 31 32 int main(int argc, char** argv) { 33 PRStatus rv; 34 PRInt32 test_status = 1; 35 PRIntervalTime t_start, t_elapsed; 36 PRFileDesc* debug = NULL; 37 Child* child = PR_NEWZAP(Child); 38 39 if (1 == argc) { 40 /* no command-line arguments: run the default test */ 41 child->argv = default_argv; 42 } else { 43 argv += 1; /* don't care about our program name */ 44 while (*argv != NULL && argv[0][0] == '-') { 45 if (argv[0][1] == 'd') { 46 debug = PR_GetSpecialFD(PR_StandardError); 47 } else { 48 PrintUsage(); 49 return 2; /* not sufficient */ 50 } 51 argv += 1; 52 } 53 child->argv = argv; 54 } 55 56 if (NULL == *child->argv) { 57 PrintUsage(); 58 return 2; 59 } 60 61 child->name = *child->argv; 62 if (NULL != debug) { 63 PR_fprintf(debug, "Forking %s\n", child->name); 64 } 65 66 child->attr = PR_NewProcessAttr(); 67 PR_ProcessAttrSetStdioRedirect(child->attr, PR_StandardOutput, 68 PR_GetSpecialFD(PR_StandardOutput)); 69 PR_ProcessAttrSetStdioRedirect(child->attr, PR_StandardError, 70 PR_GetSpecialFD(PR_StandardError)); 71 72 t_start = PR_IntervalNow(); 73 child->process = 74 PR_CreateProcess(child->name, child->argv, NULL, child->attr); 75 t_elapsed = (PRIntervalTime)(PR_IntervalNow() - t_start); 76 77 PR_DestroyProcessAttr(child->attr); 78 79 test_status = (NULL == child->process) ? 1 : 0; 80 if (NULL != debug) { 81 PR_fprintf(debug, "Child was %sforked\n", (0 == test_status) ? "" : "NOT "); 82 if (0 == test_status) 83 PR_fprintf(debug, "PR_CreateProcess took %lu microseconds\n", 84 PR_IntervalToMicroseconds(t_elapsed)); 85 } 86 87 if (0 == test_status) { 88 if (NULL != debug) { 89 PR_fprintf(debug, "Waiting for child to exit\n"); 90 } 91 rv = PR_WaitProcess(child->process, &test_status); 92 if (PR_SUCCESS == rv) { 93 if (NULL != debug) 94 PR_fprintf(debug, "Child exited %s\n", 95 (0 == test_status) ? "successfully" : "with error"); 96 } else { 97 test_status = 1; 98 if (NULL != debug) { 99 PR_fprintf(debug, "PR_WaitProcess failed\n"); 100 } 101 } 102 } 103 PR_DELETE(child); 104 PR_Cleanup(); 105 return test_status; 106 107 } /* main */ 108 109 /* parent.c */