tail(1): Implement tac(1) as the reverse version of cat(1)
authorAaron LI <aly@aaronly.me>
Sat, 20 Jun 2020 07:10:41 +0000 (15:10 +0800)
committerAaron LI <aly@aaronly.me>
Sat, 20 Jun 2020 07:10:41 +0000 (15:10 +0800)
The tac(1) is the reverse version of cat(1) and is implemented with
'tail -rq'.

Update cat.1, rev.1 and tail.1 man pages to mention the new tac(1).

The tac.1 man page is obtained from NetBSD.  The implementation is also
inspired by NetBSD but is different.

bin/cat/cat.1
usr.bin/rev/rev.1
usr.bin/tail/Makefile
usr.bin/tail/tac.1 [new file with mode: 0644]
usr.bin/tail/tail.1
usr.bin/tail/tail.c

index 861d62e..883e33d 100644 (file)
@@ -31,9 +31,8 @@
 .\"
 .\"     @(#)cat.1      8.3 (Berkeley) 5/2/95
 .\" $FreeBSD: src/bin/cat/cat.1,v 1.27 2006/12/23 09:25:23 ru Exp $
-.\" $DragonFly: src/bin/cat/cat.1,v 1.6 2007/02/04 21:08:28 pavalos Exp $
 .\"
-.Dd March 21, 2004
+.Dd June 20, 2020
 .Dt CAT 1
 .Os
 .Sh NAME
@@ -158,6 +157,7 @@ operand.
 .Xr more 1 ,
 .Xr pr 1 ,
 .Xr sh 1 ,
+.Xr tac 1 ,
 .Xr tail 1 ,
 .Xr vis 1 ,
 .Xr zcat 1 ,
index 20ef0b2..2c72649 100644 (file)
@@ -27,9 +27,8 @@
 .\"
 .\"    @(#)rev.1       8.1 (Berkeley) 6/9/93
 .\" $FreeBSD: src/usr.bin/rev/rev.1,v 1.4.2.2 2001/03/06 12:52:55 ru Exp $
-.\" $DragonFly: src/usr.bin/rev/rev.1,v 1.2 2003/06/17 04:29:30 dillon Exp $
 .\"
-.Dd June 9, 1993
+.Dd June 20, 2020
 .Dt REV 1
 .Os
 .Sh NAME
@@ -44,3 +43,5 @@ The
 utility copies the specified files to the standard output, reversing the
 order of characters in every line.
 If no files are specified, the standard input is read.
+.Sh SEE ALSO
+.Xr tac 1
index 26411cb..98cd3df 100644 (file)
@@ -1,9 +1,11 @@
 #      @(#)Makefile    8.1 (Berkeley) 6/6/93
-# $DragonFly: src/usr.bin/tail/Makefile,v 1.3 2007/08/27 16:50:59 pavalos Exp $
 
 PROG=  tail
+MAN=   tail.1 tac.1
 SRCS=  forward.c misc.c read.c reverse.c tail.c
 
+LINKS= ${BINDIR}/tail ${BINDIR}/tac
+
 .if defined(BOOTSTRAPPING)
 CFLAGS+= -DBOOTSTRAPPING
 .endif
diff --git a/usr.bin/tail/tac.1 b/usr.bin/tail/tac.1
new file mode 100644 (file)
index 0000000..2f3ef48
--- /dev/null
@@ -0,0 +1,64 @@
+.\"    $NetBSD: tac.1,v 1.2 2017/10/01 22:35:23 kre Exp $
+.\"
+.\" Copyright (c) 2017 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Maya Rashish.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in
+.\"    the documentation and/or other materials provided with the
+.\"    distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd June 20, 2020
+.Dt TAC 1
+.Os
+.Sh NAME
+.Nm tac
+.Nd display file in reverse
+.Sh SYNOPSIS
+.Nm
+.Op Ar file ...
+.Sh DESCRIPTION
+.Nm
+.Pq cat backwards
+outputs the contents of each of the specified files,
+or the standard input if no files are specified,
+in reverse line order to the standard output.
+.Pp
+The
+.Nm
+utility is a hard link to
+.Xr tail 1
+and behaves as
+.Nm tail Fl rq .
+.Sh EXIT STATUS
+.Ex -std tac
+.Sh COMPATIBILITY
+The
+.Nm
+utility doesn't support any of the options of GNU tac.
+.Sh SEE ALSO
+.Xr cat 1 ,
+.Xr rev 1 ,
+.Xr tail 1
index 0171ca1..1a73de6 100644 (file)
@@ -158,7 +158,8 @@ flag disables the printing of the header in both cases.
 .Sh SEE ALSO
 .Xr cat 1 ,
 .Xr head 1 ,
-.Xr sed 1
+.Xr sed 1 ,
+.Xr tac 1
 .Sh STANDARDS
 The
 .Nm
index 0712ec0..476de9c 100644 (file)
@@ -57,6 +57,7 @@ static void getarg(int, enum STYLE, enum STYLE, enum STYLE *, int *, off_t *);
 int
 main(int argc, char **argv)
 {
+       const char *optstring;
        struct stat sb;
        FILE *fp;
        off_t off = 0;
@@ -67,9 +68,19 @@ main(int argc, char **argv)
        file_info_t *file;
 #endif
 
+       if (strcmp(getprogname(), "tac") == 0) {
+               optstring = "";
+               qflag = 1;
+               rflag = 1;
+               vflag = 0;
+       } else {
+               /* tail */
+               optstring = "Fb:c:fn:qrv";
+       }
+
        obsolete(argv);
        style_set = 0;
-       while ((ch = getopt(argc, argv, "Fb:c:fn:qrv")) != -1) {
+       while ((ch = getopt(argc, argv, optstring)) != -1) {
                switch(ch) {
                case 'F':       /* -F is superset of (and implies) -f */
 #ifndef BOOTSTRAPPING
@@ -336,8 +347,12 @@ obsolete(char **argv)
 static void __dead2
 usage(void)
 {
-       fprintf(stderr,
-               "usage: tail [-F | -f | -r] [-q | -v] [-b # | -c # | -n #] "
-               "[file ...]\n");
+       if (strcmp(getprogname(), "tac") == 0) {
+               fprintf(stderr, "usage: tac [file ...]\n");
+       } else {
+               fprintf(stderr,
+                       "usage: tail [-F | -f | -r] [-q | -v] "
+                       "[-b # | -c # | -n #] [file ...]\n");
+       }
        exit(1);
 }