tor-browser

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

sockping.c (3500B)


      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: sockping.c
      8 *
      9 * Description:
     10 * This test runs in conjunction with the sockpong test.
     11 * This test creates a socket pair and passes one socket
     12 * to the sockpong test.  Then this test writes "ping" to
     13 * to the sockpong test and the sockpong test writes "pong"
     14 * back.  To run this pair of tests, just invoke sockping.
     15 *
     16 * Tested areas: process creation, socket pairs, file
     17 * descriptor 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[] = {"sockpong", NULL};
     31 
     32 int main(int argc, char** argv) {
     33  PRFileDesc* sock[2];
     34  PRStatus status;
     35  PRProcess* process;
     36  PRProcessAttr* attr;
     37  char buf[1024];
     38  PRInt32 nBytes;
     39  PRInt32 exitCode;
     40  int idx;
     41 
     42  status = PR_NewTCPSocketPair(sock);
     43  if (status == PR_FAILURE) {
     44    fprintf(stderr, "PR_NewTCPSocketPair failed\n");
     45    exit(1);
     46  }
     47 
     48  status = PR_SetFDInheritable(sock[0], PR_FALSE);
     49  if (status == PR_FAILURE) {
     50    fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n", PR_GetError(),
     51            PR_GetOSError());
     52    exit(1);
     53  }
     54  status = PR_SetFDInheritable(sock[1], PR_TRUE);
     55  if (status == PR_FAILURE) {
     56    fprintf(stderr, "PR_SetFDInheritable failed: (%d, %d)\n", PR_GetError(),
     57            PR_GetOSError());
     58    exit(1);
     59  }
     60 
     61  attr = PR_NewProcessAttr();
     62  if (attr == NULL) {
     63    fprintf(stderr, "PR_NewProcessAttr failed\n");
     64    exit(1);
     65  }
     66 
     67  status = PR_ProcessAttrSetInheritableFD(attr, sock[1], "SOCKET");
     68  if (status == PR_FAILURE) {
     69    fprintf(stderr, "PR_ProcessAttrSetInheritableFD failed\n");
     70    exit(1);
     71  }
     72 
     73  process = PR_CreateProcess(child_argv[0], child_argv, NULL, attr);
     74  if (process == NULL) {
     75    fprintf(stderr, "PR_CreateProcess failed\n");
     76    exit(1);
     77  }
     78  PR_DestroyProcessAttr(attr);
     79  status = PR_Close(sock[1]);
     80  if (status == PR_FAILURE) {
     81    fprintf(stderr, "PR_Close failed\n");
     82    exit(1);
     83  }
     84 
     85  for (idx = 0; idx < NUM_ITERATIONS; idx++) {
     86    strcpy(buf, "ping");
     87    printf("ping process: sending \"%s\"\n", buf);
     88    nBytes = PR_Write(sock[0], buf, 5);
     89    if (nBytes == -1) {
     90      fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
     91              PR_GetOSError());
     92      exit(1);
     93    }
     94    memset(buf, 0, sizeof(buf));
     95    nBytes = PR_Read(sock[0], buf, sizeof(buf));
     96    if (nBytes == -1) {
     97      fprintf(stderr, "PR_Read failed: (%d, %d)\n", PR_GetError(),
     98              PR_GetOSError());
     99      exit(1);
    100    }
    101    printf("ping process: received \"%s\"\n", buf);
    102    if (nBytes != 5) {
    103      fprintf(stderr, "ping process: expected 5 bytes but got %d bytes\n",
    104              nBytes);
    105      exit(1);
    106    }
    107    if (strcmp(buf, "pong") != 0) {
    108      fprintf(stderr, "ping process: expected \"pong\" but got \"%s\"\n", buf);
    109      exit(1);
    110    }
    111  }
    112 
    113  status = PR_Close(sock[0]);
    114  if (status == PR_FAILURE) {
    115    fprintf(stderr, "PR_Close failed\n");
    116    exit(1);
    117  }
    118  status = PR_WaitProcess(process, &exitCode);
    119  if (status == PR_FAILURE) {
    120    fprintf(stderr, "PR_WaitProcess failed\n");
    121    exit(1);
    122  }
    123  if (exitCode == 0) {
    124    printf("PASS\n");
    125    return 0;
    126  } else {
    127    printf("FAIL\n");
    128    return 1;
    129  }
    130 }