tor-browser

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

pipeping.c (4156B)


      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: pipeping.c
      8 *
      9 * Description:
     10 * This test runs in conjunction with the pipepong test.
     11 * This test creates two pipes and redirects the stdin and
     12 * stdout of the pipepong test to the pipes.  Then this
     13 * test writes "ping" to the pipepong test and the pipepong
     14 * test writes "pong" back.  To run this pair of tests,
     15 * just invoke pipeping.
     16 *
     17 * Tested areas: process creation, pipes, file descriptor
     18 * inheritance, standard I/O redirection.
     19 */
     20 
     21 #include "prerror.h"
     22 #include "prio.h"
     23 #include "prproces.h"
     24 
     25 #include <stdio.h>
     26 #include <stdlib.h>
     27 #include <string.h>
     28 
     29 static char* child_argv[] = {"pipepong", NULL};
     30 
     31 #define NUM_ITERATIONS 10
     32 
     33 int main(int argc, char** argv) {
     34  PRFileDesc* in_pipe[2];
     35  PRFileDesc* out_pipe[2];
     36  PRStatus status;
     37  PRProcess* process;
     38  PRProcessAttr* attr;
     39  char buf[1024];
     40  PRInt32 nBytes;
     41  PRInt32 exitCode;
     42  int idx;
     43 
     44  status = PR_CreatePipe(&in_pipe[0], &in_pipe[1]);
     45  if (status == PR_FAILURE) {
     46    fprintf(stderr, "PR_CreatePipe failed\n");
     47    exit(1);
     48  }
     49  status = PR_CreatePipe(&out_pipe[0], &out_pipe[1]);
     50  if (status == PR_FAILURE) {
     51    fprintf(stderr, "PR_CreatePipe failed\n");
     52    exit(1);
     53  }
     54 
     55  status = PR_SetFDInheritable(in_pipe[0], PR_FALSE);
     56  if (status == PR_FAILURE) {
     57    fprintf(stderr, "PR_SetFDInheritable failed\n");
     58    exit(1);
     59  }
     60  status = PR_SetFDInheritable(in_pipe[1], PR_TRUE);
     61  if (status == PR_FAILURE) {
     62    fprintf(stderr, "PR_SetFDInheritable failed\n");
     63    exit(1);
     64  }
     65  status = PR_SetFDInheritable(out_pipe[0], PR_TRUE);
     66  if (status == PR_FAILURE) {
     67    fprintf(stderr, "PR_SetFDInheritable failed\n");
     68    exit(1);
     69  }
     70  status = PR_SetFDInheritable(out_pipe[1], PR_FALSE);
     71  if (status == PR_FAILURE) {
     72    fprintf(stderr, "PR_SetFDInheritable failed\n");
     73    exit(1);
     74  }
     75 
     76  attr = PR_NewProcessAttr();
     77  if (attr == NULL) {
     78    fprintf(stderr, "PR_NewProcessAttr failed\n");
     79    exit(1);
     80  }
     81 
     82  PR_ProcessAttrSetStdioRedirect(attr, PR_StandardInput, out_pipe[0]);
     83  PR_ProcessAttrSetStdioRedirect(attr, PR_StandardOutput, in_pipe[1]);
     84 
     85  process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr);
     86  if (process == NULL) {
     87    fprintf(stderr, "PR_CreateProcess failed\n");
     88    exit(1);
     89  }
     90  PR_DestroyProcessAttr(attr);
     91  status = PR_Close(out_pipe[0]);
     92  if (status == PR_FAILURE) {
     93    fprintf(stderr, "PR_Close failed\n");
     94    exit(1);
     95  }
     96  status = PR_Close(in_pipe[1]);
     97  if (status == PR_FAILURE) {
     98    fprintf(stderr, "PR_Close failed\n");
     99    exit(1);
    100  }
    101 
    102  for (idx = 0; idx < NUM_ITERATIONS; idx++) {
    103    strcpy(buf, "ping");
    104    printf("ping process: sending \"%s\"\n", buf);
    105    nBytes = PR_Write(out_pipe[1], buf, 5);
    106    if (nBytes == -1) {
    107      fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
    108              PR_GetOSError());
    109      exit(1);
    110    }
    111    memset(buf, 0, sizeof(buf));
    112    nBytes = PR_Read(in_pipe[0], buf, sizeof(buf));
    113    if (nBytes == -1) {
    114      fprintf(stderr, "PR_Read failed: (%d, %d)\n", PR_GetError(),
    115              PR_GetOSError());
    116      exit(1);
    117    }
    118    printf("ping process: received \"%s\"\n", buf);
    119    if (nBytes != 5) {
    120      fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n",
    121              nBytes);
    122      exit(1);
    123    }
    124    if (strcmp(buf, "pong") != 0) {
    125      fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n", buf);
    126      exit(1);
    127    }
    128  }
    129 
    130  status = PR_Close(in_pipe[0]);
    131  if (status == PR_FAILURE) {
    132    fprintf(stderr, "PR_Close failed\n");
    133    exit(1);
    134  }
    135  status = PR_Close(out_pipe[1]);
    136  if (status == PR_FAILURE) {
    137    fprintf(stderr, "PR_Close failed\n");
    138    exit(1);
    139  }
    140  status = PR_WaitProcess(process, &exitCode);
    141  if (status == PR_FAILURE) {
    142    fprintf(stderr, "PR_WaitProcess failed\n");
    143    exit(1);
    144  }
    145  if (exitCode == 0) {
    146    printf("PASS\n");
    147    return 0;
    148  } else {
    149    printf("FAIL\n");
    150    return 1;
    151  }
    152 }