tailf: remove deprecated utility

March 2017 is gone, it is time to remove this utility as scheduled in
earlier commit, and promised in manual page.

Reference: 3f8478a71c
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Sami Kerola 2017-04-02 16:50:42 +01:00
parent eff2c9a426
commit 70ca1a7772
No known key found for this signature in database
GPG Key ID: A9553245FDE9B739
30 changed files with 0 additions and 480 deletions

1
.gitignore vendored
View File

@ -156,7 +156,6 @@ ylwrap
/swapoff
/swapon
/switch_root
/tailf
/taskset
/test_*
/tunelp

View File

@ -13,11 +13,6 @@ why: Output printed by --compare option was nonesense.
--------------------------
what: tailf
why: "tail -f" is better nowadays, tailf has unfixed bugs
--------------------------
what: sfdisk --show-size
why: this does not belong to fdisk, use "blockdev --getsz"

View File

@ -90,9 +90,6 @@ endif
if BUILD_SETSID
dist_bashcompletion_DATA += bash-completion/setsid
endif
if BUILD_TAILF
dist_bashcompletion_DATA += bash-completion/tailf
endif
if BUILD_WHEREIS
dist_bashcompletion_DATA += bash-completion/whereis
endif

View File

@ -1,28 +0,0 @@
_tailf_module()
{
local cur prev OPTS
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
case $prev in
'-n'|'--lines')
COMPREPLY=( $(compgen -W "number" -- $cur) )
return 0
;;
'-h'|'--help'|'-V'|'--version')
return 0
;;
esac
case $cur in
-*)
OPTS="--lines --version --help"
COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
return 0
;;
esac
local IFS=$'\n'
compopt -o filenames
COMPREPLY=( $(compgen -f -- $cur) )
return 0
}
complete -F _tailf_module tailf

View File

