summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSami Kerola2017-04-02 17:50:42 +0200
committerSami Kerola2017-04-02 17:51:00 +0200
commit70ca1a77721b41f2355eeb00d4e55e13dba3e313 (patch)
tree9f262b680e64e7af888f9bbebb7974a87352d10d
parenttests: add --mountpoint to findmnt calls (diff)
downloadkernel-qcow2-util-linux-70ca1a77721b41f2355eeb00d4e55e13dba3e313.tar.gz
kernel-qcow2-util-linux-70ca1a77721b41f2355eeb00d4e55e13dba3e313.tar.xz
kernel-qcow2-util-linux-70ca1a77721b41f2355eeb00d4e55e13dba3e313.zip
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: 3f8478a71ccde6883d4c81b7e65561a106653b28 Signed-off-by: Sami Kerola <kerolasa@iki.fi>
-rw-r--r--.gitignore1
-rw-r--r--Documentation/deprecated.txt5
-rw-r--r--bash-completion/Makemodule.am3
-rw-r--r--bash-completion/tailf28
-rw-r--r--configure.ac7
-rw-r--r--tests/commands.sh1
-rw-r--r--tests/expected/build-sys/config-all1
-rw-r--r--tests/expected/build-sys/config-all-devel1
-rw-r--r--tests/expected/build-sys/config-all-non-nls1
-rw-r--r--tests/expected/build-sys/config-audit1
-rw-r--r--tests/expected/build-sys/config-chfnsh-libuser1
-rw-r--r--tests/expected/build-sys/config-chfnsh-no-password1
-rw-r--r--tests/expected/build-sys/config-chfnsh-pam1
-rw-r--r--tests/expected/build-sys/config-core1
-rw-r--r--tests/expected/build-sys/config-devel1
-rw-r--r--tests/expected/build-sys/config-devel-new-mount1
-rw-r--r--tests/expected/build-sys/config-devel-non-docs1
-rw-r--r--tests/expected/build-sys/config-non-libblkid1
-rw-r--r--tests/expected/build-sys/config-non-libmount1
-rw-r--r--tests/expected/build-sys/config-non-libs1
-rw-r--r--tests/expected/build-sys/config-non-libsmartcols1
-rw-r--r--tests/expected/build-sys/config-non-libuuid1
-rw-r--r--tests/expected/build-sys/config-non-nls1
-rw-r--r--tests/expected/build-sys/config-selinux1
-rw-r--r--tests/expected/build-sys/config-slang1
-rw-r--r--tests/expected/build-sys/config-static1
-rwxr-xr-xtests/ts/tailf/simple40
-rw-r--r--text-utils/Makemodule.am7
-rw-r--r--text-utils/tailf.173
-rw-r--r--text-utils/tailf.c295
30 files changed, 0 insertions, 480 deletions
diff --git a/.gitignore b/.gitignore
index f325d5c77..38afedbab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -156,7 +156,6 @@ ylwrap
/swapoff
/swapon
/switch_root
-/tailf
/taskset
/test_*
/tunelp
diff --git a/Documentation/deprecated.txt b/Documentation/deprecated.txt
index df7f18fbf..5e8e9e151 100644
--- a/Documentation/deprecated.txt
+++ b/Documentation/deprecated.txt
@@ -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"
diff --git a/bash-completion/Makemodule.am b/bash-completion/Makemodule.am
index ff7b052b5..6885ae91c 100644
--- a/bash-completion/Makemodule.am
+++ b/bash-completion/Makemodule.am
@@ -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
diff --git a/bash-completion/tailf b/bash-completion/tailf
deleted file mode 100644
index 0d4c869c0..000000000
--- a/bash-completion/tailf
+++ /dev/null
@@ -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
diff --git a/configure.ac b/configure.ac
index 1acd2b00a..18bdf67f3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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]),
diff --git a/tests/commands.sh b/tests/commands.sh
index 2e5c11d1e..f655a6829 100644
--- a/tests/commands.sh
+++ b/tests/commands.sh
@@ -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"}
diff --git a/tests/expected/build-sys/config-all b/tests/expected/build-sys/config-all
index ce41a5707..302841b21 100644
--- a/tests/expected/build-sys/config-all
+++ b/tests/expected/build-sys/config-all
@@ -101,7 +101,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
tunelp:
ul: libtinfo
diff --git a/tests/expected/build-sys/config-all-devel b/tests/expected/build-sys/config-all-devel
index 812777d15..3e9a72072 100644
--- a/tests/expected/build-sys/config-all-devel
+++ b/tests/expected/build-sys/config-all-devel
@@ -112,5 +112,4 @@ line:
more: libtinfo
pg: libncursesw libtinfo
rev:
-tailf:
ul: libtinfo
diff --git a/tests/expected/build-sys/config-all-non-nls b/tests/expected/build-sys/config-all-non-nls
index ce41a5707..302841b21 100644
--- a/tests/expected/build-sys/config-all-non-nls
+++ b/tests/expected/build-sys/config-all-non-nls
@@ -101,7 +101,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
tunelp:
ul: libtinfo
diff --git a/tests/expected/build-sys/config-audit b/tests/expected/build-sys/config-audit
index 25592075b..dfdcd7731 100644
--- a/tests/expected/build-sys/config-audit
+++ b/tests/expected/build-sys/config-audit
@@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-chfnsh-libuser b/tests/expected/build-sys/config-chfnsh-libuser
index bc5bc9dbe..6fd737373 100644
--- a/tests/expected/build-sys/config-chfnsh-libuser
+++ b/tests/expected/build-sys/config-chfnsh-libuser
@@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-chfnsh-no-password b/tests/expected/build-sys/config-chfnsh-no-password
index b71a6a79f..884a3aef6 100644
--- a/tests/expected/build-sys/config-chfnsh-no-password
+++ b/tests/expected/build-sys/config-chfnsh-no-password
@@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-chfnsh-pam b/tests/expected/build-sys/config-chfnsh-pam
index fb1dda4bb..e7c6a922b 100644
--- a/tests/expected/build-sys/config-chfnsh-pam
+++ b/tests/expected/build-sys/config-chfnsh-pam
@@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-core b/tests/expected/build-sys/config-core
index e36eba9e6..3802c96fb 100644
--- a/tests/expected/build-sys/config-core
+++ b/tests/expected/build-sys/config-core
@@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-devel b/tests/expected/build-sys/config-devel
index 49e9083ea..58e25289b 100644
--- a/tests/expected/build-sys/config-devel
+++ b/tests/expected/build-sys/config-devel
@@ -101,7 +101,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
-tailf:
taskset:
tunelp:
ul: libtinfo
diff --git a/tests/expected/build-sys/config-devel-new-mount b/tests/expected/build-sys/config-devel-new-mount
index d56be6c70..9ac827257 100644
--- a/tests/expected/build-sys/config-devel-new-mount
+++ b/tests/expected/build-sys/config-devel-new-mount
@@ -119,5 +119,4 @@ line:
more: libtinfo
pg: libncursesw libtinfo
rev:
-tailf:
ul: libtinfo
diff --git a/tests/expected/build-sys/config-devel-non-docs b/tests/expected/build-sys/config-devel-non-docs
index 49e9083ea..58e25289b 100644
--- a/tests/expected/build-sys/config-devel-non-docs
+++ b/tests/expected/build-sys/config-devel-non-docs
@@ -101,7 +101,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
-tailf:
taskset:
tunelp:
ul: libtinfo
diff --git a/tests/expected/build-sys/config-non-libblkid b/tests/expected/build-sys/config-non-libblkid
index 3fcdbfe60..02667195b 100644
--- a/tests/expected/build-sys/config-non-libblkid
+++ b/tests/expected/build-sys/config-non-libblkid
@@ -76,7 +76,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-non-libmount b/tests/expected/build-sys/config-non-libmount
index 41315fb79..faf405dc5 100644
--- a/tests/expected/build-sys/config-non-libmount
+++ b/tests/expected/build-sys/config-non-libmount
@@ -85,7 +85,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-non-libs b/tests/expected/build-sys/config-non-libs
index 7a4311d7b..a661528dd 100644
--- a/tests/expected/build-sys/config-non-libs
+++ b/tests/expected/build-sys/config-non-libs
@@ -60,7 +60,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-non-libsmartcols b/tests/expected/build-sys/config-non-libsmartcols
index f29522415..d7b75cf8d 100644
--- a/tests/expected/build-sys/config-non-libsmartcols
+++ b/tests/expected/build-sys/config-non-libsmartcols
@@ -77,7 +77,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-non-libuuid b/tests/expected/build-sys/config-non-libuuid
index b327352c1..1894de08e 100644
--- a/tests/expected/build-sys/config-non-libuuid
+++ b/tests/expected/build-sys/config-non-libuuid
@@ -91,7 +91,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-non-nls b/tests/expected/build-sys/config-non-nls
index e36eba9e6..3802c96fb 100644
--- a/tests/expected/build-sys/config-non-nls
+++ b/tests/expected/build-sys/config-non-nls
@@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-selinux b/tests/expected/build-sys/config-selinux
index 84e67cbcd..a3ade2702 100644
--- a/tests/expected/build-sys/config-selinux
+++ b/tests/expected/build-sys/config-selinux
@@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: libselinux rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-slang b/tests/expected/build-sys/config-slang
index 5da133216..a78e16a04 100644
--- a/tests/expected/build-sys/config-slang
+++ b/tests/expected/build-sys/config-slang
@@ -98,7 +98,6 @@ setterm: libtinfo
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
unshare:
diff --git a/tests/expected/build-sys/config-static b/tests/expected/build-sys/config-static
index a5c23ad2b..ab514df9d 100644
--- a/tests/expected/build-sys/config-static
+++ b/tests/expected/build-sys/config-static
@@ -104,7 +104,6 @@ sfdisk.static: STATIC
su: libpam libpam_misc
sulogin: rypt
switch_root:
-tailf:
taskset:
ul: libtinfo
umount.static: STATIC
diff --git a/tests/ts/tailf/simple b/tests/ts/tailf/simple
deleted file mode 100755
index 35d10f3c4..000000000
--- a/tests/ts/tailf/simple
+++ /dev/null
@@ -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
diff --git a/text-utils/Makemodule.am b/text-utils/Makemodule.am
index e42704dfe..f260dd2b7 100644
--- a/text-utils/Makemodule.am
+++ b/text-utils/Makemodule.am
@@ -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
diff --git a/text-utils/tailf.1 b/text-utils/tailf.1
deleted file mode 100644
index f4a389c9e..000000000
--- a/text-utils/tailf.1
+++ /dev/null
@@ -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/.
diff --git a/text-utils/tailf.c b/text-utils/tailf.c
deleted file mode 100644
index 78ead34f7..000000000
--- a/text-utils/tailf.c
+++ /dev/null
@@ -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;
-}
-