tor-browser

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

fileio.c (4898B)


      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 **
      8 ** Name: fileio.c
      9 **
     10 ** Description: Program to copy one file to another.
     11 **
     12 ** Modification History:
     13 ** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
     14 **           The debug mode will print all of the printfs associated with this
     15 *test.
     16 **           The regress mode will be the default mode. Since the regress tool
     17 *limits
     18 **           the output to a one line status:PASS or FAIL,all of the printf
     19 *statements
     20 **           have been handled with an if (debug_mode) statement.
     21 ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been
     22 *updated to
     23 **          recognize the return code from tha main program.
     24 ** 12-June-97 Revert to return code 0 and 1, remove debug option (obsolete).
     25 ***********************************************************************/
     26 
     27 /***********************************************************************
     28 ** Includes
     29 ***********************************************************************/
     30 #include "prinit.h"
     31 #include "prthread.h"
     32 #include "prlock.h"
     33 #include "prcvar.h"
     34 #include "prmon.h"
     35 #include "prmem.h"
     36 #include "prio.h"
     37 #include "prlog.h"
     38 
     39 #include <stdio.h>
     40 
     41 #include "obsolete/prsem.h"
     42 
     43 #define TBSIZE 1024
     44 
     45 static PRUint8 tbuf[TBSIZE];
     46 
     47 static PRFileDesc *t1, *t2;
     48 
     49 PRIntn failed_already = 0;
     50 PRIntn debug_mode;
     51 static void InitialSetup(void) {
     52  PRUintn i;
     53  PRInt32 nWritten, rv;
     54 
     55  t1 = PR_Open("t1.tmp", PR_CREATE_FILE | PR_RDWR, 0);
     56  PR_ASSERT(t1 != NULL);
     57 
     58  for (i = 0; i < TBSIZE; i++) {
     59    tbuf[i] = i;
     60  }
     61 
     62  nWritten = PR_Write((PRFileDesc*)t1, tbuf, TBSIZE);
     63  PR_ASSERT(nWritten == TBSIZE);
     64 
     65  rv = PR_Seek(t1, 0, PR_SEEK_SET);
     66  PR_ASSERT(rv == 0);
     67 
     68  t2 = PR_Open("t2.tmp", PR_CREATE_FILE | PR_RDWR, 0);
     69  PR_ASSERT(t2 != NULL);
     70 }
     71 
     72 static void VerifyAndCleanup(void) {
     73  PRUintn i;
     74  PRInt32 nRead, rv;
     75 
     76  for (i = 0; i < TBSIZE; i++) {
     77    tbuf[i] = 0;
     78  }
     79 
     80  rv = PR_Seek(t2, 0, PR_SEEK_SET);
     81  PR_ASSERT(rv == 0);
     82 
     83  nRead = PR_Read((PRFileDesc*)t2, tbuf, TBSIZE);
     84  PR_ASSERT(nRead == TBSIZE);
     85 
     86  for (i = 0; i < TBSIZE; i++)
     87    if (tbuf[i] != (PRUint8)i) {
     88      if (debug_mode) {
     89        printf("data mismatch for index= %d \n", i);
     90      } else {
     91        failed_already = 1;
     92      }
     93    }
     94  PR_Close(t1);
     95  PR_Close(t2);
     96 
     97  PR_Delete("t1.tmp");
     98  PR_Delete("t2.tmp");
     99 
    100  if (debug_mode) {
    101    printf("fileio test passed\n");
    102  }
    103 }
    104 
    105 /*------------------ Following is the real test program ---------*/
    106 /*
    107    Program to copy one file to another.  Two temporary files get
    108    created.  First one gets written in one write call.  Then,
    109    a reader thread reads from this file into a double buffer.
    110    The writer thread writes from double buffer into the other
    111    temporary file.  The second temporary file gets verified
    112    for accurate data.
    113 */
    114 
    115 PRSemaphore* emptyBufs; /* number of empty buffers */
    116 PRSemaphore* fullBufs;  /* number of buffers that are full */
    117 
    118 #define BSIZE 100
    119 
    120 struct {
    121  char data[BSIZE];
    122  PRUintn nbytes; /* number of bytes in this buffer */
    123 } buf[2];
    124 
    125 static void PR_CALLBACK reader(void* arg) {
    126  PRUintn i = 0;
    127  PRInt32 nbytes;
    128 
    129  do {
    130    (void)PR_WaitSem(emptyBufs);
    131    nbytes = PR_Read((PRFileDesc*)arg, buf[i].data, BSIZE);
    132    if (nbytes >= 0) {
    133      buf[i].nbytes = nbytes;
    134      PR_PostSem(fullBufs);
    135      i = (i + 1) % 2;
    136    }
    137  } while (nbytes > 0);
    138 }
    139 
    140 static void PR_CALLBACK writer(void* arg) {
    141  PRUintn i = 0;
    142  PRInt32 nbytes;
    143 
    144  do {
    145    (void)PR_WaitSem(fullBufs);
    146    nbytes = buf[i].nbytes;
    147    if (nbytes > 0) {
    148      nbytes = PR_Write((PRFileDesc*)arg, buf[i].data, nbytes);
    149      PR_PostSem(emptyBufs);
    150      i = (i + 1) % 2;
    151    }
    152  } while (nbytes > 0);
    153 }
    154 
    155 int main(int argc, char** argv) {
    156  PRThread *r, *w;
    157 
    158  PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
    159 
    160  emptyBufs = PR_NewSem(2); /* two empty buffers */
    161 
    162  fullBufs = PR_NewSem(0); /* zero full buffers */
    163 
    164  /* Create initial temp file setup */
    165  InitialSetup();
    166 
    167  /* create the reader thread */
    168 
    169  r = PR_CreateThread(PR_USER_THREAD, reader, t1, PR_PRIORITY_NORMAL,
    170                      PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
    171 
    172  w = PR_CreateThread(PR_USER_THREAD, writer, t2, PR_PRIORITY_NORMAL,
    173                      PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
    174 
    175  /* Do the joining for both threads */
    176  (void)PR_JoinThread(r);
    177  (void)PR_JoinThread(w);
    178 
    179  /* Do the verification and clean up */
    180  VerifyAndCleanup();
    181 
    182  PR_DestroySem(emptyBufs);
    183  PR_DestroySem(fullBufs);
    184 
    185  PR_Cleanup();
    186 
    187  if (failed_already) {
    188    printf("Fail\n");
    189    return 1;
    190  } else {
    191    printf("PASS\n");
    192    return 0;
    193  }
    194 }