summaryrefslogtreecommitdiff
path: root/src/tail.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tail.c')
-rw-r--r--src/tail.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/tail.c b/src/tail.c
index 9007888fc..781adf200 100644
--- a/src/tail.c
+++ b/src/tail.c
@@ -180,6 +180,9 @@ static bool from_start;
/* If true, print filename headers. */
static bool print_headers;
+/* Character to split lines by. */
+static char line_end;
+
/* When to print the filename banners. */
enum header_mode
{
@@ -238,6 +241,7 @@ static struct option const long_options[] =
{"silent", no_argument, NULL, 'q'},
{"sleep-interval", required_argument, NULL, 's'},
{"verbose", no_argument, NULL, 'v'},
+ {"zero-terminated", no_argument, NULL, 'z'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -297,6 +301,9 @@ With more than one FILE, precede each with a header giving the file name.\n\
least once every N seconds\n\
-v, --verbose always output headers giving file names\n\
"), stdout);
+ fputs (_("\
+ -z, --zero-terminated line delimiter is NUL, not newline\n\
+"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\
@@ -499,7 +506,7 @@ file_lines (const char *pretty_filename, int fd, uintmax_t n_lines,
*read_pos = pos + bytes_read;
/* Count the incomplete line on files that don't end with a newline. */
- if (bytes_read && buffer[bytes_read - 1] != '\n')
+ if (bytes_read && buffer[bytes_read - 1] != line_end)
--n_lines;
do
@@ -510,7 +517,7 @@ file_lines (const char *pretty_filename, int fd, uintmax_t n_lines,
while (n)
{
char const *nl;
- nl = memrchr (buffer, '\n', n);
+ nl = memrchr (buffer, line_end, n);
if (nl == NULL)
break;
n = nl - buffer;
@@ -595,7 +602,7 @@ pipe_lines (const char *pretty_filename, int fd, uintmax_t n_lines,
{
char const *buffer_end = tmp->buffer + n_read;
char const *p = tmp->buffer;
- while ((p = memchr (p, '\n', buffer_end - p)))
+ while ((p = memchr (p, line_end, buffer_end - p)))
{
++p;
++tmp->nlines;
@@ -649,7 +656,7 @@ pipe_lines (const char *pretty_filename, int fd, uintmax_t n_lines,
goto free_lbuffers;
/* Count the incomplete line on files that don't end with a newline. */
- if (last->buffer[last->nbytes - 1] != '\n')
+ if (last->buffer[last->nbytes - 1] != line_end)
{
++last->nlines;
++total_lines;
@@ -671,7 +678,7 @@ pipe_lines (const char *pretty_filename, int fd, uintmax_t n_lines,
size_t j;
for (j = total_lines - n_lines; j; --j)
{
- beg = memchr (beg, '\n', buffer_end - beg);
+ beg = memchr (beg, line_end, buffer_end - beg);
assert (beg);
++beg;
}
@@ -857,7 +864,7 @@ start_lines (const char *pretty_filename, int fd, uintmax_t n_lines,
*read_pos += bytes_read;
char *p = buffer;
- while ((p = memchr (p, '\n', buffer_end - p)))
+ while ((p = memchr (p, line_end, buffer_end - p)))
{
++p;
if (--n_lines == 0)
@@ -2047,7 +2054,7 @@ parse_options (int argc, char **argv,
{
int c;
- while ((c = getopt_long (argc, argv, "c:n:fFqs:v0123456789",
+ while ((c = getopt_long (argc, argv, "c:n:fFqs:vz0123456789",
long_options, NULL))
!= -1)
{
@@ -2124,6 +2131,10 @@ parse_options (int argc, char **argv,
*header_mode = always;
break;
+ case 'z':
+ line_end = '\0';
+ break;
+
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -2221,6 +2232,7 @@ main (int argc, char **argv)
count_lines = true;
forever = from_start = print_headers = false;
+ line_end = '\n';
obsolete_option = parse_obsolete_option (argc, argv, &n_units);
argc -= obsolete_option;
argv += obsolete_option;