tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 */