tor-browser

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

pipeself.c (6125B)


      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: pipeself.c
      8 *
      9 * Description:
     10 * This test has two threads communicating with each other using
     11 * two unidirectional pipes.  The primordial thread is the ping
     12 * thread and the other thread is the pong thread.  The ping
     13 * thread writes "ping" to the pong thread and the pong thread
     14 * writes "pong" back.
     15 */
     16 
     17 #include "prio.h"
     18 #include "prerror.h"
     19 #include "prthread.h"
     20 
     21 #include <stdio.h>
     22 #include <stdlib.h>
     23 #include <string.h>
     24 
     25 #define NUM_ITERATIONS 10
     26 
     27 static PRFileDesc *ping_in, *ping_out;
     28 static PRFileDesc *pong_in, *pong_out;
     29 
     30 static void PongThreadFunc(void* arg) {
     31  char buf[1024];
     32  int idx;
     33  PRInt32 nBytes;
     34  PRStatus status;
     35 
     36  for (idx = 0; idx < NUM_ITERATIONS; idx++) {
     37    memset(buf, 0, sizeof(buf));
     38    nBytes = PR_Read(pong_in, buf, sizeof(buf));
     39    if (nBytes == -1) {
     40      fprintf(stderr, "PR_Read failed\n");
     41      exit(1);
     42    }
     43    printf("pong thread: received \"%s\"\n", buf);
     44    if (nBytes != 5) {
     45      fprintf(stderr, "pong thread: expected 5 bytes but got %d bytes\n",
     46              nBytes);
     47      exit(1);
     48    }
     49    if (strcmp(buf, "ping") != 0) {
     50      fprintf(stderr, "pong thread: expected \"ping\" but got \"%s\"\n", buf);
     51      exit(1);
     52    }
     53    strcpy(buf, "pong");
     54    printf("pong thread: sending \"%s\"\n", buf);
     55    nBytes = PR_Write(pong_out, buf, 5);
     56    if (nBytes == -1) {
     57      fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
     58              PR_GetOSError());
     59      exit(1);
     60    }
     61  }
     62 
     63  status = PR_Close(pong_in);
     64  if (status == PR_FAILURE) {
     65    fprintf(stderr, "PR_Close failed\n");
     66    exit(1);
     67  }
     68  status = PR_Close(pong_out);
     69  if (status == PR_FAILURE) {
     70    fprintf(stderr, "PR_Close failed\n");
     71    exit(1);
     72  }
     73 }
     74 
     75 int main(int argc, char** argv) {
     76  PRStatus status;
     77  PRThread* pongThread;
     78  char buf[1024];
     79  PRInt32 nBytes;
     80  int idx;
     81 
     82  status = PR_CreatePipe(&ping_in, &pong_out);
     83  if (status == PR_FAILURE) {
     84    fprintf(stderr, "PR_CreatePipe failed\n");
     85    exit(1);
     86  }
     87  status = PR_CreatePipe(&pong_in, &ping_out);
     88  if (status == PR_FAILURE) {
     89    fprintf(stderr, "PR_CreatePipe failed\n");
     90    exit(1);
     91  }
     92 
     93  pongThread =
     94      PR_CreateThread(PR_USER_THREAD, PongThreadFunc, NULL, PR_PRIORITY_NORMAL,
     95                      PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
     96  if (pongThread == NULL) {
     97    fprintf(stderr, "PR_CreateThread failed\n");
     98    exit(1);
     99  }
    100 
    101  for (idx = 0; idx < NUM_ITERATIONS; idx++) {
    102    strcpy(buf, "ping");
    103    printf("ping thread: sending \"%s\"\n", buf);
    104    nBytes = PR_Write(ping_out, buf, 5);
    105    if (nBytes == -1) {
    106      fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
    107              PR_GetOSError());
    108      exit(1);
    109    }
    110    memset(buf, 0, sizeof(buf));
    111    nBytes = PR_Read(ping_in, buf, sizeof(buf));
    112    if (nBytes == -1) {
    113      fprintf(stderr, "PR_Read failed\n");
    114      exit(1);
    115    }
    116    printf("ping thread: received \"%s\"\n", buf);
    117    if (nBytes != 5) {
    118      fprintf(stderr, "ping thread: expected 5 bytes but got %d bytes\n",
    119              nBytes);
    120      exit(1);
    121    }
    122    if (strcmp(buf, "pong") != 0) {
    123      fprintf(stderr, "ping thread: expected \"pong\" but got \"%s\"\n", buf);
    124      exit(1);
    125    }
    126  }
    127 
    128  status = PR_Close(ping_in);
    129  if (status == PR_FAILURE) {
    130    fprintf(stderr, "PR_Close failed\n");
    131    exit(1);
    132  }
    133  status = PR_Close(ping_out);
    134  if (status == PR_FAILURE) {
    135    fprintf(stderr, "PR_Close failed\n");
    136    exit(1);
    137  }
    138  status = PR_JoinThread(pongThread);
    139  if (status == PR_FAILURE) {
    140    fprintf(stderr, "PR_JoinThread failed\n");
    141    exit(1);
    142  }
    143 
    144 #if defined(XP_UNIX)
    145  /*
    146   * Test PR_Available for pipes
    147   */
    148  status = PR_CreatePipe(&ping_in, &ping_out);
    149  if (status == PR_FAILURE) {
    150    fprintf(stderr, "PR_CreatePipe failed\n");
    151    exit(1);
    152  }
    153  nBytes = PR_Write(ping_out, buf, 250);
    154  if (nBytes == -1) {
    155    fprintf(stderr, "PR_Write failed: (%d, %d)\n", PR_GetError(),
    156            PR_GetOSError());
    157    exit(1);
    158  }
    159  nBytes = PR_Available(ping_in);
    160  if (nBytes < 0) {
    161    fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
    162            PR_GetOSError());
    163    exit(1);
    164  } else if (nBytes != 250) {
    165    fprintf(stderr, "PR_Available: expected 250 bytes but got %d bytes\n",
    166            nBytes);
    167    exit(1);
    168  }
    169  printf("PR_Available: expected %d, got %d bytes\n", 250, nBytes);
    170  /* read some data */
    171  nBytes = PR_Read(ping_in, buf, 7);
    172  if (nBytes == -1) {
    173    fprintf(stderr, "PR_Read failed\n");
    174    exit(1);
    175  }
    176  /* check available data */
    177  nBytes = PR_Available(ping_in);
    178  if (nBytes < 0) {
    179    fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
    180            PR_GetOSError());
    181    exit(1);
    182  } else if (nBytes != (250 - 7)) {
    183    fprintf(stderr, "PR_Available: expected 243 bytes but got %d bytes\n",
    184            nBytes);
    185    exit(1);
    186  }
    187  printf("PR_Available: expected %d, got %d bytes\n", 243, nBytes);
    188  /* read all data */
    189  nBytes = PR_Read(ping_in, buf, sizeof(buf));
    190  if (nBytes == -1) {
    191    fprintf(stderr, "PR_Read failed\n");
    192    exit(1);
    193  } else if (nBytes != 243) {
    194    fprintf(stderr, "PR_Read failed: expected %d, got %d bytes\n", 243, nBytes);
    195    exit(1);
    196  }
    197  /* check available data */
    198  nBytes = PR_Available(ping_in);
    199  if (nBytes < 0) {
    200    fprintf(stderr, "PR_Available failed: (%d, %d)\n", PR_GetError(),
    201            PR_GetOSError());
    202    exit(1);
    203  } else if (nBytes != 0) {
    204    fprintf(stderr, "PR_Available: expected 0 bytes but got %d bytes\n",
    205            nBytes);
    206    exit(1);
    207  }
    208  printf("PR_Available: expected %d, got %d bytes\n", 0, nBytes);
    209 
    210  status = PR_Close(ping_in);
    211  if (status == PR_FAILURE) {
    212    fprintf(stderr, "PR_Close failed\n");
    213    exit(1);
    214  }
    215  status = PR_Close(ping_out);
    216  if (status == PR_FAILURE) {
    217    fprintf(stderr, "PR_Close failed\n");
    218    exit(1);
    219  }
    220 #endif /* XP_UNIX */
    221 
    222  printf("PASS\n");
    223  return 0;
    224 }