@ -1644,13 +1644,6 @@ AM_CONDITIONAL([BUILD_HEXDUMP], [test "x$build_hexdump" = xyes])
UL_BUILD_INIT([rev], [yes])
AM_CONDITIONAL([BUILD_REV], [test "x$build_rev" = xyes])
AC_ARG_ENABLE([tailf],
AS_HELP_STRING([--enable-tailf], [build tailf (deprecated)]),
[], [UL_DEFAULT_ENABLE([tailf], [no])]
)
UL_BUILD_INIT([tailf])
AM_CONDITIONAL([BUILD_TAILF], [test "x$build_tailf" = xyes])
AC_ARG_ENABLE([tunelp],
AS_HELP_STRING([--enable-tunelp], [build tunelp]),

View File

@ -88,7 +88,6 @@ TS_CMD_SETSID=${TS_CMD_SETSID-"$top_builddir/setsid"}
TS_CMD_SWAPLABEL=${TS_CMD_SWAPLABEL:-"$top_builddir/swaplabel"}
TS_CMD_SWAPOFF=${TS_CMD_SWAPOFF:-"$top_builddir/swapoff"}
TS_CMD_SWAPON=${TS_CMD_SWAPON:-"$top_builddir/swapon"}
TS_CMD_TAILF=${TS_CMD_TAILF-"$top_builddir/tailf"}
TS_CMD_UL=${TS_CMD_UL-"$top_builddir/ul"}
TS_CMD_UMOUNT=${TS_CMD_UMOUNT:-"$top_builddir/umount"}
TS_CMD_UTMPDUMP=${TS_CMD_UTMPDUMP-"$top_builddir/utmpdump"}

View File

@ -101,7 +101,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
tunelp:
ul: libtinfo

View File

@ -112,5 +112,4 @@ line:
more: libtinfo
pg: libncursesw libtinfo
rev:
tailf:
ul: libtinfo

View File

@ -101,7 +101,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
tunelp:
ul: libtinfo

View File

@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -101,7 +101,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
tailf:
taskset:
tunelp:
ul: libtinfo

View File

@ -119,5 +119,4 @@ line:
more: libtinfo
pg: libncursesw libtinfo
rev:
tailf:
ul: libtinfo

View File

@ -101,7 +101,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
tailf:
taskset:
tunelp:
ul: libtinfo

View File

@ -76,7 +76,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -85,7 +85,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -60,7 +60,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -77,7 +77,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -91,7 +91,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
ul: libtinfo
unshare:

View File

@ -104,7 +104,6 @@ sfdisk.static: STATIC
su: libpam libpam_misc
sulogin: rypt
switch_root:
tailf:
taskset:
ul: libtinfo
umount.static: STATIC

View File

@ -1,40 +0,0 @@
#!/bin/bash
# This file is part of util-linux.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
TS_TOPDIR="${0%/*}/../.."
TS_DESC="simple"
. $TS_TOPDIR/functions.sh
ts_init "$*"
ts_check_test_command "$TS_CMD_TAILF"
# This test is unsafe for some filesystems and for case non-inotify. We don't
# fix it since tailf is deprecated. Just keep this test for the test log.
TS_KNOWN_FAIL="yes"
INPUT=$TS_OUTDIR/$TS_TESTNAME.input
rm -f $INPUT
echo {a..z} > $INPUT
$TS_CMD_TAILF $INPUT > $TS_OUTPUT 2>&1 &
sleep 0.5
echo {0..9} >> $INPUT
sleep 0.5
rm -f $INPUT
ts_finalize

View File

@ -43,13 +43,6 @@ dist_man_MANS += text-utils/rev.1
rev_SOURCES = text-utils/rev.c
endif
if BUILD_TAILF
usrbin_exec_PROGRAMS += tailf
dist_man_MANS += text-utils/tailf.1
tailf_SOURCES = text-utils/tailf.c
tailf_LDADD = $(LDADD) libcommon.la
endif
if BUILD_LINE
usrbin_exec_PROGRAMS += line
line_SOURCES = text-utils/line.c

View File

@ -1,73 +0,0 @@
.\" tailf.1 -- man page for tailf
.\" Copyright 1996, 2003 Rickard E. Faith (faith@acm.org)
.\"
.\" Permission is granted to make and distribute verbatim copies of this
.\" manual provided the copyright notice and this permission notice are
.\" preserved on all copies.
.\"
.\" Permission is granted to copy and distribute modified versions of this
.\" manual under the conditions for verbatim copying, provided that the
.\" entire resulting derived work is distributed under the terms of a
.\" permission notice identical to this one.
.\"
.\" Since the Linux kernel and libraries are constantly changing, this
.\" manual page may be incorrect or out-of-date. The author(s) assume no
.\" responsibility for errors or omissions, or for damages resulting from
.\" the use of the information contained herein. The author(s) may not
.\" have taken the same level of care in the production of this manual,
.\" which is licensed free of charge, as they might when working
.\" professionally.
.\"
.\" Formatted or processed versions of this manual, if unaccompanied by
.\" the source, must acknowledge the copyright and authors of this work.
.\"
.TH TAILF 1 "March 2015" "util-linux" "User Commands"
.SH NAME
tailf \- follow the growth of a log file
.SH SYNOPSIS
.B tailf
[option]
.I file
.SH DESCRIPTION
.B tailf is deprecated.
It may have unfixed bugs and will be removed from util-linux in March 2017.
Nowadays it's safe to use
.B tail -f
(from coreutils), in contrast to what the original documentation below says.
.PP
.B tailf
will print out the last 10 lines of the given \fIfile\fR and then wait
for this \fIfile\fR to grow. It is similar to
.B tail -f
but does not access the file when it is not growing. This has the side
effect of not updating the access time for the file, so a filesystem flush
does not occur periodically when no log activity is happening.
.PP
.B tailf
is extremely useful for monitoring log files on a laptop when logging is
infrequent and the user wishes the hard disk to spin down to conserve
battery life.
.TP
.BR \-n , " -\-lines=\fInumber\fR" , " \-\fInumber\fR"
Output the last
.I number
lines, instead of the last 10.
.TP
\fB\-V\fR, \fB\-\-version
Display version information and exit.
.TP
\fB\-h\fR, \fB\-\-help
Display help text and exit.
.SH AUTHOR
This program was originally written by Rik Faith (faith@acm.org) and may be freely
distributed under the terms of the X11/MIT License. There is ABSOLUTELY
NO WARRANTY for this program.
The latest inotify-based implementation was written by Karel Zak (kzak@redhat.com).
.SH "SEE ALSO"
.BR less (1),
.BR tail (1)
.SH AVAILABILITY
The tailf command is part of the util-linux package and is available from
https://www.kernel.org/pub/linux/utils/util-linux/.

View File

@ -1,295 +0,0 @@
/* tailf.c -- tail a log file and then follow it
* Created: Tue Jan 9 15:49:21 1996 by faith@acm.org
* Copyright 1996, 2003 Rickard E. Faith (faith@acm.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* This command is deprecated. The utility is in maintenance mode,
* meaning we keep them in source tree for backward compatibility
* only. Do not waste time making this command better, unless the
* fix is about security or other very critical issue.
*
* See Documentation/deprecated.txt for more information.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <sys/mman.h>
#include <limits.h>
#ifdef HAVE_INOTIFY_INIT
#include <sys/inotify.h>
#endif
#include "nls.h"
#include "xalloc.h"
#include "strutils.h"
#include "c.h"
#include "closestream.h"
#define DEFAULT_LINES 10
/* st->st_size has to be greater than zero and smaller or equal to SIZE_MAX! */
static void tailf(const char *filename, size_t lines, struct stat *st)
{
int fd;
size_t i;
char *data;
fd = open(filename, O_RDONLY);
if (fd < 0)
err(EXIT_FAILURE, _("cannot open %s"), filename);
data = mmap(NULL, st->st_size, PROT_READ, MAP_SHARED, fd, 0);
i = (size_t) st->st_size - 1;
/* humans do not think last new line in a file should be counted,
* in that case do off by one from counter point of view */
if (data[i] == '\n')
lines++;
while (i) {
if (data[i] == '\n' && --lines == 0) {
i++;
break;
}
i--;
}
fwrite(data + i, st->st_size - i, 1, stdout);
munmap(data, st->st_size);
close(fd);
fflush(stdout);
}
static void roll_file(const char *filename, struct stat *old)
{
char buf[BUFSIZ];
int fd;
struct stat st;
off_t pos;
fd = open(filename, O_RDONLY);
if (fd < 0)
err(EXIT_FAILURE, _("cannot open %s"), filename);
if (fstat(fd, &st) == -1)
err(EXIT_FAILURE, _("stat of %s failed"), filename);
if (st.st_size == old->st_size) {
close(fd);
return;
}
if (lseek(fd, old->st_size, SEEK_SET) != (off_t)-1) {
ssize_t rc, wc;
while ((rc = read(fd, buf, sizeof(buf))) > 0) {
wc = write(STDOUT_FILENO, buf, rc);
if (rc != wc)
warnx(_("incomplete write to \"%s\" (written %zd, expected %zd)\n"),
filename, wc, rc);
}
fflush(stdout);
}
pos = lseek(fd, 0, SEEK_CUR);
/* If we've successfully read something, use the file position, this
* avoids data duplication. If we read nothing or hit an error, reset
* to the reported size, this handles truncated files.
*/
old->st_size = (pos != -1 && pos != old->st_size) ? pos : st.st_size;
close(fd);
}
static void watch_file(const char *filename, struct stat *old)
{
do {
roll_file(filename, old);
xusleep(250000);
} while(1);
}
#ifdef HAVE_INOTIFY_INIT
#define EVENTS (IN_MODIFY|IN_DELETE_SELF|IN_MOVE_SELF|IN_UNMOUNT)
#define NEVENTS 4
static int watch_file_inotify(const char *filename, struct stat *old)
{
char buf[ NEVENTS * sizeof(struct inotify_event) ];
int fd, ffd, e;
ssize_t len;
fd = inotify_init();
if (fd == -1)
return 0;
ffd = inotify_add_watch(fd, filename, EVENTS);
if (ffd == -1) {
if (errno == ENOSPC)
errx(EXIT_FAILURE, _("%s: cannot add inotify watch "
"(limit of inotify watches was reached)."),
filename);
err(EXIT_FAILURE, _("%s: cannot add inotify watch."), filename);
}
while (ffd >= 0) {
len = read(fd, buf, sizeof(buf));
if (len < 0 && (errno == EINTR || errno == EAGAIN))
continue;
if (len < 0)
err(EXIT_FAILURE,
_("%s: cannot read inotify events"), filename);
for (e = 0; e < len; ) {
struct inotify_event *ev = (struct inotify_event *) &buf[e];
if (ev->mask & IN_MODIFY)
roll_file(filename, old);
else {
close(ffd);
ffd = -1;
break;
}
e += sizeof(struct inotify_event) + ev->len;
}
}
close(fd);
return 1;
}
#endif /* HAVE_INOTIFY_INIT */
static void __attribute__ ((__noreturn__)) usage(FILE *out)
{
fputs(USAGE_HEADER, out);
fprintf(out, _(" %s [option] <file>\n"), program_invocation_short_name);
fputs(USAGE_SEPARATOR, out);
fputs(_("Follow the growth of a log file.\n"), out);
fputs(USAGE_OPTIONS, out);
fputs(_(" -n, --lines <number> output the last <number> lines\n"), out);
fputs(_(" -<number> same as '-n <number>'\n"), out);
fputs(USAGE_SEPARATOR, out);
fputs(USAGE_HELP, out);
fputs(USAGE_VERSION, out);
fprintf(out, USAGE_MAN_TAIL("tailf(1)"));
fputs(_("Warning: use of 'tailf' is deprecated, use 'tail -f' instead.\n"), out);
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}
/* parses -N option */
static long old_style_option(int *argc, char **argv, size_t *lines)
{
int i = 1, nargs = *argc, ret = 0;
while(i < nargs) {
if (argv[i][0] == '-' && isdigit(argv[i][1])) {
*lines = strtoul_or_err(argv[i] + 1,
_("failed to parse number of lines"));
nargs--;
ret = 1;
if (nargs - i)
memmove(argv + i, argv + i + 1,
sizeof(char *) * (nargs - i));
} else
i++;
}
*argc = nargs;
return ret;
}
int main(int argc, char **argv)
{
const char *filename;
size_t lines;
int ch;
struct stat st;
static const struct option longopts[] = {
{ "lines", required_argument, NULL, 'n' },
{ "version", no_argument, NULL, 'V' },
{ "help", no_argument, NULL, 'h' },
{ NULL, 0, NULL, 0 }
};
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
atexit(close_stdout);
if (!old_style_option(&argc, argv, &lines))
lines = DEFAULT_LINES;
while ((ch = getopt_long(argc, argv, "n:N:Vh", longopts, NULL)) != -1)
switch ((char)ch) {
case 'n':
case 'N':
lines = strtoul_or_err(optarg,
_("failed to parse number of lines"));
break;
case 'V':
printf(UTIL_LINUX_VERSION);
exit(EXIT_SUCCESS);
case 'h':
usage(stdout);
default:
errtryhelp(EXIT_FAILURE);
}
if (argc == optind)
errx(EXIT_FAILURE, _("no input file specified"));
filename = argv[optind];
if (stat(filename, &st) != 0)
err(EXIT_FAILURE, _("stat of %s failed"), filename);
if (!S_ISREG(st.st_mode))
errx(EXIT_FAILURE, _("%s: is not a file"), filename);
/* mmap is based on size_t */
if (st.st_size > 0 && (uintmax_t) st.st_size <= (uintmax_t) SIZE_MAX)
tailf(filename, lines, &st);
#ifdef HAVE_INOTIFY_INIT
if (!watch_file_inotify(filename, &st))
#endif
watch_file(filename, &st);
return EXIT_SUCCESS;
}