aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/tail
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/tail')
-rw-r--r--usr.bin/tail/tail.c12
-rwxr-xr-xusr.bin/tail/tests/tail_test.sh48
2 files changed, 55 insertions, 5 deletions
diff --git a/usr.bin/tail/tail.c b/usr.bin/tail/tail.c
index fc60a82287df..a92eee3881b4 100644
--- a/usr.bin/tail/tail.c
+++ b/usr.bin/tail/tail.c
@@ -95,15 +95,17 @@ main(int argc, char *argv[])
* -r is the entire file, not 10 lines.
*/
#define ARG(units, forward, backward) { \
+ int64_t num; \
if (style) \
usage(); \
- if (expand_number(optarg, &off)) \
+ if (expand_number(optarg, &num)) \
err(1, "illegal offset -- %s", optarg); \
- if (off > INT64_MAX / units || off < INT64_MIN / units ) \
+ if (num > INT64_MAX / units || num < INT64_MIN / units) \
errx(1, "illegal offset -- %s", optarg); \
- switch(optarg[0]) { \
+ off = num * units; \
+ switch (optarg[0]) { \
case '+': \
- if (off) \
+ if (off != 0) \
off -= (units); \
style = (forward); \
break; \
@@ -121,7 +123,7 @@ main(int argc, char *argv[])
off = 0;
while ((ch = getopt_long(argc, argv, "+Fb:c:fn:qrv", long_opts, NULL)) !=
-1)
- switch(ch) {
+ switch (ch) {
case 'F': /* -F is superset of (and implies) -f */
Fflag = fflag = 1;
break;
diff --git a/usr.bin/tail/tests/tail_test.sh b/usr.bin/tail/tests/tail_test.sh
index 9c941f8a2c2f..74d6908f7568 100755
--- a/usr.bin/tail/tests/tail_test.sh
+++ b/usr.bin/tail/tests/tail_test.sh
@@ -423,6 +423,51 @@ no_lf_at_eof_body()
atf_check -o inline:"a\nb\nc" tail -4 infile
}
+atf_test_case tail_b
+tail_b_head()
+{
+ atf_set "descr" "Test -b option"
+}
+tail_b_body()
+{
+ (jot -b a 256 ; jot -b b 256 ; jot -b c 256) >infile
+ (jot -b b 256 ; jot -b c 256) >outfile
+ # infile is 3 blocks long, outfile contains the last two
+ atf_check -o file:outfile tail -b +2 infile # start at the 2nd block
+ atf_check -o file:outfile tail -b -2 infile # 2 blocks from the end
+ atf_check -o file:outfile tail -b 2 infile # 2 blocks from the end
+}
+
+atf_test_case tail_c
+tail_c_head()
+{
+ atf_set "descr" "Test -c option"
+}
+tail_c_body()
+{
+ (jot -b a 256 ; jot -b b 256 ; jot -b c 256) >infile
+ (jot -b b 256 ; jot -b c 256) >outfile
+ # infile is 1536 bytes long, outfile contains the last 1024
+ atf_check -o file:outfile tail -c +513 infile # start at the 513th byte
+ atf_check -o file:outfile tail -c -1024 infile # 1024 bytes from the end
+ atf_check -o file:outfile tail -c 1024 infile # 1024 bytes from the end
+}
+
+atf_test_case tail_n
+tail_n_head()
+{
+ atf_set "descr" "Test -n option"
+}
+tail_n_body()
+{
+ (jot -b a 256 ; jot -b b 256 ; jot -b c 256) >infile
+ (jot -b b 256 ; jot -b c 256) >outfile
+ # infile is 768 lines long, outfile contains the last 512
+ atf_check -o file:outfile tail -n +257 infile # start at the 257th line
+ atf_check -o file:outfile tail -n -512 infile # 512 lines from the end
+ atf_check -o file:outfile tail -n 512 infile # 512 lines from the end
+}
+
atf_init_test_cases()
{
atf_add_test_case empty_r
@@ -448,4 +493,7 @@ atf_init_test_cases()
atf_add_test_case verbose_header
atf_add_test_case si_number
atf_add_test_case no_lf_at_eof
+ atf_add_test_case tail_b
+ atf_add_test_case tail_c
+ atf_add_test_case tail_n
}