tor-browser

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

pipeping2.c (4288B)


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