nsprpub/tools/tail.c

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/. */
     6 #include "prio.h"
     7 #include "prprf.h"
     8 #include "prinit.h"
     9 #include "prthread.h"
    10 #include "prinrval.h"
    12 #include "plerror.h"
    13 #include "plgetopt.h"
    15 #include <stdlib.h>
    17 #define BUFFER_SIZE 500
    19 static PRFileDesc *out = NULL, *err = NULL;
    21 static void Help(void)
    22 {
    23     PR_fprintf(err, "Usage: tail [-n <n>] [-f] [-h] <filename>\n");
    24     PR_fprintf(err, "\t-t <n>	Dally time in milliseconds\n");
    25     PR_fprintf(err, "\t-n <n>	Number of bytes before <eof>\n");
    26     PR_fprintf(err, "\t-f   	Follow the <eof>\n");
    27     PR_fprintf(err, "\t-h   	This message and nothing else\n");
    28 }  /* Help */
    30 PRIntn main(PRIntn argc, char **argv)
    31 {
    32 	PRIntn rv = 0;
    33     PLOptStatus os;
    34 	PRStatus status;
    35 	PRFileDesc *file;
    36 	PRFileInfo fileInfo;
    37 	PRIntervalTime dally;
    38 	char buffer[BUFFER_SIZE];
    39 	PRBool follow = PR_FALSE;
    40 	const char *filename = NULL;
    41 	PRUint32 position = 0, seek = 0, time = 0;
    42     PLOptState *opt = PL_CreateOptState(argc, argv, "hfn:");
    44     out = PR_GetSpecialFD(PR_StandardOutput);
    45     err = PR_GetSpecialFD(PR_StandardError);
    47     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    48     {
    49         if (PL_OPT_BAD == os) continue;
    50         switch (opt->option)
    51         {
    52 		case 0:  /* it's the filename */
    53 			filename = opt->value;
    54 			break;
    55         case 'n':  /* bytes before end of file */
    56             seek = atoi(opt->value);
    57             break;
    58         case 't':  /* dally time */
    59             time = atoi(opt->value);
    60             break;
    61         case 'f':  /* follow the end of file */
    62             follow = PR_TRUE;
    63             break;
    64         case 'h':  /* user wants some guidance */
    65             Help();  /* so give him an earful */
    66             return 2;  /* but not a lot else */
    67             break;
    68          default:
    69             break;
    70         }
    71     }
    72     PL_DestroyOptState(opt);
    74 	if (0 == time) time = 1000;
    75 	dally = PR_MillisecondsToInterval(time);
    77     if (NULL == filename)
    78     {
    79         (void)PR_fprintf(out, "Input file not specified\n");
    80         rv = 1; goto done;
    81     }
    82 	file = PR_Open(filename, PR_RDONLY, 0);
    83 	if (NULL == file)
    84 	{
    85 		PL_FPrintError(err, "File cannot be opened for reading");
    86 		return 1;
    87 	}
    89 	status = PR_GetOpenFileInfo(file, &fileInfo);
    90 	if (PR_FAILURE == status)
    91 	{
    92 		PL_FPrintError(err, "Cannot acquire status of file");
    93 		rv = 1; goto done;
    94 	}
    95 	if (seek > 0)
    96 	{
    97 	    if (seek > fileInfo.size) seek = 0;
    98 		position = PR_Seek(file, (fileInfo.size - seek), PR_SEEK_SET);
    99 		if (-1 == (PRInt32)position)
   100 			PL_FPrintError(err, "Cannot seek to starting position");
   101 	}
   103 	do
   104 	{
   105 		while (position < fileInfo.size)
   106 		{
   107 			PRInt32 read, bytes = fileInfo.size - position;
   108 			if (bytes > sizeof(buffer)) bytes = sizeof(buffer);
   109 			read = PR_Read(file, buffer, bytes);
   110 			if (read != bytes)
   111 				PL_FPrintError(err, "Cannot read to eof");
   112 			position += read;
   113 			PR_Write(out, buffer, read);
   114 		}
   116 		if (follow)
   117 		{
   118 			PR_Sleep(dally);
   119 			status = PR_GetOpenFileInfo(file, &fileInfo);
   120 			if (PR_FAILURE == status)
   121 			{
   122 				PL_FPrintError(err, "Cannot acquire status of file");
   123 				rv = 1; goto done;
   124 			}
   125 		}
   126 	} while (follow);
   128 done:
   129 	PR_Close(file);
   131 	return rv;
   132 }  /* main */
   134 /* tail.c */

mercurial