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/. */
17 #define BUFFER_SIZE 500
19 static PRFileDesc
*out
= NULL
, *err
= NULL
;
21 static void Help(void)
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");
30 PRIntn
main(PRIntn argc
, char **argv
)
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
)))
49 if (PL_OPT_BAD
== os
) continue;
52 case 0: /* it's the filename */
53 filename
= opt
->value
;
55 case 'n': /* bytes before end of file */
56 seek
= atoi(opt
->value
);
58 case 't': /* dally time */
59 time
= atoi(opt
->value
);
61 case 'f': /* follow the end of file */
64 case 'h': /* user wants some guidance */
65 Help(); /* so give him an earful */
66 return 2; /* but not a lot else */
72 PL_DestroyOptState(opt
);
74 if (0 == time
) time
= 1000;
75 dally
= PR_MillisecondsToInterval(time
);
79 (void)PR_fprintf(out
, "Input file not specified\n");
82 file
= PR_Open(filename
, PR_RDONLY
, 0);
85 PL_FPrintError(err
, "File cannot be opened for reading");
89 status
= PR_GetOpenFileInfo(file
, &fileInfo
);
90 if (PR_FAILURE
== status
)
92 PL_FPrintError(err
, "Cannot acquire status of file");
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");
105 while (position
< fileInfo
.size
)
107 PRInt32 read
, bytes
= fileInfo
.size
- position
;
108 if (bytes
> sizeof(buffer
)) bytes
= sizeof(buffer
);
109 read
= PR_Read(file
, buffer
, bytes
);
111 PL_FPrintError(err
, "Cannot read to eof");
113 PR_Write(out
, buffer
, read
);
119 status
= PR_GetOpenFileInfo(file
, &fileInfo
);
120 if (PR_FAILURE
== status
)
122 PL_FPrintError(err
, "Cannot acquire status of file");