/* vi: set sw=4 ts=4: */
#include "internal.h"
+
/* This file contains _two_ implementations of tail. One is
* a bit more full featured, but costs 6k. The other (i.e. the
* SIMPLE_TAIL one) is less capable, but is good enough for about
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
+#define BB_DECLARE_EXTERN
+#define bb_need_help
+#include "messages.c"
#define XWRITE(fd, buffer, n_bytes) \
do { \
if (n_bytes > 0 && fwrite ((buffer), 1, (n_bytes), stdout) == 0) \
- error("write error"); \
+ errorMsg("write error"); \
} while (0)
/* Number of items to tail. */
static int print_headers;
const char tail_usage[] =
- "tail [OPTION] [FILE]...\n\n"
- "Print last 10 lines of each FILE to standard output.\n"
+ "tail [OPTION] [FILE]...\n"
+#ifndef BB_FEATURE_TRIVIAL_HELP
+ "\nPrint last 10 lines of each FILE to standard output.\n"
"With more than one FILE, precede each with a header giving the\n"
"file name. With no FILE, or when FILE is -, read standard input.\n\n"
"Options:\n"
"\t-n NUM\t\tPrint last NUM lines instead of first 10\n"
"\t-f\t\tOutput data as the file grows. This version\n"
- "\t\t\tof 'tail -f' supports only one file at a time.\n";
+ "\t\t\tof 'tail -f' supports only one file at a time.\n"
+#endif
+ ;
static void write_header(const char *filename)
lseek(fd, pos, SEEK_SET);
bytes_read = fullRead(fd, buffer, bytes_read);
if (bytes_read == -1)
- error("read error");
+ errorMsg("read error");
/* Count the incomplete line on files that don't end with a newline. */
if (bytes_read && buffer[bytes_read - 1] != '\n')
}
while ((bytes_read = fullRead(fd, buffer, BUFSIZ)) > 0);
if (bytes_read == -1)
- error("read error");
+ errorMsg("read error");
return 0;
}
}
}
if (tmp->nbytes == -1)
- error("read error");
+ errorMsg("read error");
free((char *) tmp);
total += bytes_read;
}
if (bytes_read == -1)
- error("read error");
+ errorMsg("read error");
if (forever) {
fflush(stdout);
sleep(1);
write_header(filename);
if (fstat(fd, &stats))
- error("fstat error");
+ errorMsg("fstat error");
/* Use file_lines only if FD refers to a regular file with
its file pointer positioned at beginning of file. */
/* Not standard input. */
fd = open(filename, O_RDONLY);
if (fd == -1)
- error("open error");
+ perror(filename);
errors = tail_lines(filename, fd, (long) n_units);
close(fd);
case 'h':
usage(tail_usage);
default:
- fprintf(stderr, "tail: invalid option -- %c\n", opt);
- usage(tail_usage);
+ if ((n_units = atoi(&argv[i][1])) < 1) {
+ fprintf(stderr, "tail: invalid option -- %c\n", opt);
+ usage(tail_usage);
+ }
}
} else {
break;
exit_status |= tail_file(argv[i], n_units);
}
- exit(exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
+ return(exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
#define NDEBUG 1
+static void detailed_error(int i, int errnum, char *fmt, ...)
+ __attribute__ ((format (printf, 3, 4)));
static void detailed_error(int i, int errnum, char *fmt, ...)
{
va_list arguments;
static int have_read_stdin;
-static const char tail_usage[] = "tail [OPTION]... [FILE]...\n\
-\n\
-Print last 10 lines of each FILE to standard output.\n\
+static const char tail_usage[] = "tail [OPTION]... [FILE]...\n"
+#ifndef BB_FEATURE_TRIVIAL_HELP
+"\nPrint last 10 lines of each FILE to standard output.\n\
With more than one FILE, precede each with a header giving the file name.\n\
With no FILE, or when FILE is -, read standard input.\n\
\n\
-n=N output the last N lines, instead of last 10\n\
-q never output headers giving file names\n\
-v always output headers giving file names\n\
- --help display this help and exit\n\
\n\
If the first character of N (bytes or lines) is a `+', output begins with \n\
the Nth item from the start of each file, otherwise, print the last N items\n\
-in the file. N bytes may be suffixed by k (x1024), b (x512), or m (1024^2).\n\n";
+in the file. N bytes may be suffixed by k (x1024), b (x512), or m (1024^2).\n"
+#endif
+;
static void write_header(const char *filename, const char *comment)
{