aboutsummaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/Makefile10
-rw-r--r--usr.bin/beep/beep.c2
-rwxr-xr-xusr.bin/bsdcat/tests/functional_test.sh2
-rw-r--r--usr.bin/calendar/calendars/calendar.freebsd4
-rw-r--r--usr.bin/calendar/calendars/calendar.status_reports28
-rw-r--r--usr.bin/clang/Makefile5
-rw-r--r--usr.bin/clang/llvm-ar/Makefile3
-rw-r--r--usr.bin/clang/llvm-cov/Makefile2
-rw-r--r--usr.bin/clang/llvm-cxxfilt/Makefile4
-rw-r--r--usr.bin/clang/llvm-nm/Makefile2
-rw-r--r--usr.bin/clang/llvm-objcopy/Makefile4
-rw-r--r--usr.bin/clang/llvm-objdump/Makefile2
-rw-r--r--usr.bin/clang/llvm-readobj/Makefile2
-rw-r--r--usr.bin/clang/llvm-size/Makefile2
-rw-r--r--usr.bin/clang/llvm-symbolizer/Makefile2
-rwxr-xr-xusr.bin/cpio/tests/functional_test.sh2
-rw-r--r--usr.bin/diff/diff.c47
-rw-r--r--usr.bin/diff/diff.h3
-rw-r--r--usr.bin/diff/diffdir.c36
-rw-r--r--usr.bin/diff/diffreg.c45
-rw-r--r--usr.bin/diff/diffreg_new.c37
-rw-r--r--usr.bin/diff/pr.c37
-rw-r--r--usr.bin/diff/pr.h5
-rwxr-xr-xusr.bin/diff/tests/diff_test.sh126
-rw-r--r--usr.bin/diff3/diff3.117
-rw-r--r--usr.bin/diff3/diff3.c198
-rw-r--r--usr.bin/diff3/tests/Makefile16
-rw-r--r--usr.bin/diff3/tests/conflict-Em.out19
-rw-r--r--usr.bin/diff3/tests/conflict-merge.out25
-rw-r--r--usr.bin/diff3/tests/conflict1.txt5
-rw-r--r--usr.bin/diff3/tests/conflict2.txt9
-rw-r--r--usr.bin/diff3/tests/conflict3.txt5
-rwxr-xr-xusr.bin/diff3/tests/diff3_test.sh45
-rw-r--r--usr.bin/diff3/tests/passwd-Em.out16
-rw-r--r--usr.bin/diff3/tests/passwd-new.txt12
-rw-r--r--usr.bin/diff3/tests/passwd-old.txt11
-rw-r--r--usr.bin/diff3/tests/passwd-test.txt15
-rw-r--r--usr.bin/diff3/tests/simple-Em.out3
-rw-r--r--usr.bin/diff3/tests/simple-merge.out3
-rw-r--r--usr.bin/diff3/tests/simple1.txt2
-rw-r--r--usr.bin/diff3/tests/simple2.txt2
-rw-r--r--usr.bin/diff3/tests/simple3.txt3
-rw-r--r--usr.bin/etdump/etdump.c2
-rw-r--r--usr.bin/etdump/etdump.h2
-rw-r--r--usr.bin/etdump/output_shell.c2
-rw-r--r--usr.bin/etdump/output_text.c2
-rw-r--r--usr.bin/from/from.c19
-rw-r--r--usr.bin/kdump/kdump.c6
-rw-r--r--usr.bin/kyua/Makefile2
-rw-r--r--usr.bin/less/defines.h116
-rw-r--r--usr.bin/less/lesspipe.sh2
-rw-r--r--usr.bin/m4/eval.c10
-rw-r--r--usr.bin/m4/misc.c2
-rw-r--r--usr.bin/m4/tests/Makefile15
-rw-r--r--usr.bin/m4/tests/defn.m45
-rw-r--r--usr.bin/m4/tests/eval.m42
-rw-r--r--usr.bin/m4/tests/legacy_test.sh5
-rw-r--r--usr.bin/m4/tests/m4_test.sh249
-rw-r--r--usr.bin/m4/tests/regress.defn.out1
-rw-r--r--usr.bin/m4/tests/regress.eval.out2
-rw-r--r--usr.bin/m4/tests/regress.gnuprefix.err44
-rw-r--r--usr.bin/m4/tests/regress.gnuprefix.out44
-rw-r--r--usr.bin/m4/tests/regress.gnusofterror.err1
-rw-r--r--usr.bin/m4/tests/regress.gnusofterror.out1
-rw-r--r--usr.bin/m4/tests/regress.quotes.err2
-rw-r--r--usr.bin/m4/tests/regress.quotes.out2
-rw-r--r--usr.bin/m4/tests/regress.sh32
-rw-r--r--usr.bin/man/manpath.12
-rw-r--r--usr.bin/mkimg/apm.c2
-rw-r--r--usr.bin/mkimg/bsd.c2
-rw-r--r--usr.bin/mkimg/ebr.c2
-rw-r--r--usr.bin/mkimg/endian.h2
-rw-r--r--usr.bin/mkimg/format.c2
-rw-r--r--usr.bin/mkimg/format.h2
-rw-r--r--usr.bin/mkimg/gpt.c2
-rw-r--r--usr.bin/mkimg/image.c2
-rw-r--r--usr.bin/mkimg/image.h2
-rw-r--r--usr.bin/mkimg/mbr.c2
-rw-r--r--usr.bin/mkimg/mkimg.c2
-rw-r--r--usr.bin/mkimg/mkimg.h2
-rw-r--r--usr.bin/mkimg/qcow.c2
-rw-r--r--usr.bin/mkimg/raw.c2
-rw-r--r--usr.bin/mkimg/scheme.c2
-rw-r--r--usr.bin/mkimg/scheme.h2
-rw-r--r--usr.bin/mkimg/uuid.c2
-rw-r--r--usr.bin/mkimg/vhd.c2
-rw-r--r--usr.bin/mkimg/vhdx.c2
-rw-r--r--usr.bin/mkimg/vmdk.c2
-rw-r--r--usr.bin/mt/mt.19
-rw-r--r--usr.bin/netstat/mroute.c11
-rw-r--r--usr.bin/netstat/mroute6.c13
-rw-r--r--usr.bin/netstat/route_netlink.c5
-rw-r--r--usr.bin/newgrp/newgrp.117
-rw-r--r--usr.bin/paste/Makefile8
-rw-r--r--usr.bin/paste/paste.c61
-rw-r--r--usr.bin/procstat/procstat_kqueue.c6
-rw-r--r--usr.bin/resizewin/resizewin.c2
-rw-r--r--usr.bin/rpcinfo/rpcinfo.c8
-rw-r--r--usr.bin/runat/runat.c35
-rw-r--r--usr.bin/rup/rup.c2
-rw-r--r--usr.bin/rusers/rusers.c2
-rw-r--r--usr.bin/sockstat/main.c10
-rwxr-xr-xusr.bin/tar/tests/functional_test.sh4
-rw-r--r--usr.bin/touch/tests/touch_test.sh66
-rw-r--r--usr.bin/touch/touch.c13
-rw-r--r--usr.bin/tr/tr.c34
-rwxr-xr-xusr.bin/unzip/tests/functional_test.sh2
-rw-r--r--usr.bin/vtfontcvt/vtfontcvt.c2
-rwxr-xr-xusr.bin/xinstall/tests/install_test.sh38
-rw-r--r--usr.bin/xinstall/xinstall.c44
-rw-r--r--usr.bin/yes/Makefile4
-rw-r--r--usr.bin/yes/tests/Makefile4
-rw-r--r--usr.bin/yes/tests/yes_test.sh85
-rw-r--r--usr.bin/yes/yes.16
-rw-r--r--usr.bin/yes/yes.c76
115 files changed, 1482 insertions, 515 deletions
diff --git a/usr.bin/Makefile b/usr.bin/Makefile
index 0f0233bb5091..6ca784ef6cb6 100644
--- a/usr.bin/Makefile
+++ b/usr.bin/Makefile
@@ -24,10 +24,12 @@ SUBDIR= apply \
comm \
command \
compress \
+ cpio \
csplit \
ctlstat \
cut \
diff \
+ diff3 \
dirname \
dtc \
du \
@@ -185,7 +187,6 @@ SUBDIR= apply \
SUBDIR.${MK_ACCT}+= lastcomm
SUBDIR.${MK_AT}+= at
SUBDIR.${MK_BLUETOOTH}+= bluetooth
-SUBDIR.${MK_BSD_CPIO}+= cpio
SUBDIR.${MK_CALENDAR}+= calendar
.if ${MK_CLANG} != "no" || ${MK_LLVM_BINUTILS} != "no" || \
${MK_LLD} != "no" || ${MK_LLDB} != "no"
@@ -206,9 +207,6 @@ SUBDIR.${MK_GAMES}+= pom
SUBDIR.${MK_GAMES}+= primes
SUBDIR.${MK_GAMES}+= random
SUBDIR+= gh-bc
-.if ${MK_GNU_DIFF} == "no"
-SUBDIR+= diff3
-.endif
SUBDIR.${MK_HESIOD}+= hesinfo
SUBDIR.${MK_ICONV}+= iconv
SUBDIR.${MK_ICONV}+= mkcsmapper
@@ -250,6 +248,7 @@ SUBDIR.${MK_TFTP}+= tftp
# Only build the elftoolchain tools if we aren't using the LLVM ones.
SUBDIR.${MK_TOOLCHAIN}+= addr2line
SUBDIR.${MK_TOOLCHAIN}+= ar
+SUBDIR.${MK_TOOLCHAIN}+= cxxfilt
SUBDIR.${MK_TOOLCHAIN}+= nm
SUBDIR.${MK_TOOLCHAIN}+= readelf
SUBDIR.${MK_TOOLCHAIN}+= size
@@ -257,9 +256,6 @@ SUBDIR.${MK_TOOLCHAIN}+= size
SUBDIR.${MK_TOOLCHAIN}+= c89
SUBDIR.${MK_TOOLCHAIN}+= c99
SUBDIR.${MK_TOOLCHAIN}+= ctags
-.if ${MK_LLVM_CXXFILT} == "no"
-SUBDIR.${MK_TOOLCHAIN}+= cxxfilt
-.endif
# ELF Tool Chain elfcopy required for EFI objects (PR280771)
SUBDIR.${MK_TOOLCHAIN}+= elfcopy
SUBDIR.${MK_TOOLCHAIN}+= file2c
diff --git a/usr.bin/beep/beep.c b/usr.bin/beep/beep.c
index d16ad5b699c3..a6e09fbf61c1 100644
--- a/usr.bin/beep/beep.c
+++ b/usr.bin/beep/beep.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2021 Hans Petter Selasky <hselasky@freebsd.org>
*
* Redistribution and use in source and binary forms, with or without
diff --git a/usr.bin/bsdcat/tests/functional_test.sh b/usr.bin/bsdcat/tests/functional_test.sh
index efed232374e2..27bf51298bb8 100755
--- a/usr.bin/bsdcat/tests/functional_test.sh
+++ b/usr.bin/bsdcat/tests/functional_test.sh
@@ -46,7 +46,7 @@ atf_init_test_cases()
# Redirect stderr to stdout for the usage message because if you don't
# kyua list/kyua test will break:
# https://github.com/jmmv/kyua/issues/149
- testcases=$(${TESTER} -h 2>&1 | awk 'p != 0 && $1 ~ /^[0-9]+:/ { print $NF } /Available tests:/ { p=1 }')
+ testcases=$(${TESTER} -l 2>&1 | awk '/^ [0-9]+: / { print $2 }')
for testcase in ${testcases}; do
atf_test_case ${testcase}
eval "${testcase}_body() { check ${testcase}; }"
diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd
index bfcdfe5f9a75..37dad2d237a7 100644
--- a/usr.bin/calendar/calendars/calendar.freebsd
+++ b/usr.bin/calendar/calendars/calendar.freebsd
@@ -123,7 +123,6 @@
03/14 Eric Turgeon <ericbsd@FreeBSD.org> born in Edmundston, New Brunswick, Canada, 1982
03/15 Paolo Pisati <piso@FreeBSD.org> born in Lodi, Italy, 1977
03/15 Brian Fundakowski Feldman <green@FreeBSD.org> born in Alexandria, Virginia, United States, 1983
-03/15 First quarterly status reports are due on 03/31
03/17 Michael Smith <msmith@FreeBSD.org> born in Bankstown, New South Wales, Australia, 1971
03/17 Alexander Motin <mav@FreeBSD.org> born in Simferopol, Ukraine, 1979
03/18 Koop Mast <kwm@FreeBSD.org> born in Dokkum, the Netherlands, 1981
@@ -260,7 +259,6 @@
06/09 Stanislav Galabov <sgalabov@FreeBSD.org> born in Sofia, Bulgaria, 1978
06/11 Alonso Cardenas Marquez <acm@FreeBSD.org> born in Arequipa, Peru, 1979
06/14 Josh Paetzel <jpaetzel@FreeBSD.org> born in Minneapolis, Minnesota, United States, 1973
-06/15 Second quarterly status reports are due on 06/30
06/15 Aymeric Wibo <obiwac@FreeBSD.org> born in Plaistow, London, United Kingdom, 2004
06/17 Tilman Linneweh <arved@FreeBSD.org> born in Weinheim, Baden-Wuerttemberg, Germany, 1978
06/18 Li-Wen Hsu <lwhsu@FreeBSD.org> born in Taipei, Taiwan, Republic of China, 1984
@@ -382,7 +380,6 @@
09/14 Matthew Seaman <matthew@FreeBSD.org> born in Bristol, United Kingdom, 1965
09/15 Aleksandr Rybalko <ray@FreeBSD.org> born in Odessa, Ukraine, 1977
09/15 Dima Panov <fluffy@FreeBSD.org> born in Khabarovsk, Russian Federation, 1978
-09/15 Third quarterly status reports are due on 09/30
09/16 Maksim Yevmenkin <emax@FreeBSD.org> born in Taganrog, USSR, 1974
09/17 Maxim Bolotin <mb@FreeBSD.org> born in Rostov-on-Don, Russian Federation, 1976
09/18 Matthew Fleming <mdf@FreeBSD.org> born in Cleveland, Ohio, United States, 1975
@@ -488,7 +485,6 @@
12/11 Koichiro Iwao <meta@FreeBSD.org> born in Oita, Japan, 1987
12/15 James FitzGibbon <jfitz@FreeBSD.org> born in Amersham, Buckinghamshire, United Kingdom, 1974
12/15 Timur I. Bakeyev <timur@FreeBSD.org> born in Kazan, Republic of Tatarstan, USSR, 1974
-12/15 Fourth quarterly status reports are due on 12/31
12/18 Chris Timmons <cwt@FreeBSD.org> born in Ellensburg, Washington, United States, 1964
12/18 Dag-Erling Smorgrav <des@FreeBSD.org> born in Brussels, Belgium, 1977
12/18 Muhammad Moinur Rahman <bofh@FreeBSD.org> born in Dhaka, Bangladesh, 1983
diff --git a/usr.bin/calendar/calendars/calendar.status_reports b/usr.bin/calendar/calendars/calendar.status_reports
new file mode 100644
index 000000000000..f4e1e7b822cf
--- /dev/null
+++ b/usr.bin/calendar/calendars/calendar.status_reports
@@ -0,0 +1,28 @@
+/*
+ * FreeBSD
+ */
+
+#ifndef _calendar_status_reports_
+#define _calendar_status_reports_
+
+03/01 Status Reports: First call for Q1
+03/15 Status Reports: 1 month left reminder for Q1
+03/31 Status Reports: 2 weeks left reminder for Q1
+04/14 Status Reports: Q1 deadline
+
+06/01 Status Reports: First call for Q2
+06/15 Status Reports: 1 month left reminder for Q2
+06/30 Status Reports: 2 weeks left reminder for Q2
+07/14 Status Reports: Q2 deadline
+
+09/01 Status Reports: First call for Q3
+09/15 Status Reports: 1 month left reminder for Q3
+09/30 Status Reports: 2 weeks left reminder for Q3
+10/14 Status Reports: Q3 deadline
+
+12/01 Status Reports: First call for Q4
+12/15 Status Reports: 1 month left reminder for Q4
+12/31 Status Reports: 2 weeks left reminder for Q4
+01/14 Status Reports: Q4 deadline
+
+#endif /* !_calendar_status_reports_ */
diff --git a/usr.bin/clang/Makefile b/usr.bin/clang/Makefile
index e2debfb8c582..ac92b08a54cb 100644
--- a/usr.bin/clang/Makefile
+++ b/usr.bin/clang/Makefile
@@ -14,6 +14,7 @@ SUBDIR+= clang-scan-deps
# as the default binutils (ar,nm,addr2line, etc.).
.if ${MK_CLANG} != "no" || ${MK_LLVM_BINUTILS} != "no"
SUBDIR+= llvm-ar
+SUBDIR+= llvm-cxxfilt
SUBDIR+= llvm-nm
SUBDIR+= llvm-objcopy
SUBDIR+= llvm-objdump
@@ -23,10 +24,6 @@ SUBDIR+= llvm-strings
SUBDIR+= llvm-symbolizer
.endif
-.if ${MK_LLVM_BINUTILS} != "no" || ${MK_LLVM_CXXFILT} != "no"
-SUBDIR+= llvm-cxxfilt
-.endif
-
.if ${MK_CLANG_EXTRAS} != "no"
SUBDIR+= bugpoint
SUBDIR+= llc
diff --git a/usr.bin/clang/llvm-ar/Makefile b/usr.bin/clang/llvm-ar/Makefile
index e019c89b3581..ee776a7c0d9e 100644
--- a/usr.bin/clang/llvm-ar/Makefile
+++ b/usr.bin/clang/llvm-ar/Makefile
@@ -11,7 +11,8 @@ SRCS+= llvm-ar.cpp
LINKS+= ${BINDIR}/llvm-ar ${BINDIR}/llvm-ranlib
.if ${MK_LLVM_BINUTILS} != "no"
-LINKS+= ${BINDIR}/llvm-ar ${BINDIR}/ar ${BINDIR}/llvm-ar ${BINDIR}/ranlib
+SYMLINKS+= llvm-ar ${BINDIR}/ar
+SYMLINKS+= llvm-ranlib ${BINDIR}/ranlib
MLINKS+= llvm-ar.1 ar.1 llvm-ar.1 ranlib.1
.endif
diff --git a/usr.bin/clang/llvm-cov/Makefile b/usr.bin/clang/llvm-cov/Makefile
index 3eb14eb37139..3c02d4b7d144 100644
--- a/usr.bin/clang/llvm-cov/Makefile
+++ b/usr.bin/clang/llvm-cov/Makefile
@@ -1,7 +1,7 @@
.include <src.opts.mk>
PROG_CXX= llvm-cov
-LINKS= ${BINDIR}/llvm-cov ${BINDIR}/gcov
+SYMLINKS= llvm-cov ${BINDIR}/gcov
MLINKS= llvm-cov.1 gcov.1
SRCDIR= llvm/tools/llvm-cov
diff --git a/usr.bin/clang/llvm-cxxfilt/Makefile b/usr.bin/clang/llvm-cxxfilt/Makefile
index f9621da8da89..26a5d9e8975d 100644
--- a/usr.bin/clang/llvm-cxxfilt/Makefile
+++ b/usr.bin/clang/llvm-cxxfilt/Makefile
@@ -22,8 +22,8 @@ DEPENDFILES+= ${TGHDRS:C/$/.d/}
DPSRCS+= ${TGHDRS}
CLEANFILES+= ${TGHDRS} ${TGHDRS:C/$/.d/}
-.if ${MK_LLVM_CXXFILT} != "no"
-LINKS= ${BINDIR}/llvm-cxxfilt ${BINDIR}/c++filt
+.if ${MK_LLVM_BINUTILS} != "no"
+SYMLINKS= llvm-cxxfilt ${BINDIR}/c++filt
MLINKS= llvm-cxxfilt.1 c++filt.1
.endif
diff --git a/usr.bin/clang/llvm-nm/Makefile b/usr.bin/clang/llvm-nm/Makefile
index 7e089d1b408d..333513246cb6 100644
--- a/usr.bin/clang/llvm-nm/Makefile
+++ b/usr.bin/clang/llvm-nm/Makefile
@@ -24,7 +24,7 @@ DPSRCS+= ${TGHDRS}
CLEANFILES+= ${TGHDRS} ${TGHDRS:C/$/.d/}
.if ${MK_LLVM_BINUTILS} != "no"
-LINKS+= ${BINDIR}/llvm-nm ${BINDIR}/nm
+SYMLINKS+= llvm-nm ${BINDIR}/nm
MLINKS+= llvm-nm.1 nm.1
.endif
diff --git a/usr.bin/clang/llvm-objcopy/Makefile b/usr.bin/clang/llvm-objcopy/Makefile
index fcf59e4b4bca..13bbab97899f 100644
--- a/usr.bin/clang/llvm-objcopy/Makefile
+++ b/usr.bin/clang/llvm-objcopy/Makefile
@@ -27,8 +27,8 @@ CLEANFILES+= ${TGHDRS} ${TGHDRS:C/$/.d/}
LINKS= ${BINDIR}/llvm-objcopy ${BINDIR}/llvm-strip
.if ${MK_LLVM_BINUTILS} != "no"
-LINKS+= ${BINDIR}/llvm-objcopy ${BINDIR}/objcopy \
- ${BINDIR}/llvm-strip ${BINDIR}/strip
+SYMLINKS+= llvm-objcopy ${BINDIR}/objcopy \
+ llvm-strip ${BINDIR}/strip
MLINKS= llvm-objcopy.1 objcopy.1 \
llvm-objcopy.1 strip.1
.endif
diff --git a/usr.bin/clang/llvm-objdump/Makefile b/usr.bin/clang/llvm-objdump/Makefile
index ad1c7beee95f..86281217ee0a 100644
--- a/usr.bin/clang/llvm-objdump/Makefile
+++ b/usr.bin/clang/llvm-objdump/Makefile
@@ -29,7 +29,7 @@ DEPENDFILES+= ${TGHDRS:C/$/.d/}
DPSRCS+= ${TGHDRS}
CLEANFILES+= ${TGHDRS} ${TGHDRS:C/$/.d/}
-LINKS= ${BINDIR}/llvm-objdump ${BINDIR}/objdump
+SYMLINKS= llvm-objdump ${BINDIR}/objdump
MLINKS= llvm-objdump.1 objdump.1
.include "../llvm.prog.mk"
diff --git a/usr.bin/clang/llvm-readobj/Makefile b/usr.bin/clang/llvm-readobj/Makefile
index f532358ea79e..3f705431e509 100644
--- a/usr.bin/clang/llvm-readobj/Makefile
+++ b/usr.bin/clang/llvm-readobj/Makefile
@@ -36,7 +36,7 @@ CLEANFILES+= ${TGHDRS} ${TGHDRS:C/$/.d/}
LINKS+= ${BINDIR}/llvm-readobj ${BINDIR}/llvm-readelf
.if ${MK_LLVM_BINUTILS} != "no"
-LINKS+= ${BINDIR}/llvm-readelf ${BINDIR}/readelf
+SYMLINKS+= llvm-readelf ${BINDIR}/readelf
MLINKS+= llvm-readelf.1 readelf.1
.endif
diff --git a/usr.bin/clang/llvm-size/Makefile b/usr.bin/clang/llvm-size/Makefile
index 9d3505cdd319..1991065b61b2 100644
--- a/usr.bin/clang/llvm-size/Makefile
+++ b/usr.bin/clang/llvm-size/Makefile
@@ -24,7 +24,7 @@ DPSRCS+= ${TGHDRS}
CLEANFILES+= ${TGHDRS} ${TGHDRS:C/$/.d/}
.if ${MK_LLVM_BINUTILS} != "no"
-LINKS+= ${BINDIR}/llvm-size ${BINDIR}/size
+SYMLINKS+= llvm-size ${BINDIR}/size
MLINKS+= llvm-size.1 size.1
.endif
diff --git a/usr.bin/clang/llvm-symbolizer/Makefile b/usr.bin/clang/llvm-symbolizer/Makefile
index c45300c92a90..1a3a65c774c9 100644
--- a/usr.bin/clang/llvm-symbolizer/Makefile
+++ b/usr.bin/clang/llvm-symbolizer/Makefile
@@ -26,7 +26,7 @@ CLEANFILES+= ${TGHDRS} ${TGHDRS:C/$/.d/}
LINKS+= ${BINDIR}/llvm-symbolizer ${BINDIR}/llvm-addr2line
.if ${MK_LLVM_BINUTILS} != "no"
-LINKS+= ${BINDIR}/llvm-symbolizer ${BINDIR}/addr2line
+SYMLINKS+= llvm-addr2line ${BINDIR}/addr2line
MLINKS+= llvm-addr2line.1 addr2line.1
.endif
diff --git a/usr.bin/cpio/tests/functional_test.sh b/usr.bin/cpio/tests/functional_test.sh
index a915cc91faea..6bc58e5236ae 100755
--- a/usr.bin/cpio/tests/functional_test.sh
+++ b/usr.bin/cpio/tests/functional_test.sh
@@ -46,7 +46,7 @@ atf_init_test_cases()
# Redirect stderr to stdout for the usage message because if you don't
# kyua list/kyua test will break:
# https://github.com/jmmv/kyua/issues/149
- testcases=$(${TESTER} -h 2>&1 | awk 'p != 0 && $1 ~ /^[0-9]+:/ { print $NF } /Available tests:/ { p=1 }')
+ testcases=$(${TESTER} -l 2>&1 | awk '/^ [0-9]+: / { print $2 }')
for testcase in ${testcases}; do
atf_test_case ${testcase}
eval "${testcase}_body() { check ${testcase}; }"
diff --git a/usr.bin/diff/diff.c b/usr.bin/diff/diff.c
index 83aa20c52cf3..b5fa12268bac 100644
--- a/usr.bin/diff/diff.c
+++ b/usr.bin/diff/diff.c
@@ -35,7 +35,7 @@
#include "diff.h"
#include "xmalloc.h"
-static const char diff_version[] = "FreeBSD diff 20240307";
+static const char diff_version[] = "FreeBSD diff 20260206";
bool lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag;
bool ignore_file_case, suppress_common, color, noderef;
static bool help = false;
@@ -137,10 +137,9 @@ static bool do_color(void);
int
main(int argc, char **argv)
{
- const char *errstr = NULL;
- char *ep, **oargv;
- long l;
- int ch, dflags, lastch, gotstdin, prevoptind, newarg;
+ const char *errstr;
+ char **oargv;
+ int ch, dflags, lastch, gotstdin, prevoptind, newarg;
oargv = argv;
gotstdin = 0;
@@ -177,7 +176,7 @@ main(int argc, char **argv)
}
if (diff_algorithm == D_DIFFNONE) {
- printf("unknown algorithm: %s\n", optarg);
+ warnx("unknown algorithm: %s", optarg);
usage();
}
break;
@@ -194,10 +193,13 @@ main(int argc, char **argv)
cflag = true;
diff_format = D_CONTEXT;
if (optarg != NULL) {
- l = strtol(optarg, &ep, 10);
- if (*ep != '\0' || l < 0 || l >= INT_MAX)
+ diff_context = (int) strtonum(optarg,
+ 1, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ warnx("context size is %s: %s",
+ errstr, optarg);
usage();
- diff_context = (int)l;
+ }
}
break;
case 'd':
@@ -249,6 +251,7 @@ main(int argc, char **argv)
usage();
break;
case 'l':
+ dflags |= D_PAGINATION;
lflag = true;
break;
case 'N':
@@ -293,10 +296,13 @@ main(int argc, char **argv)
conflicting_format();
diff_format = D_UNIFIED;
if (optarg != NULL) {
- l = strtol(optarg, &ep, 10);
- if (*ep != '\0' || l < 0 || l >= INT_MAX)
+ diff_context = (int) strtonum(optarg,
+ 0, INT_MAX, &errstr);
+ if (errstr != NULL) {
+ warnx("context size is %s: %s",
+ errstr, optarg);
usage();
- diff_context = (int)l;
+ }
}
break;
case 'w':
@@ -304,8 +310,8 @@ main(int argc, char **argv)
break;
case 'W':
width = (int) strtonum(optarg, 1, INT_MAX, &errstr);
- if (errstr) {
- warnx("Invalid argument for width");
+ if (errstr != NULL) {
+ warnx("width is %s: %s", errstr, optarg);
usage();
}
break;
@@ -345,8 +351,8 @@ main(int argc, char **argv)
break;
case OPT_TSIZE:
tabsize = (int) strtonum(optarg, 1, INT_MAX, &errstr);
- if (errstr) {
- warnx("Invalid argument for tabsize");
+ if (errstr != NULL) {
+ warnx("tabsize is %s: %s", errstr, optarg);
usage();
}
break;
@@ -363,9 +369,12 @@ main(int argc, char **argv)
colorflag = COLORFLAG_ALWAYS;
else if (strncmp(optarg, "never", 5) == 0)
colorflag = COLORFLAG_NEVER;
- else
- errx(2, "unsupported --color value '%s' (must be always, auto, or never)",
- optarg);
+ else {
+ warnx("unsupported --color value "
+ "(must be always, auto, or never): "
+ "%s", optarg);
+ usage();
+ }
break;
case OPT_NO_DEREFERENCE:
noderef = true;
diff --git a/usr.bin/diff/diff.h b/usr.bin/diff/diff.h
index 74be55db8a33..fe41e8746f4d 100644
--- a/usr.bin/diff/diff.h
+++ b/usr.bin/diff/diff.h
@@ -1,6 +1,8 @@
/* $OpenBSD: diff.h,v 1.34 2020/11/01 18:16:08 jcs Exp $ */
/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -80,6 +82,7 @@
#define D_STRIPCR 0x400 /* Strip trailing cr */
#define D_SKIPBLANKLINES 0x800 /* Skip blank lines */
#define D_MATCHLAST 0x1000 /* Display last line matching provided regex */
+#define D_PAGINATION 0x2000 /* Paginate via pr(1) */
/* Features supported by new algorithms */
#define D_NEWALGO_FLAGS (D_FORCEASCII | D_PROTOTYPE | D_IGNOREBLANKS)
diff --git a/usr.bin/diff/diffdir.c b/usr.bin/diff/diffdir.c
index a55a2bec70ee..489b873e2fcf 100644
--- a/usr.bin/diff/diffdir.c
+++ b/usr.bin/diff/diffdir.c
@@ -41,8 +41,6 @@ static void diffit(struct dirent *, char *, size_t, struct dirent *,
char *, size_t, int);
static void print_only(const char *, size_t, const char *);
-#define d_status d_type /* we need to store status for -l */
-
struct inode {
dev_t dev;
ino_t ino;
@@ -62,7 +60,8 @@ static struct inodetree v2 = RB_INITIALIZER(&v2);
RB_GENERATE_STATIC(inodetree, inode, entry, inodecmp);
static int
-vscandir(struct inodetree *tree, const char *path, struct dirent ***dirp,
+vscandir(struct inodetree *tree, struct inode **inop,
+ const char *path, struct dirent ***dirp,
int (*selectf)(const struct dirent *),
int (*comparf)(const struct dirent **, const struct dirent **))
{
@@ -87,6 +86,7 @@ vscandir(struct inodetree *tree, const char *path, struct dirent ***dirp,
goto fail;
RB_INSERT(inodetree, tree, ino);
close(fd);
+ *inop = ino;
return (ret);
fail:
serrno = errno;
@@ -98,6 +98,13 @@ fail:
return (-1);
}
+static void
+leavedir(struct inodetree *tree, struct inode *ino)
+{
+ RB_REMOVE(inodetree, tree, ino);
+ free(ino);
+}
+
/*
* Diff directory traversal. Will be called recursively if -r was specified.
*/
@@ -106,6 +113,7 @@ diffdir(char *p1, char *p2, int flags)
{
struct dirent *dent1, **dp1, **edp1, **dirp1 = NULL;
struct dirent *dent2, **dp2, **edp2, **dirp2 = NULL;
+ struct inode *ino1 = NULL, *ino2 = NULL;
size_t dirlen1, dirlen2;
char path1[PATH_MAX], path2[PATH_MAX];
int pos;
@@ -133,7 +141,7 @@ diffdir(char *p1, char *p2, int flags)
* Get a list of entries in each directory, skipping "excluded" files
* and sorting alphabetically.
*/
- pos = vscandir(&v1, path1, &dirp1, selectfile, alphasort);
+ pos = vscandir(&v1, &ino1, path1, &dirp1, selectfile, alphasort);
if (pos == -1) {
if (errno == ENOENT && (Nflag || Pflag)) {
pos = 0;
@@ -145,7 +153,7 @@ diffdir(char *p1, char *p2, int flags)
dp1 = dirp1;
edp1 = dirp1 + pos;
- pos = vscandir(&v2, path2, &dirp2, selectfile, alphasort);
+ pos = vscandir(&v2, &ino2, path2, &dirp2, selectfile, alphasort);
if (pos == -1) {
if (errno == ENOENT && Nflag) {
pos = 0;
@@ -219,11 +227,15 @@ diffdir(char *p1, char *p2, int flags)
closem:
if (dirp1 != NULL) {
+ if (ino1 != NULL)
+ leavedir(&v1, ino1);
for (dp1 = dirp1; dp1 < edp1; dp1++)
free(*dp1);
free(dirp1);
}
if (dirp2 != NULL) {
+ if (ino2 != NULL)
+ leavedir(&v2, ino2);
for (dp2 = dirp2; dp2 < edp2; dp2++)
free(*dp2);
free(dirp2);
@@ -237,6 +249,8 @@ static void
diffit(struct dirent *dp, char *path1, size_t plen1, struct dirent *dp2,
char *path2, size_t plen2, int flags)
{
+ int rc;
+
flags |= D_HEADER;
strlcpy(path1 + plen1, dp->d_name, PATH_MAX - plen1);
@@ -258,7 +272,6 @@ diffit(struct dirent *dp, char *path1, size_t plen1, struct dirent *dp2,
flags |= D_EMPTY1;
memset(&stb1, 0, sizeof(stb1));
}
-
if (lstat(path2, &stb2) != 0) {
if (!Nflag || errno != ENOENT) {
warn("%s", path2);
@@ -315,7 +328,6 @@ diffit(struct dirent *dp, char *path1, size_t plen1, struct dirent *dp2,
flags |= D_EMPTY1;
memset(&stb1, 0, sizeof(stb1));
}
-
if (stat(path2, &stb2) != 0) {
if (!Nflag || errno != ENOENT) {
warn("%s", path2);
@@ -328,6 +340,8 @@ diffit(struct dirent *dp, char *path1, size_t plen1, struct dirent *dp2,
if (stb1.st_mode == 0)
stb1.st_mode = stb2.st_mode;
}
+ if (stb1.st_dev == stb2.st_dev && stb1.st_ino == stb2.st_ino)
+ return;
if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
if (rflag)
diffdir(path1, path2, flags);
@@ -337,12 +351,12 @@ diffit(struct dirent *dp, char *path1, size_t plen1, struct dirent *dp2,
return;
}
if (!S_ISREG(stb1.st_mode) && !S_ISDIR(stb1.st_mode))
- dp->d_status = D_SKIPPED1;
+ rc = D_SKIPPED1;
else if (!S_ISREG(stb2.st_mode) && !S_ISDIR(stb2.st_mode))
- dp->d_status = D_SKIPPED2;
+ rc = D_SKIPPED2;
else
- dp->d_status = diffreg(path1, path2, flags, 0);
- print_status(dp->d_status, path1, path2, "");
+ rc = diffreg(path1, path2, flags, 0);
+ print_status(rc, path1, path2, "");
}
/*
diff --git a/usr.bin/diff/diffreg.c b/usr.bin/diff/diffreg.c
index ffa5568bf442..8dcf55a7190b 100644
--- a/usr.bin/diff/diffreg.c
+++ b/usr.bin/diff/diffreg.c
@@ -77,6 +77,7 @@
#include <paths.h>
#include <regex.h>
#include <stdbool.h>
+#include <stdckdint.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
@@ -371,6 +372,9 @@ diffreg_stone(char *file1, char *file2, int flags, int capsicum)
goto closem;
}
+ if (stb1.st_dev == stb2.st_dev && stb1.st_ino == stb2.st_ino)
+ goto closem;
+
if (lflag)
pr = start_pr(file1, file2);
@@ -402,6 +406,10 @@ diffreg_stone(char *file1, char *file2, int flags, int capsicum)
break;
default:
/* error */
+ if (ferror(f1))
+ warn("%s", file1);
+ if (ferror(f2))
+ warn("%s", file2);
rval = D_ERROR;
status |= 2;
goto closem;
@@ -495,9 +503,9 @@ files_differ(FILE *f1, FILE *f2, int flags)
return (0);
for (;;) {
- i = fread(buf1, 1, sizeof(buf1), f1);
- j = fread(buf2, 1, sizeof(buf2), f2);
- if ((!i && ferror(f1)) || (!j && ferror(f2)))
+ if ((i = fread(buf1, 1, sizeof(buf1), f1)) == 0 && ferror(f1))
+ return (-1);
+ if ((j = fread(buf2, 1, sizeof(buf2), f2)) == 0 && ferror(f2))
return (-1);
if (i != j)
return (1);
@@ -1056,7 +1064,7 @@ change(char *file1, FILE *f1, char *file2, FILE *f2, int a, int b, int c, int d,
{
static size_t max_context = 64;
long curpos;
- int i, nc;
+ int dist, i, nc;
const char *walk;
bool skip_blanks, ignore;
@@ -1120,8 +1128,9 @@ proceed:
*/
print_header(file1, file2);
anychange = 1;
- } else if (a > context_vec_ptr->b + (2 * diff_context) + 1 &&
- c > context_vec_ptr->d + (2 * diff_context) + 1) {
+ } else if (!ckd_add(&dist, diff_context, diff_context) &&
+ a - context_vec_ptr->b - 1 > dist &&
+ c - context_vec_ptr->d - 1 > dist) {
/*
* If this change is more than 'diff_context' lines from the
* previous change, dump the record and reset it.
@@ -1506,10 +1515,14 @@ dump_context_vec(FILE *f1, FILE *f2, int flags)
return;
b = d = 0; /* gcc */
- lowa = MAX(1, cvp->a - diff_context);
- upb = MIN((int)len[0], context_vec_ptr->b + diff_context);
- lowc = MAX(1, cvp->c - diff_context);
- upd = MIN((int)len[1], context_vec_ptr->d + diff_context);
+ if (ckd_sub(&lowa, cvp->a, diff_context) || lowa < 1)
+ lowa = 1;
+ if (ckd_add(&upb, context_vec_ptr->b, diff_context) || upb > (int)len[0])
+ upb = (int)len[0];
+ if (ckd_sub(&lowc, cvp->c, diff_context) || lowc < 1)
+ lowc = 1;
+ if (ckd_add(&upd, context_vec_ptr->d, diff_context) || upd > (int)len[1])
+ upd = (int)len[1];
printf("***************");
if (flags & (D_PROTOTYPE | D_MATCHLAST)) {
@@ -1609,10 +1622,14 @@ dump_unified_vec(FILE *f1, FILE *f2, int flags)
return;
b = d = 0; /* gcc */
- lowa = MAX(1, cvp->a - diff_context);
- upb = MIN((int)len[0], context_vec_ptr->b + diff_context);
- lowc = MAX(1, cvp->c - diff_context);
- upd = MIN((int)len[1], context_vec_ptr->d + diff_context);
+ if (ckd_sub(&lowa, cvp->a, diff_context) || lowa < 1)
+ lowa = 1;
+ if (ckd_add(&upb, context_vec_ptr->b, diff_context) || upb > (int)len[0])
+ upb = (int)len[0];
+ if (ckd_sub(&lowc, cvp->c, diff_context) || lowc < 1)
+ lowc = 1;
+ if (ckd_add(&upd, context_vec_ptr->d, diff_context) || upd > (int)len[1])
+ upd = (int)len[1];
printf("@@ -");
uni_range(lowa, upb);
diff --git a/usr.bin/diff/diffreg_new.c b/usr.bin/diff/diffreg_new.c
index f54cd554ccad..69deae497962 100644
--- a/usr.bin/diff/diffreg_new.c
+++ b/usr.bin/diff/diffreg_new.c
@@ -33,6 +33,7 @@
#include <time.h>
#include <unistd.h>
+#include "pr.h"
#include "diff.h"
#include <arraylist.h>
#include <diff_main.h>
@@ -55,7 +56,7 @@ static const struct diff_algo_config myers_then_myers_divide;
static const struct diff_algo_config patience;
static const struct diff_algo_config myers_divide;
-static const struct diff_algo_config myers_then_patience = (struct diff_algo_config){
+static const struct diff_algo_config myers_then_patience = {
.impl = diff_algo_myers,
.permitted_state_size = 1024 * 1024 * sizeof(int),
.fallback_algo = &patience,
@@ -68,7 +69,7 @@ static const struct diff_algo_config myers_then_myers_divide =
.fallback_algo = &myers_divide,
};
-static const struct diff_algo_config patience = (struct diff_algo_config){
+static const struct diff_algo_config patience = {
.impl = diff_algo_patience,
/* After subdivision, do Patience again: */
.inner_algo = &patience,
@@ -76,14 +77,14 @@ static const struct diff_algo_config patience = (struct diff_algo_config){
.fallback_algo = &myers_then_myers_divide,
};
-static const struct diff_algo_config myers_divide = (struct diff_algo_config){
+static const struct diff_algo_config myers_divide = {
.impl = diff_algo_myers_divide,
/* When division succeeded, start from the top: */
.inner_algo = &myers_then_myers_divide,
/* (fallback_algo = NULL implies diff_algo_none). */
};
-static const struct diff_algo_config no_algo = (struct diff_algo_config){
+static const struct diff_algo_config none = {
.impl = diff_algo_none,
};
@@ -108,8 +109,9 @@ static const struct diff_config diff_config_patience = {
};
/* Directly force Patience as a first divider of the source file. */
-static const struct diff_config diff_config_no_algo = {
+static const struct diff_config diff_config_none = {
.atomize_func = diff_atomize_text_by_line,
+ .algo = &none,
};
const char *
@@ -146,6 +148,7 @@ diffreg_new(char *file1, char *file2, int flags, int capsicum)
{
char *str1, *str2;
FILE *f1, *f2;
+ struct pr *pr = NULL;
struct stat st1, st2;
struct diff_input_info info;
struct diff_data left = {}, right = {};
@@ -156,6 +159,7 @@ diffreg_new(char *file1, char *file2, int flags, int capsicum)
const struct diff_config *cfg;
enum diffreg_algo algo;
cap_rights_t rights_ro;
+ int ret;
algo = DIFFREG_ALGO_MYERS_THEN_MYERS_DIVIDE;
@@ -171,13 +175,16 @@ diffreg_new(char *file1, char *file2, int flags, int capsicum)
cfg = &diff_config_patience;
break;
case DIFFREG_ALGO_NONE:
- cfg = &diff_config_no_algo;
+ cfg = &diff_config_none;
break;
}
f1 = openfile(file1, &str1, &st1);
f2 = openfile(file2, &str2, &st2);
+ if (flags & D_PAGINATION)
+ pr = start_pr(file1, file2);
+
if (capsicum) {
cap_rights_init(&rights_ro, CAP_READ, CAP_FSTAT, CAP_SEEK);
if (caph_rights_limit(fileno(f1), &rights_ro) < 0)
@@ -214,18 +221,22 @@ diffreg_new(char *file1, char *file2, int flags, int capsicum)
if (flags & D_PROTOTYPE)
diff_flags |= DIFF_FLAG_SHOW_PROTOTYPES;
- if (diff_atomize_file(&left, cfg, f1, (uint8_t *)str1, st1.st_size, diff_flags)) {
+ ret = diff_atomize_file(&left, cfg, f1, (uint8_t *)str1, st1.st_size,
+ diff_flags);
+ if (ret != DIFF_RC_OK) {
+ warnc(ret, "%s", file1);
rc = D_ERROR;
+ status |= 2;
goto done;
}
- if (left.atomizer_flags & DIFF_ATOMIZER_FILE_TRUNCATED)
- warnx("%s truncated", file1);
- if (diff_atomize_file(&right, cfg, f2, (uint8_t *)str2, st2.st_size, diff_flags)) {
+ ret = diff_atomize_file(&right, cfg, f2, (uint8_t *)str2, st2.st_size,
+ diff_flags);
+ if (ret != DIFF_RC_OK) {
+ warnc(ret, "%s", file2);
rc = D_ERROR;
+ status |= 2;
goto done;
}
- if (right.atomizer_flags & DIFF_ATOMIZER_FILE_TRUNCATED)
- warnx("%s truncated", file2);
result = diff_main(cfg, &left, &right);
if (result->rc != DIFF_RC_OK) {
@@ -271,6 +282,8 @@ diffreg_new(char *file1, char *file2, int flags, int capsicum)
status |= 1;
}
done:
+ if (pr != NULL)
+ stop_pr(pr);
diff_result_free(result);
diff_data_free(&left);
diff_data_free(&right);
diff --git a/usr.bin/diff/pr.c b/usr.bin/diff/pr.c
index c3ea280073af..189e6b34649e 100644
--- a/usr.bin/diff/pr.c
+++ b/usr.bin/diff/pr.c
@@ -28,6 +28,7 @@
#include <sys/wait.h>
#include <err.h>
+#include <errno.h>
#include <paths.h>
#include <signal.h>
#include <stdio.h>
@@ -44,7 +45,6 @@ struct pr *
start_pr(char *file1, char *file2)
{
int pfd[2];
- int pr_pd;
pid_t pid;
char *header;
struct pr *pr;
@@ -54,13 +54,10 @@ start_pr(char *file1, char *file2)
xasprintf(&header, "%s %s %s", diffargs, file1, file2);
signal(SIGPIPE, SIG_IGN);
fflush(stdout);
- rewind(stdout);
if (pipe(pfd) == -1)
err(2, "pipe");
- switch ((pid = pdfork(&pr_pd, PD_CLOEXEC))) {
+ switch ((pid = pdfork(&pr->procd, PD_CLOEXEC))) {
case -1:
- status |= 2;
- free(header);
err(2, "No more processes");
case 0:
/* child */
@@ -72,24 +69,18 @@ start_pr(char *file1, char *file2)
execl(_PATH_PR, _PATH_PR, "-h", header, (char *)0);
_exit(127);
default:
-
/* parent */
- if (pfd[1] != STDOUT_FILENO) {
- pr->ostdout = dup(STDOUT_FILENO);
- dup2(pfd[1], STDOUT_FILENO);
+ if (pfd[1] == STDOUT_FILENO) {
+ pr->ostdout = STDOUT_FILENO;
+ } else {
+ if ((pr->ostdout = dup(STDOUT_FILENO)) < 0 ||
+ dup2(pfd[1], STDOUT_FILENO) < 0) {
+ err(2, "stdout");
+ }
close(pfd[1]);
}
close(pfd[0]);
- rewind(stdout);
free(header);
- pr->kq = kqueue();
- if (pr->kq == -1)
- err(2, "kqueue");
- pr->e = xmalloc(sizeof(struct kevent));
- EV_SET(pr->e, pr_pd, EVFILT_PROCDESC, EV_ADD, NOTE_EXIT, 0,
- NULL);
- if (kevent(pr->kq, pr->e, 1, NULL, 0, NULL) == -1)
- err(2, "kevent");
}
return (pr);
}
@@ -105,14 +96,14 @@ stop_pr(struct pr *pr)
fflush(stdout);
if (pr->ostdout != STDOUT_FILENO) {
- close(STDOUT_FILENO);
dup2(pr->ostdout, STDOUT_FILENO);
close(pr->ostdout);
}
- if (kevent(pr->kq, NULL, 0, pr->e, 1, NULL) == -1)
- err(2, "kevent");
- wstatus = pr->e[0].data;
- close(pr->kq);
+ while (pdwait(pr->procd, &wstatus, WEXITED, NULL, NULL) == -1) {
+ if (errno != EINTR)
+ err(2, "pdwait");
+ }
+ close(pr->procd);
free(pr);
if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != 0)
errx(2, "pr exited abnormally");
diff --git a/usr.bin/diff/pr.h b/usr.bin/diff/pr.h
index 2ff5949f282f..e6abad4466a6 100644
--- a/usr.bin/diff/pr.h
+++ b/usr.bin/diff/pr.h
@@ -24,12 +24,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/event.h>
-
struct pr {
int ostdout;
- int kq;
- struct kevent *e;
+ int procd;
};
struct pr *start_pr(char *file1, char *file2);
diff --git a/usr.bin/diff/tests/diff_test.sh b/usr.bin/diff/tests/diff_test.sh
index 691b649813a1..872103b24cef 100755
--- a/usr.bin/diff/tests/diff_test.sh
+++ b/usr.bin/diff/tests/diff_test.sh
@@ -1,4 +1,3 @@
-
atf_test_case simple
atf_test_case unified
atf_test_case header
@@ -24,6 +23,10 @@ atf_test_case functionname
atf_test_case noderef
atf_test_case ignorecase
atf_test_case dirloop
+atf_test_case crange
+atf_test_case urange
+atf_test_case prleak
+atf_test_case same
simple_body()
{
@@ -187,19 +190,19 @@ brief_format_body()
atf_check \
-s exit:1 \
-o inline:"Files A/test-file and B/test-file differ\n" \
- diff -rq A B
+ diff -q A B
atf_check diff -rq A C
atf_check \
-s exit:1 \
-o inline:"Only in D: another-test-file\n" \
- diff -rq A D
+ diff -q A D
atf_check \
-s exit:1 \
-o inline:"Files A/another-test-file and D/another-test-file differ\n" \
- diff -Nrq A D
+ diff -Nq A D
}
Bflag_body()
@@ -221,9 +224,9 @@ Nflag_body()
{
atf_check -x 'printf "foo" > A'
- atf_check -s exit:1 -o ignore -e ignore diff -N A NOFILE
- atf_check -s exit:1 -o ignore -e ignore diff -N NOFILE A
- atf_check -s exit:2 -o ignore -e ignore diff -N NOFILE1 NOFILE2
+ atf_check -s exit:1 -o ignore -e ignore diff -N A NOFILE
+ atf_check -s exit:1 -o ignore -e ignore diff -N NOFILE A
+ atf_check -s exit:2 -o ignore -e ignore diff -N NOFILE1 NOFILE2
}
tabsize_body()
@@ -335,23 +338,23 @@ noderef_body()
atf_check ln -s $(pwd)/test-file B/test-file
- atf_check -o empty -s exit:0 diff -r A B
+ atf_check -o empty -s exit:0 diff A B
atf_check -o inline:"File A/test-file is a file while file B/test-file is a symbolic link\n" \
- -s exit:1 diff -r --no-dereference A B
+ -s exit:1 diff --no-dereference A B
# both test files are now the same symbolic link
atf_check rm A/test-file
atf_check ln -s $(pwd)/test-file A/test-file
- atf_check -o empty -s exit:0 diff -r A B
- atf_check -o empty -s exit:0 diff -r --no-dereference A B
+ atf_check -o empty -s exit:0 diff A B
+ atf_check -o empty -s exit:0 diff --no-dereference A B
# make test files different symbolic links, but same contents
atf_check unlink A/test-file
atf_check ln -s $(pwd)/test-file2 A/test-file
- atf_check -o empty -s exit:0 diff -r A B
- atf_check -o inline:"Symbolic links A/test-file and B/test-file differ\n" -s exit:1 diff -r --no-dereference A B
+ atf_check -o empty -s exit:0 diff A B
+ atf_check -o inline:"Symbolic links A/test-file and B/test-file differ\n" -s exit:1 diff --no-dereference A B
}
ignorecase_body()
@@ -362,7 +365,7 @@ ignorecase_body()
atf_check -x "echo hello > A/foo"
atf_check -x "echo hello > B/FOO"
- atf_check -o empty -s exit:0 diff -u -r --ignore-file-name-case A B
+ atf_check -o empty -s exit:0 diff -u --ignore-file-name-case A B
}
dirloop_head()
@@ -375,9 +378,100 @@ dirloop_body()
atf_check ln -s .. a/foo/bar/up
atf_check cp -a a b
atf_check \
+ -o inline:"Common subdirectories: a/foo and b/foo\n" \
+ diff a b
+ atf_check \
-e match:"a/foo/bar/up: Directory loop detected" \
-e match:"b/foo/bar/up: Directory loop detected" \
diff -r a b
+ atf_check rm [ab]/foo/bar/up
+ atf_check mkdir -p b/foo/bar
+ atf_check ln -s foo a/baz
+ atf_check ln -s foo b/baz
+ atf_check diff -r a b
+}
+
+crange_head()
+{
+ atf_set "descr" "Context diff context length range"
+}
+crange_body()
+{
+ echo $'x\nx\na\ny\ny' >a
+ echo $'x\nx\nb\ny\ny' >b
+ atf_check -s exit:2 -e match:'too small' \
+ diff -C-1 a b
+ atf_check -s exit:2 -e match:'too small' \
+ diff -C0 a b
+ atf_check -s exit:1 -o match:'--- 2,4 ---' \
+ diff -C1 a b
+ atf_check -s exit:1 -o match:'--- 2,4 ---' \
+ diff -Astone -C1 a b
+ atf_check -s exit:2 -e match:'too large' \
+ diff -C$((1<<31)) a b
+ atf_check -s exit:1 -o match:'--- 1,5 ---' \
+ diff -C$(((1<<31)-1)) a b
+ atf_check -s exit:1 -o match:'--- 1,5 ---' \
+ diff -Astone -C$(((1<<31)-1)) a b
+}
+
+urange_head()
+{
+ atf_set "descr" "Unified diff context length range"
+}
+urange_body()
+{
+ echo $'x\nx\na\ny\ny' >a
+ echo $'x\nx\nb\ny\ny' >b
+ atf_check -s exit:2 -e match:'too small' \
+ diff -U-1 a b
+ atf_check -s exit:1 -o match:'^@@ -3 \+3 @@$' \
+ diff -U0 a b
+ atf_check -s exit:2 -e match:'too large' \
+ diff -U$((1<<31)) a b
+ atf_check -s exit:1 -o match:'^@@ -1,5 \+1,5 @@$' \
+ diff -U$(((1<<31)-1)) a b
+ atf_check -s exit:1 -o match:'^@@ -1,5 \+1,5 @@$' \
+ diff -Astone -U$(((1<<31)-1)) a b
+}
+
+prleak_head()
+{
+ atf_set "descr" "Verify that pagination does not leak resources"
+}
+prleak_body()
+{
+ local n=32
+ mkdir a b
+ for hi in $(jot -w%02x $n 0) ; do
+ mkdir a/$hi b/$hi
+ for lo in $(jot -w%02x $n 0) ; do
+ echo "$hi$lo" >a/$hi/$lo
+ echo "$hi$lo" >b/$hi/$lo
+ done
+ done
+ ulimit -n 1000
+ ulimit -u 1000
+ atf_check diff -rul a b
+ atf_check diff -Astone -rul a b
+}
+
+same_head()
+{
+ atf_set "descr" "Don't diff a file or directory with itself"
+}
+same_body()
+{
+ local n=256
+ mkdir a
+ for hi in $(jot -w%02x $n 0) ; do
+ mkdir a/$hi
+ for lo in $(jot -w%02x $n 0) ; do
+ echo "$hi$lo" >a/$hi/$lo
+ done
+ done
+ ln -s a b
+ atf_check timeout 1s diff -rqs a b
}
atf_init_test_cases()
@@ -407,4 +501,8 @@ atf_init_test_cases()
atf_add_test_case noderef
atf_add_test_case ignorecase
atf_add_test_case dirloop
+ atf_add_test_case crange
+ atf_add_test_case urange
+ atf_add_test_case prleak
+ atf_add_test_case same
}
diff --git a/usr.bin/diff3/diff3.1 b/usr.bin/diff3/diff3.1
index 9286a79e6ec6..8ca2d9f853af 100644
--- a/usr.bin/diff3/diff3.1
+++ b/usr.bin/diff3/diff3.1
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd June 23, 2022
+.Dd March 1, 2026
.Dt DIFF3 1
.Os
.Sh NAME
@@ -196,6 +196,21 @@ The lines beneath this notation are ranges of lines which are exclusively
different in file
.Va n .
.El
+.Sh EXIT STATUS
+The
+.Nm
+utility exits with a status of 0 on success
+and >1 if an error occurred.
+Additionally, if the
+.Fl A ,
+.Fl E ,
+.Fl L ,
+.Fl m ,
+or
+.Fl X
+flags were specified,
+it exits with a status of 1 if conflicts were found.
+.El
.Sh SEE ALSO
.Xr diff 1 ,
.Xr ed 1 ,
diff --git a/usr.bin/diff3/diff3.c b/usr.bin/diff3/diff3.c
index 39523f6e6b38..d85a5da94b10 100644
--- a/usr.bin/diff3/diff3.c
+++ b/usr.bin/diff3/diff3.c
@@ -1,6 +1,8 @@
/* $OpenBSD: diff3prog.c,v 1.11 2009/10/27 23:59:37 deraadt Exp $ */
/*
+ * SPDX-License-Identifier: Caldera-no-preamble AND BSD-3-Clause
+ *
* Copyright (C) Caldera International Inc. 2001-2002.
* All rights reserved.
*
@@ -62,20 +64,20 @@
* SUCH DAMAGE.
*/
+#include <sys/types.h>
#include <sys/capsicum.h>
#include <sys/procdesc.h>
-#include <sys/types.h>
-#include <sys/event.h>
#include <sys/wait.h>
+#include <assert.h>
#include <capsicum_helpers.h>
#include <ctype.h>
#include <err.h>
#include <getopt.h>
+#include <inttypes.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
-#include <limits.h>
-#include <inttypes.h>
#include <string.h>
#include <unistd.h>
@@ -88,14 +90,15 @@ struct range {
int to;
};
+enum difftype {
+ DIFF_NONE,
+ DIFF_TYPE1,
+ DIFF_TYPE2,
+ DIFF_TYPE3,
+};
+
struct diff {
-#define DIFF_TYPE1 1
-#define DIFF_TYPE2 2
-#define DIFF_TYPE3 3
- int type;
-#if DEBUG
- char *line;
-#endif /* DEBUG */
+ enum difftype type;
/* Ranges as lines */
struct range old;
@@ -119,6 +122,7 @@ static struct diff *d23;
*/
static struct diff *de;
static char *overlap;
+static int *de_delta; /* file1-file3 line number delta per edit */
static int overlapcnt;
static FILE *fp[3];
static int cline[3]; /* # of the last-read line in each file (0-2) */
@@ -137,7 +141,7 @@ static const char *newmark = ">>>>>>>";
static const char *divider = "=======";
static bool duplicate(struct range *, struct range *);
-static int edit(struct diff *, bool, int, int);
+static int edit(struct diff *, bool, int, enum difftype);
static char *getchange(FILE *);
static char *get_line(FILE *, size_t *);
static int readin(int fd, struct diff **);
@@ -150,12 +154,12 @@ static void repos(int);
static void separate(const char *);
static void edscript(int) __dead2;
static void Ascript(int) __dead2;
-static void mergescript(int) __dead2;
+static void mergescript(int, int) __dead2;
static void increase(void);
static void usage(void);
static void printrange(FILE *, struct range *);
-static const char diff3_version[] = "FreeBSD diff3 20240925";
+static const char diff3_version[] = "FreeBSD diff3 20260213";
enum {
DIFFPROG_OPT,
@@ -200,7 +204,7 @@ strtoi(char *str, char **end)
if ((end != NULL && *end == str) ||
num < 0 || num > INT_MAX ||
errno == EINVAL || errno == ERANGE)
- err(1, "error in diff output");
+ err(2, "error in diff output");
return (int)num;
}
@@ -256,9 +260,6 @@ readin(int fd, struct diff **dd)
for (i = 0; (p = getchange(f)) != NULL; i++) {
if ((size_t)i >= szchanges - 1)
increase();
-#if DEBUG
- (*dd)[i].line = strdup(p);
-#endif /* DEBUG */
a = b = strtoi(p, &p);
if (*p == ',')
@@ -268,7 +269,7 @@ readin(int fd, struct diff **dd)
if (*p == ',')
d = strtoi(p + 1, &p);
if (*p != '\n')
- errx(1, "error in diff output");
+ errx(2, "error in diff output");
if (kind == 'a')
a++;
else if (kind == 'c')
@@ -276,11 +277,11 @@ readin(int fd, struct diff **dd)
else if (kind == 'd')
c++;
else
- errx(1, "error in diff output");
+ errx(2, "error in diff output");
b++;
d++;
if (b < a || d < c)
- errx(1, "error in diff output");
+ errx(2, "error in diff output");
(*dd)[i].old.from = a;
(*dd)[i].old.to = b;
(*dd)[i].new.from = c;
@@ -288,7 +289,7 @@ readin(int fd, struct diff **dd)
if (i > 0) {
if ((*dd)[i].old.from < (*dd)[i - 1].old.to ||
(*dd)[i].new.from < (*dd)[i - 1].new.to)
- errx(1, "diff output out of order");
+ errx(2, "diff output out of order");
}
}
if (i > 0) {
@@ -361,11 +362,13 @@ merge(int m1, int m2)
{
struct diff *d1, *d2, *d3;
int j, t1, t2;
+ int f1f3delta;
bool dup = false;
d1 = d13;
d2 = d23;
j = 0;
+ f1f3delta = 0;
for (;;) {
t1 = (d1 < d13 + m1);
@@ -381,9 +384,17 @@ merge(int m1, int m2)
change(1, &d1->old, false);
keep(2, &d1->new);
change(3, &d1->new, false);
+ } else if (mflag) {
+ j++;
+ de[j].type = DIFF_TYPE1;
+ de[j].old = d1->old;
+ de[j].new = d1->new;
+ overlap[j] = 0;
} else if (eflag == EFLAG_OVERLAP) {
j = edit(d2, dup, j, DIFF_TYPE1);
}
+ f1f3delta += (d1->old.to - d1->old.from) -
+ (d1->new.to - d1->new.from);
d1++;
continue;
}
@@ -395,9 +406,10 @@ merge(int m1, int m2)
change(3, &d2->new, false);
change(2, &d2->old, false);
} else if (Aflag || mflag) {
- // XXX-THJ: What does it mean for the second file to differ?
- if (eflag == EFLAG_UNMERGED)
+ if (eflag == EFLAG_UNMERGED) {
j = edit(d2, dup, j, DIFF_TYPE2);
+ de_delta[j] = f1f3delta;
+ }
}
d2++;
continue;
@@ -433,10 +445,20 @@ merge(int m1, int m2)
change(2, &d2->old, false);
d3 = d1->old.to > d1->old.from ? d1 : d2;
change(3, &d3->new, false);
+ } else if (mflag) {
+ j++;
+ de[j].type = DIFF_TYPE3;
+ de[j].old = d1->old;
+ de[j].new = d1->new;
+ overlap[j] = !dup;
+ if (!dup)
+ overlapcnt++;
} else {
j = edit(d1, dup, j, DIFF_TYPE3);
}
dup = false;
+ f1f3delta += (d1->old.to - d1->old.from) -
+ (d1->new.to - d1->new.from);
d1++;
d2++;
continue;
@@ -462,7 +484,7 @@ merge(int m1, int m2)
}
if (mflag)
- mergescript(j);
+ mergescript(j, f1f3delta);
else if (Aflag)
Ascript(j);
else if (eflag)
@@ -544,7 +566,7 @@ skip(int i, int from, const char *pr)
for (n = 0; cline[i] < from - 1; n += j) {
if ((line = get_line(fp[i], &j)) == NULL)
- errx(EXIT_FAILURE, "logic error");
+ errx(2, "logic error");
if (pr != NULL)
printf("%s%s", Tflag == 1 ? "\t" : pr, line);
cline[i]++;
@@ -575,7 +597,7 @@ duplicate(struct range *r1, struct range *r2)
if (c == -1 && d == -1)
break;
if (c == -1 || d == -1)
- errx(EXIT_FAILURE, "logic error");
+ errx(2, "logic error");
nchar++;
if (c != d) {
repos(nchar);
@@ -600,7 +622,7 @@ repos(int nchar)
* collect an editing script for later regurgitation
*/
static int
-edit(struct diff *diff, bool dup, int j, int difftype)
+edit(struct diff *diff, bool dup, int j, enum difftype difftype)
{
if (!(eflag == EFLAG_UNMERGED ||
(!dup && eflag == EFLAG_OVERLAP ) ||
@@ -613,10 +635,6 @@ edit(struct diff *diff, bool dup, int j, int difftype)
overlapcnt++;
de[j].type = difftype;
-#if DEBUG
- de[j].line = strdup(diff->line);
-#endif /* DEBUG */
-
de[j].old.from = diff->old.from;
de[j].old.to = diff->old.to;
de[j].new.from = diff->new.from;
@@ -636,7 +654,7 @@ printrange(FILE *p, struct range *r)
return;
if (r->from > r->to)
- errx(EXIT_FAILURE, "invalid print range");
+ errx(2, "invalid print range");
/*
* XXX-THJ: We read through all of the file for each range printed.
@@ -695,7 +713,7 @@ edscript(int n)
if (iflag)
printf("w\nq\n");
- exit(eflag == EFLAG_NONE ? overlapcnt : 0);
+ exit(oflag ? overlapcnt > 0 : 0);
}
/*
@@ -724,7 +742,7 @@ Ascript(int n)
prange(old, deletenew);
printrange(fp[2], new);
} else {
- startmark = new->to - 1;
+ startmark = new->to - 1 + de_delta[n];
printf("%da\n", startmark);
printf("%s %s\n", newmark, f3mark);
@@ -789,11 +807,10 @@ Ascript(int n)
* inbetween lines.
*/
static void
-mergescript(int i)
+mergescript(int i, int f1f3delta)
{
struct range r, *new, *old;
int n;
- bool delete = false;
r.from = 1;
r.to = 1;
@@ -806,21 +823,17 @@ mergescript(int i)
* Print any lines leading up to here. If we are merging don't
* print deleted ranges.
*/
- delete = (new->from == new->to);
- if (de[n].type == DIFF_TYPE1 && delete)
- r.to = new->from - 1;
- else if (de[n].type == DIFF_TYPE3 && (old->from == old->to)) {
- r.from = old->from - 1;
- r.to = new->from;
- } else
+ if (de[n].type == DIFF_TYPE1)
+ r.to = old->to;
+ else if (de[n].type == DIFF_TYPE2)
+ r.to = new->from + de_delta[n];
+ else
r.to = old->from;
printrange(fp[0], &r);
switch (de[n].type) {
case DIFF_TYPE1:
- /* If this isn't a delete print it */
- if (!delete)
- printrange(fp[2], new);
+ /* Content included in "between" printing from fp[0] */
break;
case DIFF_TYPE2:
printf("%s %s\n", oldmark, f2mark);
@@ -856,12 +869,11 @@ mergescript(int i)
}
break;
default:
- printf("Error: Unhandled diff type - exiting\n");
- exit(EXIT_FAILURE);
+ __assert_unreachable();
}
- if (old->from == old->to)
- r.from = new->to;
+ if (de[n].type == DIFF_TYPE2)
+ r.from = new->to + de_delta[n];
else
r.from = old->to;
}
@@ -869,19 +881,8 @@ mergescript(int i)
/*
* Print from the final range to the end of 'myfile'. Any deletions or
* additions to this file should have been handled by now.
- *
- * If the ranges are the same we need to rewind a line.
- * If the new range is 0 length (from == to), we need to use the old
- * range.
*/
- new = &de[n-1].new;
- old = &de[n-1].old;
-
- if (old->from == new->from && old->to == new->to)
- r.from--;
- else if (new->from == new->to)
- r.from = old->from;
-
+ r.from -= f1f3delta;
r.to = INT_MAX;
printrange(fp[2], &r);
exit(overlapcnt > 0);
@@ -892,6 +893,7 @@ increase(void)
{
struct diff *p;
char *q;
+ int *s;
size_t newsz, incr;
/* are the memset(3) calls needed? */
@@ -900,32 +902,52 @@ increase(void)
p = reallocarray(d13, newsz, sizeof(*p));
if (p == NULL)
- err(1, NULL);
+ err(2, NULL);
memset(p + szchanges, 0, incr * sizeof(*p));
d13 = p;
p = reallocarray(d23, newsz, sizeof(*p));
if (p == NULL)
- err(1, NULL);
+ err(2, NULL);
memset(p + szchanges, 0, incr * sizeof(*p));
d23 = p;
p = reallocarray(de, newsz, sizeof(*p));
if (p == NULL)
- err(1, NULL);
+ err(2, NULL);
memset(p + szchanges, 0, incr * sizeof(*p));
de = p;
q = reallocarray(overlap, newsz, 1);
if (q == NULL)
- err(1, NULL);
+ err(2, NULL);
memset(q + szchanges, 0, incr * 1);
overlap = q;
+ s = reallocarray(de_delta, newsz, sizeof(*s));
+ if (s == NULL)
+ err(2, NULL);
+ memset(s + szchanges, 0, incr * sizeof(*s));
+ de_delta = s;
szchanges = newsz;
}
+static void
+wait_and_check(int pd)
+{
+ int status;
+
+ while (pdwait(pd, &status, WEXITED, NULL, NULL) == -1) {
+ if (errno != EINTR)
+ err(2, "pdwait");
+ }
+
+ if (WIFEXITED(status) && WEXITSTATUS(status) >= 2)
+ errx(2, "diff exited abnormally");
+ if (WIFSIGNALED(status))
+ errx(2, "diff killed by signal %d", WTERMSIG(status));
+}
int
main(int argc, char **argv)
{
- int ch, nblabels, status, m, n, kq, nke, nleft, i;
+ int ch, nblabels, m, n;
char *labels[] = { NULL, NULL, NULL };
const char *diffprog = DIFF_PATH;
char *file1, *file2, *file3;
@@ -934,7 +956,6 @@ main(int argc, char **argv)
int fd13[2], fd23[2];
int pd13, pd23;
cap_rights_t rights_ro;
- struct kevent *e;
nblabels = 0;
eflag = EFLAG_NONE;
@@ -1016,14 +1037,6 @@ main(int argc, char **argv)
cap_rights_init(&rights_ro, CAP_READ, CAP_FSTAT, CAP_SEEK);
- kq = kqueue();
- if (kq == -1)
- err(2, "kqueue");
-
- e = malloc(2 * sizeof(*e));
- if (e == NULL)
- err(2, "malloc");
-
/* TODO stdio */
file1 = argv[0];
file2 = argv[1];
@@ -1069,20 +1082,10 @@ main(int argc, char **argv)
diffargv[diffargc] = file1;
diffargv[diffargc + 1] = file3;
diffargv[diffargc + 2] = NULL;
-
- nleft = 0;
pd13 = diffexec(diffprog, diffargv, fd13);
- EV_SET(e + nleft , pd13, EVFILT_PROCDESC, EV_ADD, NOTE_EXIT, 0, NULL);
- if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1)
- err(2, "kevent1");
- nleft++;
diffargv[diffargc] = file2;
pd23 = diffexec(diffprog, diffargv, fd23);
- EV_SET(e + nleft , pd23, EVFILT_PROCDESC, EV_ADD, NOTE_EXIT, 0, NULL);
- if (kevent(kq, e + nleft, 1, NULL, 0, NULL) == -1)
- err(2, "kevent2");
- nleft++;
caph_cache_catpages();
if (caph_enter() < 0)
@@ -1093,23 +1096,10 @@ main(int argc, char **argv)
m = readin(fd13[0], &d13);
n = readin(fd23[0], &d23);
- /* waitpid cooked over pdforks */
- while (nleft > 0) {
- nke = kevent(kq, NULL, 0, e, nleft, NULL);
- if (nke == -1)
- err(2, "kevent");
- for (i = 0; i < nke; i++) {
- status = e[i].data;
- if (WIFEXITED(status) && WEXITSTATUS(status) >= 2)
- errx(2, "diff exited abnormally");
- else if (WIFSIGNALED(status))
- errx(2, "diff killed by signal %d",
- WTERMSIG(status));
- }
- nleft -= nke;
- }
- free(e);
+ wait_and_check(pd13);
+ wait_and_check(pd23);
+
merge(m, n);
- return (EXIT_SUCCESS);
+ exit(0);
}
diff --git a/usr.bin/diff3/tests/Makefile b/usr.bin/diff3/tests/Makefile
index 864f27beede8..e35ab095f2f7 100644
--- a/usr.bin/diff3/tests/Makefile
+++ b/usr.bin/diff3/tests/Makefile
@@ -23,6 +23,20 @@ ${PACKAGE}FILES+= \
long-A.out \
long-merge.out \
fbsdid1.txt \
- fbsdid2.txt
+ fbsdid2.txt \
+ conflict1.txt \
+ conflict2.txt \
+ conflict3.txt \
+ conflict-merge.out \
+ simple1.txt \
+ simple2.txt \
+ simple3.txt \
+ simple-merge.out \
+ simple-Em.out \
+ conflict-Em.out \
+ passwd-test.txt \
+ passwd-old.txt \
+ passwd-new.txt \
+ passwd-Em.out
.include <bsd.test.mk>
diff --git a/usr.bin/diff3/tests/conflict-Em.out b/usr.bin/diff3/tests/conflict-Em.out
new file mode 100644
index 000000000000..dcc1ddaff6fb
--- /dev/null
+++ b/usr.bin/diff3/tests/conflict-Em.out
@@ -0,0 +1,19 @@
+<<<<<<< conflict3.txt
+root:someone@example.com
+=======
+#root:me@my.domain
+>>>>>>> conflict2.txt
+
+<<<<<<< conflict3.txt
+#Basicsystemaliases--theseMUSTbepresent
+MAILER-DAEMON:postmaster
+postmaster:root
+=======
+#Basicsystemaliases--theseMUSTbepresent
+MAILER-DAEMON:postmaster
+postmaster:root
+
+#Generalredirectionsforpseudoaccounts
+_dhcp:root
+_pflogd:root
+>>>>>>> conflict2.txt
diff --git a/usr.bin/diff3/tests/conflict-merge.out b/usr.bin/diff3/tests/conflict-merge.out
new file mode 100644
index 000000000000..737cba7dc224
--- /dev/null
+++ b/usr.bin/diff3/tests/conflict-merge.out
@@ -0,0 +1,25 @@
+<<<<<<< conflict3.txt
+root:someone@example.com
+||||||| conflict1.txt
+# root: me@my.domain
+=======
+#root:me@my.domain
+>>>>>>> conflict2.txt
+
+<<<<<<< conflict3.txt
+#Basicsystemaliases--theseMUSTbepresent
+MAILER-DAEMON:postmaster
+postmaster:root
+||||||| conflict1.txt
+# Basic system aliases -- these MUST be present
+MAILER-DAEMON: postmaster
+postmaster: root
+=======
+#Basicsystemaliases--theseMUSTbepresent
+MAILER-DAEMON:postmaster
+postmaster:root
+
+#Generalredirectionsforpseudoaccounts
+_dhcp:root
+_pflogd:root
+>>>>>>> conflict2.txt
diff --git a/usr.bin/diff3/tests/conflict1.txt b/usr.bin/diff3/tests/conflict1.txt
new file mode 100644
index 000000000000..d5bde7598f68
--- /dev/null
+++ b/usr.bin/diff3/tests/conflict1.txt
@@ -0,0 +1,5 @@
+# root: me@my.domain
+
+# Basic system aliases -- these MUST be present
+MAILER-DAEMON: postmaster
+postmaster: root
diff --git a/usr.bin/diff3/tests/conflict2.txt b/usr.bin/diff3/tests/conflict2.txt
new file mode 100644
index 000000000000..9afb26959e35
--- /dev/null
+++ b/usr.bin/diff3/tests/conflict2.txt
@@ -0,0 +1,9 @@
+#root:me@my.domain
+
+#Basicsystemaliases--theseMUSTbepresent
+MAILER-DAEMON:postmaster
+postmaster:root
+
+#Generalredirectionsforpseudoaccounts
+_dhcp:root
+_pflogd:root
diff --git a/usr.bin/diff3/tests/conflict3.txt b/usr.bin/diff3/tests/conflict3.txt
new file mode 100644
index 000000000000..14ac33b41853
--- /dev/null
+++ b/usr.bin/diff3/tests/conflict3.txt
@@ -0,0 +1,5 @@
+root:someone@example.com
+
+#Basicsystemaliases--theseMUSTbepresent
+MAILER-DAEMON:postmaster
+postmaster:root
diff --git a/usr.bin/diff3/tests/diff3_test.sh b/usr.bin/diff3/tests/diff3_test.sh
index 3cbd7dac1ed9..4510653bcd47 100755
--- a/usr.bin/diff3/tests/diff3_test.sh
+++ b/usr.bin/diff3/tests/diff3_test.sh
@@ -5,6 +5,11 @@ atf_test_case diff3_ed
atf_test_case diff3_A
atf_test_case diff3_merge
atf_test_case diff3_E_merge
+atf_test_case diff3_merge_conflict
+atf_test_case diff3_merge_simple
+atf_test_case diff3_Em_simple
+atf_test_case diff3_Em_conflict
+atf_test_case diff3_Em_insert
diff3_body()
{
@@ -20,10 +25,10 @@ diff3_body()
atf_check -o file:$(atf_get_srcdir)/2.out \
diff3 -e $(atf_get_srcdir)/1.txt $(atf_get_srcdir)/2.txt $(atf_get_srcdir)/3.txt
- atf_check -o file:$(atf_get_srcdir)/3.out \
+ atf_check -s exit:1 -o file:$(atf_get_srcdir)/3.out \
diff3 -E -L 1 -L 2 -L 3 $(atf_get_srcdir)/1.txt $(atf_get_srcdir)/2.txt $(atf_get_srcdir)/3.txt
- atf_check -o file:$(atf_get_srcdir)/4.out \
+ atf_check -s exit:1 -o file:$(atf_get_srcdir)/4.out \
diff3 -X -L 1 -L 2 -L 3 $(atf_get_srcdir)/1.txt $(atf_get_srcdir)/2.txt $(atf_get_srcdir)/3.txt
atf_check -o file:$(atf_get_srcdir)/5.out \
@@ -75,7 +80,6 @@ expected="<<<<<<< 2
=======
# \$FreeBSD: head/local 12345 jhb \$
>>>>>>> 3
-# \$FreeBSD: head/local 12345 jhb \$
this is a file
@@ -97,6 +101,36 @@ these are some local mods to the file
}
+diff3_merge_conflict_body()
+{
+ atf_check -s exit:1 -o file:$(atf_get_srcdir)/conflict-merge.out \
+ diff3 -m -L conflict3.txt -L conflict1.txt -L conflict2.txt $(atf_get_srcdir)/conflict3.txt $(atf_get_srcdir)/conflict1.txt $(atf_get_srcdir)/conflict2.txt
+}
+
+diff3_merge_simple_body()
+{
+ atf_check -s exit:0 -o file:$(atf_get_srcdir)/simple-merge.out \
+ diff3 -m $(atf_get_srcdir)/simple3.txt $(atf_get_srcdir)/simple1.txt $(atf_get_srcdir)/simple2.txt
+}
+
+diff3_Em_simple_body()
+{
+ atf_check -s exit:0 -o file:$(atf_get_srcdir)/simple-Em.out \
+ diff3 -E -m $(atf_get_srcdir)/simple3.txt $(atf_get_srcdir)/simple1.txt $(atf_get_srcdir)/simple2.txt
+}
+
+diff3_Em_conflict_body()
+{
+ atf_check -s exit:1 -o file:$(atf_get_srcdir)/conflict-Em.out \
+ diff3 -E -m -L conflict3.txt -L conflict1.txt -L conflict2.txt $(atf_get_srcdir)/conflict3.txt $(atf_get_srcdir)/conflict1.txt $(atf_get_srcdir)/conflict2.txt
+}
+
+diff3_Em_insert_body()
+{
+ atf_check -s exit:0 -o file:$(atf_get_srcdir)/passwd-Em.out \
+ diff3 -E -m $(atf_get_srcdir)/passwd-test.txt $(atf_get_srcdir)/passwd-old.txt $(atf_get_srcdir)/passwd-new.txt
+}
+
atf_init_test_cases()
{
atf_add_test_case diff3
@@ -105,4 +139,9 @@ atf_init_test_cases()
atf_add_test_case diff3_A
atf_add_test_case diff3_merge
atf_add_test_case diff3_E_merge
+ atf_add_test_case diff3_merge_conflict
+ atf_add_test_case diff3_merge_simple
+ atf_add_test_case diff3_Em_simple
+ atf_add_test_case diff3_Em_conflict
+ atf_add_test_case diff3_Em_insert
}
diff --git a/usr.bin/diff3/tests/passwd-Em.out b/usr.bin/diff3/tests/passwd-Em.out
new file mode 100644
index 000000000000..2b52a6440f6b
--- /dev/null
+++ b/usr.bin/diff3/tests/passwd-Em.out
@@ -0,0 +1,16 @@
+#
+root:<rpass>:0:0::0:0:Charlie &:/root:/bin/csh
+toor:*:0:0::0:0:Bourne-again Superuser:/root:
+daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
+operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
+_dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin
+uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
+pop:*:68:6::0:0:Post Office Owner:/nonexistent:/usr/sbin/nologin
+auditdistd:*:78:77::0:0:Auditdistd unprivileged user:/var/empty:/usr/sbin/nologin
+www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
+hast:*:845:845::0:0:HAST unprivileged user:/var/empty:/usr/sbin/nologin
+nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
+john:<password>:1001:1001::0:0:John Baldwin:/home/john:/bin/tcsh
+messagebus:*:556:556::0:0:D-BUS Daemon User:/nonexistent:/usr/sbin/nologin
+polkit:*:562:562::0:0:PolicyKit User:/nonexistent:/usr/sbin/nologin
+haldaemon:*:560:560::0:0:HAL Daemon User:/nonexistent:/usr/sbin/nologin
diff --git a/usr.bin/diff3/tests/passwd-new.txt b/usr.bin/diff3/tests/passwd-new.txt
new file mode 100644
index 000000000000..8bec617219a3
--- /dev/null
+++ b/usr.bin/diff3/tests/passwd-new.txt
@@ -0,0 +1,12 @@
+#
+root::0:0::0:0:Charlie &:/root:/bin/csh
+toor:*:0:0::0:0:Bourne-again Superuser:/root:
+daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
+operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
+_dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin
+uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
+pop:*:68:6::0:0:Post Office Owner:/nonexistent:/usr/sbin/nologin
+auditdistd:*:78:77::0:0:Auditdistd unprivileged user:/var/empty:/usr/sbin/nologin
+www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
+hast:*:845:845::0:0:HAST unprivileged user:/var/empty:/usr/sbin/nologin
+nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
diff --git a/usr.bin/diff3/tests/passwd-old.txt b/usr.bin/diff3/tests/passwd-old.txt
new file mode 100644
index 000000000000..7a6f936e90c9
--- /dev/null
+++ b/usr.bin/diff3/tests/passwd-old.txt
@@ -0,0 +1,11 @@
+#
+root::0:0::0:0:Charlie &:/root:/bin/csh
+toor:*:0:0::0:0:Bourne-again Superuser:/root:
+daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
+operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
+_dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin
+uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
+pop:*:68:6::0:0:Post Office Owner:/nonexistent:/usr/sbin/nologin
+www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
+hast:*:845:845::0:0:HAST unprivileged user:/var/empty:/usr/sbin/nologin
+nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
diff --git a/usr.bin/diff3/tests/passwd-test.txt b/usr.bin/diff3/tests/passwd-test.txt
new file mode 100644
index 000000000000..f2b277fb3b4c
--- /dev/null
+++ b/usr.bin/diff3/tests/passwd-test.txt
@@ -0,0 +1,15 @@
+#
+root:<rpass>:0:0::0:0:Charlie &:/root:/bin/csh
+toor:*:0:0::0:0:Bourne-again Superuser:/root:
+daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
+operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
+_dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin
+uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
+pop:*:68:6::0:0:Post Office Owner:/nonexistent:/usr/sbin/nologin
+www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
+hast:*:845:845::0:0:HAST unprivileged user:/var/empty:/usr/sbin/nologin
+nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
+john:<password>:1001:1001::0:0:John Baldwin:/home/john:/bin/tcsh
+messagebus:*:556:556::0:0:D-BUS Daemon User:/nonexistent:/usr/sbin/nologin
+polkit:*:562:562::0:0:PolicyKit User:/nonexistent:/usr/sbin/nologin
+haldaemon:*:560:560::0:0:HAL Daemon User:/nonexistent:/usr/sbin/nologin
diff --git a/usr.bin/diff3/tests/simple-Em.out b/usr.bin/diff3/tests/simple-Em.out
new file mode 100644
index 000000000000..c9ad1c1bed8f
--- /dev/null
+++ b/usr.bin/diff3/tests/simple-Em.out
@@ -0,0 +1,3 @@
+this is an new line
+
+this is a local line
diff --git a/usr.bin/diff3/tests/simple-merge.out b/usr.bin/diff3/tests/simple-merge.out
new file mode 100644
index 000000000000..c9ad1c1bed8f
--- /dev/null
+++ b/usr.bin/diff3/tests/simple-merge.out
@@ -0,0 +1,3 @@
+this is an new line
+
+this is a local line
diff --git a/usr.bin/diff3/tests/simple1.txt b/usr.bin/diff3/tests/simple1.txt
new file mode 100644
index 000000000000..4c4c2cd1a4e7
--- /dev/null
+++ b/usr.bin/diff3/tests/simple1.txt
@@ -0,0 +1,2 @@
+this is an old line
+
diff --git a/usr.bin/diff3/tests/simple2.txt b/usr.bin/diff3/tests/simple2.txt
new file mode 100644
index 000000000000..e880a8af5c39
--- /dev/null
+++ b/usr.bin/diff3/tests/simple2.txt
@@ -0,0 +1,2 @@
+this is an new line
+
diff --git a/usr.bin/diff3/tests/simple3.txt b/usr.bin/diff3/tests/simple3.txt
new file mode 100644
index 000000000000..4ab38534cba1
--- /dev/null
+++ b/usr.bin/diff3/tests/simple3.txt
@@ -0,0 +1,3 @@
+this is an old line
+
+this is a local line
diff --git a/usr.bin/etdump/etdump.c b/usr.bin/etdump/etdump.c
index 6c4a256e15f5..dce2d70bf0ec 100644
--- a/usr.bin/etdump/etdump.c
+++ b/usr.bin/etdump/etdump.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2018 iXsystems, Inc.
* All rights reserved.
*
diff --git a/usr.bin/etdump/etdump.h b/usr.bin/etdump/etdump.h
index c61070d05018..8e4acc13dd77 100644
--- a/usr.bin/etdump/etdump.h
+++ b/usr.bin/etdump/etdump.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2018 iXsystems, Inc.
* All rights reserved.
*
diff --git a/usr.bin/etdump/output_shell.c b/usr.bin/etdump/output_shell.c
index d709684c02dc..1d5ec4af998b 100644
--- a/usr.bin/etdump/output_shell.c
+++ b/usr.bin/etdump/output_shell.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2018 iXsystems, Inc.
* All rights reserved.
*
diff --git a/usr.bin/etdump/output_text.c b/usr.bin/etdump/output_text.c
index aafc6d702a54..b538a2097a31 100644
--- a/usr.bin/etdump/output_text.c
+++ b/usr.bin/etdump/output_text.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2018 iXsystems, Inc.
* All rights reserved.
*
diff --git a/usr.bin/from/from.c b/usr.bin/from/from.c
index 031803ebae16..63eb69daf36a 100644
--- a/usr.bin/from/from.c
+++ b/usr.bin/from/from.c
@@ -30,6 +30,8 @@
*/
#include <sys/types.h>
+
+#include <capsicum_helpers.h>
#include <ctype.h>
#include <err.h>
#include <pwd.h>
@@ -97,9 +99,12 @@ main(int argc, char **argv)
/* read from stdin */
if (strcmp(file, "-") == 0) {
mbox = stdin;
- }
+ }
else if ((mbox = fopen(file, "r")) == NULL) {
- errx(1, "can't read %s", file);
+ errx(EXIT_FAILURE, "can't read %s", file);
+ }
+ if (caph_limit_stdio() < 0 || caph_enter() < 0) {
+ err(EXIT_FAILURE, "capsicum");
}
for (newline = 1; fgets(buf, sizeof(buf), mbox);) {
if (*buf == '\n') {
@@ -117,16 +122,16 @@ main(int argc, char **argv)
}
if (count != -1)
printf("There %s %d message%s in your incoming mailbox.\n",
- count == 1 ? "is" : "are", count, count == 1 ? "" : "s");
+ count == 1 ? "is" : "are", count, count == 1 ? "" : "s");
fclose(mbox);
- exit(0);
+ exit(EXIT_SUCCESS);
}
static void
usage(void)
{
fprintf(stderr, "usage: from [-c] [-f file] [-s sender] [user]\n");
- exit(1);
+ exit(EXIT_FAILURE);
}
static int
@@ -137,14 +142,14 @@ match(const char *line, const char *sender)
for (first = *sender++;;) {
if (isspace(ch = *line))
- return(0);
+ return (0);
++line;
ch = tolower(ch);
if (ch != first)
continue;
for (p = sender, t = line;;) {
if (!(pch = *p++))
- return(1);
+ return (1);
ch = tolower(*t);
t++;
if (ch != pch)
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index 17ed43b55c5a..d3f2ac882e61 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -2404,11 +2404,7 @@ ktrstructarray(struct ktr_struct_array *ksa, size_t buflen)
kev.filter = kev32.filter;
kev.flags = kev32.flags;
kev.fflags = kev32.fflags;
-#if BYTE_ORDER == BIG_ENDIAN
- kev.data = kev32.data2 | ((int64_t)kev32.data1 << 32);
-#else
- kev.data = kev32.data1 | ((int64_t)kev32.data2 << 32);
-#endif
+ memcpy(&kev.data, &kev32.data, sizeof(kev.data));
kev.udata = (void *)(uintptr_t)kev32.udata;
ktrkevent(&kev);
} else if (strcmp(name, "freebsd11_kevent32") == 0) {
diff --git a/usr.bin/kyua/Makefile b/usr.bin/kyua/Makefile
index d6131651afbf..aa0e5cbbcad2 100644
--- a/usr.bin/kyua/Makefile
+++ b/usr.bin/kyua/Makefile
@@ -49,6 +49,8 @@ CFLAGS+= -DGDB=\"/usr/local/bin/gdb\" \
-DPACKAGE_VERSION=\"${KYUA_VERSION}\" \
-DVERSION=\"${KYUA_VERSION}\"
+CXXWARNFLAGS.gcc+= -Wno-free-nonheap-object
+
SRCS+= utils/datetime.cpp \
utils/env.cpp \
utils/memory.cpp \
diff --git a/usr.bin/less/defines.h b/usr.bin/less/defines.h
index d95ff956bd37..a051790d0f49 100644
--- a/usr.bin/less/defines.h
+++ b/usr.bin/less/defines.h
@@ -21,91 +21,91 @@
* be safe to run by unprivileged users.
* SECURE_COMPILE is set by the --with-secure configure option.
*/
-#define SECURE SECURE_COMPILE
+#define SECURE SECURE_COMPILE
/*
* SHELL_ESCAPE is 1 if you wish to allow shell escapes.
* (This is possible only if your system supplies the system() function.)
*/
-#define SHELL_ESCAPE (!SECURE)
+#define SHELL_ESCAPE (!SECURE)
/*
* EXAMINE is 1 if you wish to allow examining files by name from within less.
*/
-#define EXAMINE (!SECURE)
+#define EXAMINE (!SECURE)
/*
* TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key
* to complete filenames at prompts.
*/
-#define TAB_COMPLETE_FILENAME (!SECURE)
+#define TAB_COMPLETE_FILENAME (!SECURE)
/*
* CMD_HISTORY is 1 if you wish to allow keys to cycle through
* previous commands at prompts.
*/
-#define CMD_HISTORY 1
+#define CMD_HISTORY 1
/*
* HILITE_SEARCH is 1 if you wish to have search targets to be
* displayed in standout mode.
*/
-#define HILITE_SEARCH 1
+#define HILITE_SEARCH 1
/*
* EDITOR is 1 if you wish to allow editor invocation (the "v" command).
* (This is possible only if your system supplies the system() function.)
* EDIT_PGM is the name of the (default) editor to be invoked.
*/
-#define EDITOR (!SECURE)
+#define EDITOR (!SECURE)
/*
* TAGS is 1 if you wish to support tag files.
*/
-#define TAGS (!SECURE)
+#define TAGS (!SECURE)
/*
- * USERFILE is 1 if you wish to allow a .less file to specify
+ * USERFILE is 1 if you wish to allow a .lesskey or .less file to specify
* user-defined key bindings.
*/
-#define USERFILE (!SECURE)
+#define USERFILE (!SECURE)
/*
* GLOB is 1 if you wish to have shell metacharacters expanded in filenames.
* This will generally work if your system provides the "popen" function
* and the "echo" shell command.
*/
-#define GLOB (!SECURE)
+#define GLOB (!SECURE)
/*
* PIPEC is 1 if you wish to have the "|" command
* which allows the user to pipe data into a shell command.
*/
-#define PIPEC (!SECURE && HAVE_POPEN)
+#define PIPEC (!SECURE && HAVE_POPEN)
/*
* LOGFILE is 1 if you wish to allow the -o option (to create log files).
*/
-#define LOGFILE (!SECURE)
+#define LOGFILE (!SECURE)
/*
- * OSC8_SEARCH is 1 if you wish to allow the ^O^O and related commands
+ * OSC8_LINK is 1 if you wish to allow the ^O^O and related commands
* (to open OSC8 hyperlinks).
*/
-#define OSC8_LINK 1
+#define OSC8_LINK 1
/*
* GNU_OPTIONS is 1 if you wish to support the GNU-style command
* line options --help and --version.
*/
-#define GNU_OPTIONS 1
+#define GNU_OPTIONS 1
/*
* ONLY_RETURN is 1 if you want RETURN to be the only input which
* will continue past an error message.
* Otherwise, any key will continue past an error message.
*/
-#define ONLY_RETURN 0
+#define ONLY_RETURN 0
/*
* LESSKEYFILE is the filename of the default lesskey output file
@@ -116,33 +116,36 @@
* LESSHISTFILE is the filename of the history file
* (in the HOME directory).
*/
-#define LESSKEYFILE ".less"
-#define LESSKEYFILE_SYS "/etc/lesskey"
-#define DEF_LESSKEYINFILE ".lesskey"
-#define LESSKEYINFILE_SYS "/etc/syslesskey"
-#define LESSHISTFILE ".lesshst"
+/* FreeBSD */
+#define SYSDIR "/etc"
+
+#define LESSKEYFILE ".less"
+#define LESSKEYFILE_SYS SYSDIR "/sysless"
+#define DEF_LESSKEYINFILE ".lesskey"
+#define LESSKEYINFILE_SYS SYSDIR "/syslesskey"
+#define LESSHISTFILE ".lesshst"
/* Autodetect mingw */
#if defined(__MINGW32__)
/*
* Define MSDOS_COMPILER if compiling under Microsoft C.
*/
-#define MSDOS_COMPILER WIN32C
+#define MSDOS_COMPILER WIN32C
/*
* Pathname separator character.
*/
-#define PATHNAME_SEP "\\"
+#define PATHNAME_SEP "\\"
#else
/*
* Define MSDOS_COMPILER if compiling under Microsoft C.
*/
-#define MSDOS_COMPILER 0
+#define MSDOS_COMPILER 0
/*
* Pathname separator character.
*/
-#define PATHNAME_SEP "/"
+#define PATHNAME_SEP "/"
#endif
/* Settings always true on Unix. */
@@ -154,9 +157,9 @@
#define TGETENT_OK 1
/*
- * HAVE_ANSI_PROTOS is 1 if your compiler supports ANSI function prototypes.
+ * HAVE_ANSI_PROTOS is 1 if your compiler supports ANSI function prototypes.
*/
-#define HAVE_ANSI_PROTOS 1
+#define HAVE_ANSI_PROTOS 1
/*
* HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
@@ -172,28 +175,28 @@
* HAVE_PERROR is 1 if your system has the perror() call.
* (Actually, if it has sys_errlist, sys_nerr and errno.)
*/
-#define HAVE_PERROR 1
+#define HAVE_PERROR 1
/*
* HAVE_TIME is 1 if your system has the time() call.
*/
-#define HAVE_TIME 1
+#define HAVE_TIME 1
/*
* HAVE_SHELL is 1 if your system supports a SHELL command interpreter.
*/
-#define HAVE_SHELL 1
+#define HAVE_SHELL 1
/*
* Default shell metacharacters and meta-escape character.
*/
-#define DEF_METACHARS "; *?\t\n'\"()<>[]|&^`#\\$%=~{},"
-#define DEF_METAESCAPE "\\"
+#define DEF_METACHARS "; *?\t\n'\"()<>[]|&^`#\\$%=~{},"
+#define DEF_METAESCAPE "\\"
/*
* HAVE_DUP is 1 if your system has the dup() call.
*/
-#define HAVE_DUP 1
+#define HAVE_DUP 1
/* Define to 1 if you have the memcpy() function. */
#define HAVE_MEMCPY 1
@@ -211,26 +214,26 @@
* Sizes of various buffers.
*/
#if 0 /* old sizes for small memory machines */
-#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
-#define UNGOT_SIZE 100 /* Max chars to unget() */
-#define LINEBUF_SIZE 1024 /* Max size of line in input file */
-#define OUTBUF_SIZE 1024 /* Output buffer */
-#define PROMPT_SIZE 200 /* Max size of prompt string */
-#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
-#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
-#define TAGLINE_SIZE 512 /* Max size of line in tags file */
-#define TABSTOP_MAX 32 /* Max number of custom tab stops */
+#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
+#define UNGOT_SIZE 100 /* Max chars to unget() */
+#define LINEBUF_SIZE 1024 /* Max size of line in input file */
+#define OUTBUF_SIZE 1024 /* Output buffer */
+#define PROMPT_SIZE 200 /* Max size of prompt string */
+#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
+#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
+#define TAGLINE_SIZE 512 /* Max size of line in tags file */
+#define TABSTOP_MAX 32 /* Max number of custom tab stops */
#define LINENUM_POOL 200 /* Size of line number pool */
#else /* more reasonable sizes for modern machines */
-#define CMDBUF_SIZE 2048 /* Buffer for multichar commands */
-#define UNGOT_SIZE 200 /* Max chars to unget() */
-#define LINEBUF_SIZE 1024 /* Initial max size of line in input file */
-#define OUTBUF_SIZE 1024 /* Output buffer */
-#define PROMPT_SIZE 2048 /* Max size of prompt string */
-#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
-#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
-#define TAGLINE_SIZE 1024 /* Max size of line in tags file */
-#define TABSTOP_MAX 128 /* Max number of custom tab stops */
+#define CMDBUF_SIZE 2048 /* Buffer for multichar commands */
+#define UNGOT_SIZE 200 /* Max chars to unget() */
+#define LINEBUF_SIZE 1024 /* Initial max size of line in input file */
+#define OUTBUF_SIZE 1024 /* Output buffer */
+#define PROMPT_SIZE 2048 /* Max size of prompt string */
+#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
+#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
+#define TAGLINE_SIZE 1024 /* Max size of line in tags file */
+#define TABSTOP_MAX 128 /* Max number of custom tab stops */
#define LINENUM_POOL 1024 /* Size of line number pool */
#endif
@@ -393,6 +396,9 @@
/* Define to 1 if you have the <termcap.h> header file. */
#define HAVE_TERMCAP_H 1
+/* Define HAVE_TERMINFO if you have the terminfo library. */
+#define HAVE_TERMINFO 1
+
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr. */
#define HAVE_TERMIOS_FUNCS 1
@@ -429,12 +435,6 @@
/* Define HAVE_VOID if your compiler supports the "void" type. */
#define HAVE_VOID 1
-/* Define HAVE_WCTYPE if you have iswupper, iswlower, towupper, towlower. */
-#define HAVE_WCTYPE 1
-
-/* Define to 1 if you have the <wctype.h> header file. */
-#define HAVE_WCTYPE_H 1
-
/* Define to 1 if you have the '_setjmp' function. */
#define HAVE__SETJMP 1
diff --git a/usr.bin/less/lesspipe.sh b/usr.bin/less/lesspipe.sh
index 253914b8b3ee..7992cc4e2e3d 100644
--- a/usr.bin/less/lesspipe.sh
+++ b/usr.bin/less/lesspipe.sh
@@ -21,7 +21,7 @@ case "$1" in
exec lzma -d -c "$1" 2>/dev/null
;;
*.zst)
- exec zstd -d -q -c "$1" 2>/dev/null
+ exec zstdcat -q "$1" 2>/dev/null
;;
*) exec cat "$1" 2>/dev/null
;;
diff --git a/usr.bin/m4/eval.c b/usr.bin/m4/eval.c
index 3170d52bfe2a..0963a61a2914 100644
--- a/usr.bin/m4/eval.c
+++ b/usr.bin/m4/eval.c
@@ -178,7 +178,7 @@ expand_builtin(const char *argv[], int argc, int td)
*/
{
int base = 10;
- int maxdigits = 0;
+ int mindigits = 0;
const char *errstr;
if (argc > 3 && *argv[3] != '\0') {
@@ -189,14 +189,14 @@ expand_builtin(const char *argv[], int argc, int td)
}
}
if (argc > 4) {
- maxdigits = strtonum(argv[4], 0, INT_MAX, &errstr);
+ mindigits = strtonum(argv[4], 0, INT_MAX, &errstr);
if (errstr) {
- m4errx(1, "expr: maxdigits is %s: %s.",
+ m4errx(1, "expr: mindigits is %s: %s.",
errstr, argv[4]);
}
}
if (argc > 2)
- pbnumbase(expr(argv[2]), base, maxdigits);
+ pbnumbase(expr(argv[2]), base, mindigits);
break;
}
@@ -490,7 +490,7 @@ expand_builtin(const char *argv[], int argc, int td)
case DEFNTYPE:
if (argc > 2)
- for (n = 2; n < argc; n++)
+ for (n = argc - 1; n >= 2; n--)
dodefn(argv[n]);
break;
diff --git a/usr.bin/m4/misc.c b/usr.bin/m4/misc.c
index 3091f2ad1f9e..fd72292aeac0 100644
--- a/usr.bin/m4/misc.c
+++ b/usr.bin/m4/misc.c
@@ -138,8 +138,6 @@ pbnumbase(int n, int base, int d)
}
while ((num /= base) > 0);
- if (n < 0)
- printed++;
while (printed++ < d)
pushback('0');
diff --git a/usr.bin/m4/tests/Makefile b/usr.bin/m4/tests/Makefile
index 45245d75e85d..fd7a44cea14c 100644
--- a/usr.bin/m4/tests/Makefile
+++ b/usr.bin/m4/tests/Makefile
@@ -1,10 +1,11 @@
PACKAGE= tests
-TAP_TESTS_SH= legacy_test
+ATF_TESTS_SH= m4_test
${PACKAGE}FILES+= args.m4
${PACKAGE}FILES+= args2.m4
${PACKAGE}FILES+= comments.m4
+${PACKAGE}FILES+= defn.m4
${PACKAGE}FILES+= esyscmd.m4
${PACKAGE}FILES+= eval.m4
${PACKAGE}FILES+= ff_after_dnl.m4.uu
@@ -20,9 +21,14 @@ ${PACKAGE}FILES+= m4wrap3.m4
${PACKAGE}FILES+= patterns.m4
${PACKAGE}FILES+= quotes.m4
${PACKAGE}FILES+= redef.m4
+${PACKAGE}FILES+= strangequotes.m4.uu
+${PACKAGE}FILES+= translit.m4
+${PACKAGE}FILES+= translit2.m4
+
${PACKAGE}FILES+= regress.args.out
${PACKAGE}FILES+= regress.args2.out
${PACKAGE}FILES+= regress.comments.out
+${PACKAGE}FILES+= regress.defn.out
${PACKAGE}FILES+= regress.esyscmd.out
${PACKAGE}FILES+= regress.eval.out
${PACKAGE}FILES+= regress.ff_after_dnl.out
@@ -31,19 +37,18 @@ ${PACKAGE}FILES+= regress.gnuformat.out
${PACKAGE}FILES+= regress.gnupatterns.out
${PACKAGE}FILES+= regress.gnupatterns2.out
${PACKAGE}FILES+= regress.gnuprefix.out
+${PACKAGE}FILES+= regress.gnuprefix.err
${PACKAGE}FILES+= regress.gnusofterror.out
+${PACKAGE}FILES+= regress.gnusofterror.err
${PACKAGE}FILES+= regress.gnutranslit2.out
${PACKAGE}FILES+= regress.includes.out
${PACKAGE}FILES+= regress.m4wrap3.out
${PACKAGE}FILES+= regress.patterns.out
${PACKAGE}FILES+= regress.quotes.out
+${PACKAGE}FILES+= regress.quotes.err
${PACKAGE}FILES+= regress.redef.out
-${PACKAGE}FILES+= regress.sh
${PACKAGE}FILES+= regress.strangequotes.out
${PACKAGE}FILES+= regress.translit.out
${PACKAGE}FILES+= regress.translit2.out
-${PACKAGE}FILES+= strangequotes.m4.uu
-${PACKAGE}FILES+= translit.m4
-${PACKAGE}FILES+= translit2.m4
.include <bsd.test.mk>
diff --git a/usr.bin/m4/tests/defn.m4 b/usr.bin/m4/tests/defn.m4
new file mode 100644
index 000000000000..6599f95a5f20
--- /dev/null
+++ b/usr.bin/m4/tests/defn.m4
@@ -0,0 +1,5 @@
+dnl Check that our defn processes its arguments in order.
+define(a,1)dnl
+define(b,2)dnl
+define(c,3)dnl
+defn(`a',`b',`c')
diff --git a/usr.bin/m4/tests/eval.m4 b/usr.bin/m4/tests/eval.m4
index 1d3f886d0d89..dc0fada781f1 100644
--- a/usr.bin/m4/tests/eval.m4
+++ b/usr.bin/m4/tests/eval.m4
@@ -3,3 +3,5 @@ dnl expr parser
eval(224&127)
eval(224|127)
eval(224&&127)
+eval(3-2, 10, 5)
+eval(2-3, 10, 4)
diff --git a/usr.bin/m4/tests/legacy_test.sh b/usr.bin/m4/tests/legacy_test.sh
deleted file mode 100644
index 3c7842d07bf0..000000000000
--- a/usr.bin/m4/tests/legacy_test.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-SRCDIR="$(dirname "${0}")"; export SRCDIR
-
-m4 "${SRCDIR}/../regress.m4" "${SRCDIR}/regress.sh" | sh
diff --git a/usr.bin/m4/tests/m4_test.sh b/usr.bin/m4/tests/m4_test.sh
new file mode 100644
index 000000000000..aa9be767d1c9
--- /dev/null
+++ b/usr.bin/m4/tests/m4_test.sh
@@ -0,0 +1,249 @@
+#
+# Copyright (c) 2026 Klara, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+m4_test()
+{
+ local dir=$(atf_get_srcdir)
+ local rc=0
+ local args opt output script
+ while getopts "1gP" opt ; do
+ case ${opt} in
+ 1)
+ rc=1
+ ;;
+ *)
+ args="${args% }-${opt}"
+ ;;
+ esac
+ done
+ shift $((OPTIND - 1))
+ script=$1
+ output=$2
+ if [ -z "${output}" ] ; then
+ output="${script}"
+ fi
+ if [ -f "${dir}/regress.${output}.out" ] ; then
+ ln -s "${dir}/regress.${output}.out" out
+ else
+ atf_fail "regress.${output}.out not found"
+ fi
+ if [ -f "${dir}/regress.${output}.err" ] ; then
+ ln -s "${dir}/regress.${output}.err" err
+ else
+ touch err
+ fi
+ if [ -f "${dir}/${script}.m4.uu" ] ; then
+ atf_check uudecode -o "${script}.m4" "${dir}/${script}.m4.uu"
+ elif [ -f "${dir}/${script}.m4" ] ; then
+ ln -s "${dir}/${script}.m4" "${script}.m4"
+ else
+ atf_fail "${script}.m4 not found"
+ fi
+ atf_check -s exit:${rc} -o file:out -e file:err \
+ m4 -I "${dir}" ${args} "${script}.m4"
+}
+
+args_head()
+{
+}
+args_body()
+{
+ m4_test args
+}
+
+args2_head()
+{
+}
+args2_body()
+{
+ m4_test args2
+}
+
+comments_head()
+{
+}
+comments_body()
+{
+ m4_test comments
+}
+
+defn_head()
+{
+}
+defn_body()
+{
+ m4_test defn
+}
+
+esyscmd_head()
+{
+}
+esyscmd_body()
+{
+ m4_test esyscmd
+}
+
+eval_head()
+{
+}
+eval_body()
+{
+ m4_test eval
+}
+
+ff_after_dnl_head()
+{
+}
+ff_after_dnl_body()
+{
+ m4_test ff_after_dnl
+}
+
+gnueval_head()
+{
+}
+gnueval_body()
+{
+ m4_test -g gnueval
+}
+
+gnuformat_head()
+{
+}
+gnuformat_body()
+{
+ m4_test -g gnuformat
+}
+
+gnupatterns_head()
+{
+}
+gnupatterns_body()
+{
+ m4_test -g gnupatterns
+}
+
+gnupatterns2_head()
+{
+}
+gnupatterns2_body()
+{
+ m4_test -g gnupatterns2
+}
+
+gnuprefix_head()
+{
+}
+gnuprefix_body()
+{
+ m4_test -P gnuprefix
+}
+
+gnusofterror_head()
+{
+}
+gnusofterror_body()
+{
+ m4_test -1 -g gnusofterror
+}
+
+gnutranslit2_head()
+{
+}
+gnutranslit2_body()
+{
+ m4_test -g translit2 gnutranslit2
+}
+
+includes_head()
+{
+}
+includes_body()
+{
+ m4_test includes
+}
+
+m4wrap3_head()
+{
+}
+m4wrap3_body()
+{
+ m4_test m4wrap3
+}
+
+patterns_head()
+{
+}
+patterns_body()
+{
+ m4_test patterns
+}
+
+quotes_head()
+{
+}
+quotes_body()
+{
+ m4_test -1 quotes
+}
+
+redef_head()
+{
+}
+redef_body()
+{
+ m4_test redef
+}
+
+strangequotes_head()
+{
+}
+strangequotes_body()
+{
+ m4_test strangequotes
+}
+
+translit_head()
+{
+}
+translit_body()
+{
+ m4_test translit
+}
+
+translit2_head()
+{
+}
+translit2_body()
+{
+ m4_test translit2
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case args
+ atf_add_test_case args2
+ atf_add_test_case comments
+ atf_add_test_case defn
+ atf_add_test_case esyscmd
+ atf_add_test_case eval
+ atf_add_test_case ff_after_dnl
+ atf_add_test_case gnueval
+ atf_add_test_case gnuformat
+ atf_add_test_case gnupatterns
+ atf_add_test_case gnupatterns2
+ atf_add_test_case gnuprefix
+ atf_add_test_case gnusofterror
+ atf_add_test_case gnutranslit2
+ atf_add_test_case includes
+ atf_add_test_case m4wrap3
+ atf_add_test_case patterns
+ atf_add_test_case quotes
+ atf_add_test_case redef
+ atf_add_test_case strangequotes
+ atf_add_test_case translit
+ atf_add_test_case translit2
+}
diff --git a/usr.bin/m4/tests/regress.defn.out b/usr.bin/m4/tests/regress.defn.out
new file mode 100644
index 000000000000..190a18037c64
--- /dev/null
+++ b/usr.bin/m4/tests/regress.defn.out
@@ -0,0 +1 @@
+123
diff --git a/usr.bin/m4/tests/regress.eval.out b/usr.bin/m4/tests/regress.eval.out
index 7298b3f43840..b1bb211dcb64 100644
--- a/usr.bin/m4/tests/regress.eval.out
+++ b/usr.bin/m4/tests/regress.eval.out
@@ -1,3 +1,5 @@
96
255
1
+00001
+-0001
diff --git a/usr.bin/m4/tests/regress.gnuprefix.err b/usr.bin/m4/tests/regress.gnuprefix.err
new file mode 100644
index 000000000000..8939371e81f4
--- /dev/null
+++ b/usr.bin/m4/tests/regress.gnuprefix.err
@@ -0,0 +1,44 @@
+`m4_ifelse' `m4_ifelse'
+`m4_dnl' `m4_dnl'
+`m4_expr' `m4_expr'
+`m4_builtin' `m4_builtin'
+`m4_popdef' `m4_popdef'
+`m4_eval' `m4_eval'
+`m4_len' `m4_len'
+`m4_indir' `m4_indir'
+`m4_sinclude' `m4_sinclude'
+`m4_index' `m4_index'
+`m4_traceoff' `m4_traceoff'
+`m4___file__' `m4___file__'
+`m4_unix' `m4_unix'
+`m4_mkstemp' `m4_mkstemp'
+`m4_changecom' `m4_changecom'
+`m4_defn' `m4_defn'
+`m4_decr' `m4_decr'
+`m4_translit' `m4_translit'
+`m4_patsubst' `m4_patsubst'
+`m4_dumpdef' `m4_dumpdef'
+`m4___line__' `m4___line__'
+`m4_esyscmd' `m4_esyscmd'
+`m4_traceon' `m4_traceon'
+`m4_incr' `m4_incr'
+`m4_shift' `m4_shift'
+`m4_syscmd' `m4_syscmd'
+`m4_include' `m4_include'
+`m4_pushdef' `m4_pushdef'
+`m4_paste' `m4_paste'
+`m4_regexp' `m4_regexp'
+`m4_changequote' `m4_changequote'
+`m4_undivert' `m4_undivert'
+`m4_m4exit' `m4_m4exit'
+`m4_substr' `m4_substr'
+`m4_m4wrap' `m4_m4wrap'
+`m4_ifdef' `m4_ifdef'
+`m4_sysval' `m4_sysval'
+`m4_divert' `m4_divert'
+`m4_maketemp' `m4_maketemp'
+`m4_spaste' `m4_spaste'
+`m4_define' `m4_define'
+`m4_undefine' `m4_undefine'
+`m4_divnum' `m4_divnum'
+`m4_errprint' `m4_errprint'
diff --git a/usr.bin/m4/tests/regress.gnuprefix.out b/usr.bin/m4/tests/regress.gnuprefix.out
index 186421d8650b..3e86f4db699c 100644
--- a/usr.bin/m4/tests/regress.gnuprefix.out
+++ b/usr.bin/m4/tests/regress.gnuprefix.out
@@ -1,46 +1,2 @@
-`m4_ifelse' `m4_ifelse'
-`m4_dnl' `m4_dnl'
-`m4_expr' `m4_expr'
-`m4_builtin' `m4_builtin'
-`m4_popdef' `m4_popdef'
-`m4_eval' `m4_eval'
-`m4_len' `m4_len'
-`m4_indir' `m4_indir'
-`m4_sinclude' `m4_sinclude'
-`m4_index' `m4_index'
-`m4_traceoff' `m4_traceoff'
-`m4___file__' `m4___file__'
-`m4_unix' `m4_unix'
-`m4_mkstemp' `m4_mkstemp'
-`m4_changecom' `m4_changecom'
-`m4_defn' `m4_defn'
-`m4_decr' `m4_decr'
-`m4_translit' `m4_translit'
-`m4_patsubst' `m4_patsubst'
-`m4_dumpdef' `m4_dumpdef'
-`m4___line__' `m4___line__'
-`m4_esyscmd' `m4_esyscmd'
-`m4_traceon' `m4_traceon'
-`m4_incr' `m4_incr'
-`m4_shift' `m4_shift'
-`m4_syscmd' `m4_syscmd'
-`m4_include' `m4_include'
-`m4_pushdef' `m4_pushdef'
-`m4_paste' `m4_paste'
-`m4_regexp' `m4_regexp'
-`m4_changequote' `m4_changequote'
-`m4_undivert' `m4_undivert'
-`m4_m4exit' `m4_m4exit'
-`m4_substr' `m4_substr'
-`m4_m4wrap' `m4_m4wrap'
-`m4_ifdef' `m4_ifdef'
-`m4_sysval' `m4_sysval'
-`m4_divert' `m4_divert'
-`m4_maketemp' `m4_maketemp'
-`m4_spaste' `m4_spaste'
-`m4_define' `m4_define'
-`m4_undefine' `m4_undefine'
-`m4_divnum' `m4_divnum'
-`m4_errprint' `m4_errprint'
dumpdef()
diff --git a/usr.bin/m4/tests/regress.gnusofterror.err b/usr.bin/m4/tests/regress.gnusofterror.err
new file mode 100644
index 000000000000..d34464e85791
--- /dev/null
+++ b/usr.bin/m4/tests/regress.gnusofterror.err
@@ -0,0 +1 @@
+m4: gnusofterror.m4 at line 2: include(hey I do not exit): No such file or directory
diff --git a/usr.bin/m4/tests/regress.gnusofterror.out b/usr.bin/m4/tests/regress.gnusofterror.out
index 5c23eb237b6c..8baef1b4abc4 100644
--- a/usr.bin/m4/tests/regress.gnusofterror.out
+++ b/usr.bin/m4/tests/regress.gnusofterror.out
@@ -1,2 +1 @@
-m4: gnusofterror.m4 at line 2: include(hey I do not exit): No such file or directory
abc
diff --git a/usr.bin/m4/tests/regress.quotes.err b/usr.bin/m4/tests/regress.quotes.err
new file mode 100644
index 000000000000..50eb78ca62df
--- /dev/null
+++ b/usr.bin/m4/tests/regress.quotes.err
@@ -0,0 +1,2 @@
+m4: unclosed quote:
+ quotes.m4 at line 54
diff --git a/usr.bin/m4/tests/regress.quotes.out b/usr.bin/m4/tests/regress.quotes.out
index cf34ba42a8d0..df38b6e6cd4d 100644
--- a/usr.bin/m4/tests/regress.quotes.out
+++ b/usr.bin/m4/tests/regress.quotes.out
@@ -1,5 +1,3 @@
-m4: unclosed quote:
- quotes.m4 at line 54
1: normal
quoted string
[quoted STRING]
diff --git a/usr.bin/m4/tests/regress.sh b/usr.bin/m4/tests/regress.sh
deleted file mode 100644
index 39c9103db8d9..000000000000
--- a/usr.bin/m4/tests/regress.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-
-echo 1..21
-
-test_m4() {
- m4 "${@}" 2>&1 | sed -e "s,${SRCDIR}/,,g"
-}
-
-REGRESSION_START($1)
-
-REGRESSION_TEST(`args', `test_m4 ${SRCDIR}/args.m4')
-REGRESSION_TEST(`args2', `test_m4 ${SRCDIR}/args2.m4')
-REGRESSION_TEST(`comments', `test_m4 ${SRCDIR}/comments.m4')
-REGRESSION_TEST(`esyscmd', `test_m4 ${SRCDIR}/esyscmd.m4')
-REGRESSION_TEST(`eval', `test_m4 ${SRCDIR}/eval.m4')
-REGRESSION_TEST(`ff_after_dnl', `uudecode -o /dev/stdout ${SRCDIR}/ff_after_dnl.m4.uu | m4')
-REGRESSION_TEST(`gnueval', `test_m4 -g ${SRCDIR}/gnueval.m4')
-REGRESSION_TEST(`gnuformat', `test_m4 -g ${SRCDIR}/gnuformat.m4')
-REGRESSION_TEST(`gnupatterns', `test_m4 -g ${SRCDIR}/gnupatterns.m4')
-REGRESSION_TEST(`gnupatterns2', `test_m4 -g ${SRCDIR}/gnupatterns2.m4')
-REGRESSION_TEST(`gnuprefix', `test_m4 -P ${SRCDIR}/gnuprefix.m4 2>&1')
-REGRESSION_TEST(`gnusofterror', `test_m4 -g ${SRCDIR}/gnusofterror.m4 2>&1')
-REGRESSION_TEST(`gnutranslit2', `test_m4 -g ${SRCDIR}/translit2.m4')
-REGRESSION_TEST(`includes', `test_m4 -I${SRCDIR} ${SRCDIR}/includes.m4')
-REGRESSION_TEST(`m4wrap3', `test_m4 ${SRCDIR}/m4wrap3.m4')
-REGRESSION_TEST(`patterns', `test_m4 ${SRCDIR}/patterns.m4')
-REGRESSION_TEST(`quotes', `test_m4 ${SRCDIR}/quotes.m4 2>&1')
-REGRESSION_TEST(`strangequotes', `uudecode -o /dev/stdout ${SRCDIR}/strangequotes.m4.uu | m4')
-REGRESSION_TEST(`redef', `test_m4 ${SRCDIR}/redef.m4')
-REGRESSION_TEST(`translit', `test_m4 ${SRCDIR}/translit.m4')
-REGRESSION_TEST(`translit2', `test_m4 ${SRCDIR}/translit2.m4')
-
-REGRESSION_END()
diff --git a/usr.bin/man/manpath.1 b/usr.bin/man/manpath.1
index ac9e3b2db5a7..ea01ce23333a 100644
--- a/usr.bin/man/manpath.1
+++ b/usr.bin/man/manpath.1
@@ -1,5 +1,5 @@
.\"-
-.\" SPDX-License-Identifer: BSD-2-Clause
+.\" SPDX-License-Identifier: BSD-2-Clause
.\"
.\" Copyright (c) 2010 Gordon Tetlow
.\" All rights reserved.
diff --git a/usr.bin/mkimg/apm.c b/usr.bin/mkimg/apm.c
index 259a7533c27c..59776d18bc47 100644
--- a/usr.bin/mkimg/apm.c
+++ b/usr.bin/mkimg/apm.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/bsd.c b/usr.bin/mkimg/bsd.c
index 17933c01ac07..647e9ab0608c 100644
--- a/usr.bin/mkimg/bsd.c
+++ b/usr.bin/mkimg/bsd.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/ebr.c b/usr.bin/mkimg/ebr.c
index 4d6adbb3b8ba..20ade1ed88d1 100644
--- a/usr.bin/mkimg/ebr.c
+++ b/usr.bin/mkimg/ebr.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/endian.h b/usr.bin/mkimg/endian.h
index e9dc2b44b9b7..98e699bee855 100644
--- a/usr.bin/mkimg/endian.h
+++ b/usr.bin/mkimg/endian.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
* All rights reserved.
*
diff --git a/usr.bin/mkimg/format.c b/usr.bin/mkimg/format.c
index 6730c22ca153..97e580cd8ca2 100644
--- a/usr.bin/mkimg/format.c
+++ b/usr.bin/mkimg/format.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/format.h b/usr.bin/mkimg/format.h
index 304af4586da8..db1ea764ced2 100644
--- a/usr.bin/mkimg/format.h
+++ b/usr.bin/mkimg/format.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/gpt.c b/usr.bin/mkimg/gpt.c
index ed3f008c394f..ce817ea10ed2 100644
--- a/usr.bin/mkimg/gpt.c
+++ b/usr.bin/mkimg/gpt.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/image.c b/usr.bin/mkimg/image.c
index 07aaf1a6c0ea..90817206e317 100644
--- a/usr.bin/mkimg/image.c
+++ b/usr.bin/mkimg/image.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/image.h b/usr.bin/mkimg/image.h
index 53dd3dc2df8a..956fe3f27556 100644
--- a/usr.bin/mkimg/image.h
+++ b/usr.bin/mkimg/image.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/mbr.c b/usr.bin/mkimg/mbr.c
index 7bda01c72e6a..cc5bd51bd7e5 100644
--- a/usr.bin/mkimg/mbr.c
+++ b/usr.bin/mkimg/mbr.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/mkimg.c b/usr.bin/mkimg/mkimg.c
index 8f3a5d879bbb..c625b49dc29a 100644
--- a/usr.bin/mkimg/mkimg.c
+++ b/usr.bin/mkimg/mkimg.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2013,2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/mkimg.h b/usr.bin/mkimg/mkimg.h
index aa0ec2a8d944..13ca7aab36fb 100644
--- a/usr.bin/mkimg/mkimg.h
+++ b/usr.bin/mkimg/mkimg.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/qcow.c b/usr.bin/mkimg/qcow.c
index 2dc3e5498420..6e67cbaa0887 100644
--- a/usr.bin/mkimg/qcow.c
+++ b/usr.bin/mkimg/qcow.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Marcel Moolenaar
* All rights reserved.
*
diff --git a/usr.bin/mkimg/raw.c b/usr.bin/mkimg/raw.c
index 2de674b908ac..b68c5f06b3c4 100644
--- a/usr.bin/mkimg/raw.c
+++ b/usr.bin/mkimg/raw.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/scheme.c b/usr.bin/mkimg/scheme.c
index 85ed94013e8d..80ff456a709f 100644
--- a/usr.bin/mkimg/scheme.c
+++ b/usr.bin/mkimg/scheme.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2013,2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/scheme.h b/usr.bin/mkimg/scheme.h
index 52614255595f..1c234b86d66c 100644
--- a/usr.bin/mkimg/scheme.h
+++ b/usr.bin/mkimg/scheme.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2013,2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mkimg/uuid.c b/usr.bin/mkimg/uuid.c
index 885a6c36b522..da99c33109e3 100644
--- a/usr.bin/mkimg/uuid.c
+++ b/usr.bin/mkimg/uuid.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2016 Marcel Moolenaar
* All rights reserved.
*
diff --git a/usr.bin/mkimg/vhd.c b/usr.bin/mkimg/vhd.c
index c0fe45ab416e..09d3cfab4dcc 100644
--- a/usr.bin/mkimg/vhd.c
+++ b/usr.bin/mkimg/vhd.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014, 2015 Marcel Moolenaar
* All rights reserved.
*
diff --git a/usr.bin/mkimg/vhdx.c b/usr.bin/mkimg/vhdx.c
index e280250bd964..6ecdfe8e13e9 100644
--- a/usr.bin/mkimg/vhdx.c
+++ b/usr.bin/mkimg/vhdx.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2020 Oleksandr Tymoshenko <gonzo@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
diff --git a/usr.bin/mkimg/vmdk.c b/usr.bin/mkimg/vmdk.c
index 132eb801387a..79ef256df223 100644
--- a/usr.bin/mkimg/vmdk.c
+++ b/usr.bin/mkimg/vmdk.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2014 Juniper Networks, Inc.
* All rights reserved.
*
diff --git a/usr.bin/mt/mt.1 b/usr.bin/mt/mt.1
index 4cafdf4437c7..361c9ae65bda 100644
--- a/usr.bin/mt/mt.1
+++ b/usr.bin/mt/mt.1
@@ -26,7 +26,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd October 31, 2023
+.Dd March 2, 2026
.Dt MT 1
.Os
.Sh NAME
@@ -524,6 +524,8 @@ Value Width Tracks Density Code Type Reference Note
0x5D 12.7 (0.5) 5376 19,107 (485,318) C LTO-M8 14
0x5E 12.7 (0.5) 6656 20,669 (524,993) C LTO-8
0x60 12.7 (0.5) 8960 23,031 (584,987) C LTO-9
+0x62 12.7 (0.5)15104 21,657 (550,088) C LTO-10 15
+0x63 12.7 (0.5)15104 22,441 (570,001) C LTO-10P 15
0x71 12.7 (0.5) 512 11,800 (299,720) C 3592A1 (encrypted)
0x72 12.7 (0.5) 896 11,800 (299,720) C 3592A2 (encrypted)
0x73 12.7 (0.5) 1152 13,452 (341,681) C 3592A3 (encrypted)
@@ -572,6 +574,11 @@ NOTES
LTO-7 cartridge initialized with a higher density format by an LTO-8
drive. It cannot be read by an LTO-7 drive. Uncompressed capacity
is 9TB, compared to 6TB for LTO-7 and 12TB for LTO-8.
+15. LTO-10 Premium cartridges hold 40TB uncompressed vs. 30TB
+ uncompressed for standard LTO-10 cartridges due to slightly higher
+ density and stronger, thinner, longer tape. LTO-10 tape drives
+ are not backward compatible with previous generation LTO tape
+ cartridges.
.Ed
.Bd -literal -offset 2n
NOTE ON QIC STREAMERS
diff --git a/usr.bin/netstat/mroute.c b/usr.bin/netstat/mroute.c
index 1577a6ae73ac..75c3c8477ea4 100644
--- a/usr.bin/netstat/mroute.c
+++ b/usr.bin/netstat/mroute.c
@@ -37,7 +37,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
/*
* Print multicast routing structures and statistics.
*
@@ -157,7 +156,7 @@ print_bw_meter(struct bw_meter *bw_meter, int *banner_printed)
}
xo_emit(" {:remaining-time/%s}", s3);
- xo_open_instance("bandwidth-meter");
+ xo_close_instance("bandwidth-meter");
xo_emit("\n");
}
@@ -186,9 +185,9 @@ print_mfc(struct mfc *m, int maxvif, int *banner_printed)
}
memcpy(&sin.sin_addr, &m->mfc_origin, sizeof(sin.sin_addr));
- xo_emit(" {:origin-address/%-15.15s}", routename(sa, numeric_addr));
+ xo_emit(" {t:origin-address/%-*.15s}", 15, routename(sa, numeric_addr));
memcpy(&sin.sin_addr, &m->mfc_mcastgrp, sizeof(sin.sin_addr));
- xo_emit(" {:group-address/%-15.15s}",
+ xo_emit(" {t:group-address/%-15.15s}",
routename(sa, numeric_addr));
xo_emit(" {:sent-packets/%9lu}", m->mfc_pkt_cnt);
xo_emit(" {:parent/%3d} ", m->mfc_parent);
@@ -303,12 +302,12 @@ mroutepr(void)
xo_open_instance("vif");
memcpy(&sin.sin_addr, &v->v_lcl_addr, sizeof(sin.sin_addr));
- xo_emit(" {:vif/%2u} {:threshold/%6u} {:route/%-15.15s}",
+ xo_emit(" {:vif/%2u} {:threshold/%6u} {t:route/%-15.15s}",
/* opposite math of add_vif() */
vifi, v->v_threshold,
routename(sa, numeric_addr));
memcpy(&sin.sin_addr, &v->v_rmt_addr, sizeof(sin.sin_addr));
- xo_emit(" {:source/%-15.15s}", (v->v_flags & VIFF_TUNNEL) ?
+ xo_emit(" {t:source/%-15.15s}", (v->v_flags & VIFF_TUNNEL) ?
routename(sa, numeric_addr) : "");
xo_emit(" {:received-packets/%9lu} {:sent-packets/%9lu}\n",
diff --git a/usr.bin/netstat/mroute6.c b/usr.bin/netstat/mroute6.c
index 0bb44b8292e7..5898791dcbe6 100644
--- a/usr.bin/netstat/mroute6.c
+++ b/usr.bin/netstat/mroute6.c
@@ -65,7 +65,6 @@
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#ifdef INET6
#include <sys/param.h>
#include <sys/queue.h>
@@ -151,7 +150,7 @@ mroute6pr(void)
xo_close_instance("multicast-interface");
}
if (banner_printed)
- xo_open_list("multicast-interface");
+ xo_close_list("multicast-interface");
else
xo_emit("\n{T:IPv6 Multicast Interface Table is empty}\n");
@@ -172,19 +171,19 @@ mroute6pr(void)
xo_open_list("multicast-forwarding-cache");
xo_emit("\n"
"{T:IPv6 Multicast Forwarding Cache}\n");
- xo_emit(" {T:%-*.*s} {T:%-*.*s} {T:%s}",
+ xo_emit(" {T:/%-*.*s} {T:/%-*.*s} {T:/%s}\n",
WID_ORG, WID_ORG, "Origin",
WID_GRP, WID_GRP, "Group",
- " Packets Waits In-Mif Out-Mifs\n");
+ " Packets Waits In-Mif Out-Mifs");
banner_printed = 1;
}
xo_open_instance("multicast-forwarding-cache");
- xo_emit(" {:origin/%-*.*s}", WID_ORG, WID_ORG,
+ xo_emit(" {t:origin/%-*.*s}", WID_ORG, WID_ORG,
routename(sin6tosa(&mfc.mf6c_origin),
numeric_addr));
- xo_emit(" {:group/%-*.*s}", WID_GRP, WID_GRP,
+ xo_emit(" {t:group/%-*.*s}", WID_GRP, WID_GRP,
routename(sin6tosa(&mfc.mf6c_mcastgrp),
numeric_addr));
xo_emit(" {:total-packets/%9ju}",
@@ -205,7 +204,7 @@ mroute6pr(void)
xo_open_list("mif");
for (mifi = 0; mifi <= maxmif; mifi++) {
if (IF_ISSET(mifi, &mfc.mf6c_ifset))
- xo_emit(" {l:%u}", mifi);
+ xo_emit(" {l:/%u}", mifi);
}
xo_close_list("mif");
xo_emit("\n");
diff --git a/usr.bin/netstat/route_netlink.c b/usr.bin/netstat/route_netlink.c
index e7b2a1964602..2c4b7a5c6b00 100644
--- a/usr.bin/netstat/route_netlink.c
+++ b/usr.bin/netstat/route_netlink.c
@@ -218,8 +218,8 @@ p_path(struct snl_parsed_route *rt, bool is_mpath)
else
xo_emit("{t:interface-name/%*.*s}", wid.iface, wid.iface,
prettyname);
- if (rt->rta_expires > 0) {
- xo_emit(" {:expire-time/%*u}", wid.expire, rt->rta_expires);
+ if (rt->rta_expire > 0) {
+ xo_emit(" {:expire-time/%*u}", wid.expire, rt->rta_expire);
}
}
@@ -244,6 +244,7 @@ p_rtentry_netlink(struct snl_state *ss, const char *name, struct nlmsghdr *hdr)
rt.rtax_weight = nhop->rtnh_weight;
rt.rta_rtflags = nhop->rta_rtflags ? nhop->rta_rtflags : orig_rtflags;
rt.rtax_mtu = nhop->rtax_mtu ? nhop->rtax_mtu : orig_mtu;
+ rt.rta_expire = nhop->rta_expire;
xo_open_instance(name);
p_path(&rt, true);
diff --git a/usr.bin/newgrp/newgrp.1 b/usr.bin/newgrp/newgrp.1
index d9701feef0d7..032aeb72616d 100644
--- a/usr.bin/newgrp/newgrp.1
+++ b/usr.bin/newgrp/newgrp.1
@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd February 8, 2013
+.Dd February 6, 2025
.Dt NEWGRP 1
.Os
.Sh NAME
@@ -67,6 +67,21 @@ exits >0.
Otherwise, the exit status of
.Nm
is the exit status of the shell.
+.Sh EXAMPLES
+Create a new group,
+.Ar foo ,
+with
+.Xr pw 8 :
+.Pp
+.Dl pw group add foo
+.Pp
+Set the group password:
+.Pp
+.Dl pw group mod foo -h 0
+.Pp
+As a non-root user, switch to the group:
+.Pp
+.Dl newgrp foo
.Sh SEE ALSO
.Xr csh 1 ,
.Xr groups 1 ,
diff --git a/usr.bin/paste/Makefile b/usr.bin/paste/Makefile
index e4f9e6d817b5..33fcb91db84d 100644
--- a/usr.bin/paste/Makefile
+++ b/usr.bin/paste/Makefile
@@ -1,3 +1,11 @@
+.include <src.opts.mk>
+
PROG= paste
+.if ${MK_CASPER} != "no" && !defined(RESCUE)
+LIBADD+= casper
+LIBADD+= cap_fileargs
+CFLAGS+= -DWITH_CASPER
+.endif
+
.include <bsd.prog.mk>
diff --git a/usr.bin/paste/paste.c b/usr.bin/paste/paste.c
index 8114a85a869a..cc029e20ea9c 100644
--- a/usr.bin/paste/paste.c
+++ b/usr.bin/paste/paste.c
@@ -33,9 +33,13 @@
*/
#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/capsicum.h>
+#include <capsicum_helpers.h>
#include <err.h>
#include <errno.h>
+#include <fcntl.h>
#include <limits.h>
#include <locale.h>
#include <stdio.h>
@@ -44,11 +48,14 @@
#include <unistd.h>
#include <wchar.h>
+#include <libcasper.h>
+#include <casper/cap_fileargs.h>
+
static wchar_t *delim;
static int delimcnt;
-static int parallel(char **);
-static int sequential(char **);
+static int parallel(char **, fileargs_t *);
+static int sequential(char **, fileargs_t *);
static int tr(wchar_t *);
static void usage(void) __dead2;
@@ -61,6 +68,8 @@ main(int argc, char *argv[])
wchar_t *warg;
const char *arg;
size_t len;
+ fileargs_t *fa;
+ cap_rights_t rights;
setlocale(LC_CTYPE, "");
@@ -98,51 +107,58 @@ main(int argc, char *argv[])
delim = tab;
}
- if (seq)
- rval = sequential(argv);
- else
- rval = parallel(argv);
+ fa = fileargs_init(argc, argv, O_RDONLY, 0,
+ cap_rights_init(&rights, CAP_READ, CAP_FSTAT, CAP_FCNTL), FA_OPEN);
+ if (fa == NULL)
+ err(1, "unable to open system.fileargs service");
+
+ caph_cache_catpages();
+ if (caph_enter_casper() < 0)
+ err(1, "unable to enter capability mode");
+
+ rval = seq ? sequential(argv, fa) : parallel(argv, fa);
+
+ fileargs_free(fa);
exit(rval);
}
typedef struct _list {
- struct _list *next;
+ STAILQ_ENTRY(_list) entries;
FILE *fp;
int cnt;
char *name;
} LIST;
+static STAILQ_HEAD(head, _list) lh;
+
static int
-parallel(char **argv)
+parallel(char **argv, fileargs_t *fa)
{
LIST *lp;
int cnt;
wint_t ich;
wchar_t ch;
char *p;
- LIST *head, *tmp;
int opencnt, output;
- for (cnt = 0, head = tmp = NULL; (p = *argv); ++argv, ++cnt) {
+ STAILQ_INIT(&lh);
+
+ for (cnt = 0; (p = *argv); ++argv, ++cnt) {
if ((lp = malloc(sizeof(LIST))) == NULL)
err(1, NULL);
if (p[0] == '-' && !p[1])
lp->fp = stdin;
- else if (!(lp->fp = fopen(p, "r")))
+ else if (!(lp->fp = fileargs_fopen(fa, p, "r")))
err(1, "%s", p);
- lp->next = NULL;
lp->cnt = cnt;
lp->name = p;
- if (!head)
- head = tmp = lp;
- else {
- tmp->next = lp;
- tmp = lp;
- }
+
+ STAILQ_INSERT_TAIL(&lh, lp, entries);
}
for (opencnt = cnt; opencnt;) {
- for (output = 0, lp = head; lp; lp = lp->next) {
+ output = 0;
+ STAILQ_FOREACH(lp, &lh, entries) {
if (!lp->fp) {
if (output && lp->cnt &&
(ch = delim[(lp->cnt - 1) % delimcnt]))
@@ -183,7 +199,7 @@ parallel(char **argv)
}
static int
-sequential(char **argv)
+sequential(char **argv, fileargs_t *fa)
{
FILE *fp;
int cnt, failed, needdelim;
@@ -194,7 +210,7 @@ sequential(char **argv)
for (; (p = *argv); ++argv) {
if (p[0] == '-' && !p[1])
fp = stdin;
- else if (!(fp = fopen(p, "r"))) {
+ else if (!(fp = fileargs_fopen(fa, p, "r"))) {
warn("%s", p);
failed = 1;
continue;
@@ -243,7 +259,8 @@ tr(wchar_t *arg)
default:
*arg = ch;
break;
- } else
+ }
+ else
*arg = ch;
if (!cnt)
diff --git a/usr.bin/procstat/procstat_kqueue.c b/usr.bin/procstat/procstat_kqueue.c
index ce9d2cb42fe2..b4d396e12d3a 100644
--- a/usr.bin/procstat/procstat_kqueue.c
+++ b/usr.bin/procstat/procstat_kqueue.c
@@ -135,8 +135,10 @@ procstat_kqueue_flags(const struct pk_elem *names, unsigned flags, bool commas)
}
}
- if (strlen(res) == 0)
- return (strdup("-"));
+ if (strlen(res) == 0) {
+ free(res);
+ res = strdup("-");
+ }
return (res);
}
diff --git a/usr.bin/resizewin/resizewin.c b/usr.bin/resizewin/resizewin.c
index c6fefd79624c..89b91c219de8 100644
--- a/usr.bin/resizewin/resizewin.c
+++ b/usr.bin/resizewin/resizewin.c
@@ -1,4 +1,6 @@
/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* resizewin
*
* Query terminal for size and inform the kernel
diff --git a/usr.bin/rpcinfo/rpcinfo.c b/usr.bin/rpcinfo/rpcinfo.c
index 5f2dd4433292..5156dd2db4e0 100644
--- a/usr.bin/rpcinfo/rpcinfo.c
+++ b/usr.bin/rpcinfo/rpcinfo.c
@@ -125,7 +125,8 @@ static void pmapdump(int, char **);
static void get_inet_address(struct sockaddr_in *, char *);
#endif
-static bool_t reply_proc(void *, struct netbuf *, struct netconfig *);
+static bool_t reply_proc(char *, const struct netbuf *,
+ const struct netconfig *);
static void brdcst(int, char **);
static void addrping(char *, char *, int, char **);
static void progping(char *, int, char **);
@@ -584,7 +585,8 @@ get_inet_address(struct sockaddr_in *addr, char *host)
/*ARGSUSED*/
static bool_t
-reply_proc(void *res, struct netbuf *who, struct netconfig *nconf)
+reply_proc(char *res __unused, const struct netbuf *who,
+ const struct netconfig *nconf)
/* void *res; Nothing comes back */
/* struct netbuf *who; Who sent us the reply */
/* struct netconfig *nconf; On which transport the reply came */
@@ -621,7 +623,7 @@ brdcst(int argc, char **argv)
vers = getvers(argv[1]);
rpc_stat = rpc_broadcast(prognum, vers, NULLPROC,
(xdrproc_t) xdr_void, (char *)NULL, (xdrproc_t) xdr_void,
- (char *)NULL, (resultproc_t) reply_proc, NULL);
+ (char *)NULL, reply_proc, NULL);
if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT))
errx(1, "broadcast failed: %s", clnt_sperrno(rpc_stat));
exit(0);
diff --git a/usr.bin/runat/runat.c b/usr.bin/runat/runat.c
index 99437f3472f4..eb30ef87f2f9 100644
--- a/usr.bin/runat/runat.c
+++ b/usr.bin/runat/runat.c
@@ -8,17 +8,25 @@
#include <sys/wait.h>
#include <err.h>
#include <fcntl.h>
+#include <getopt.h>
#include <paths.h>
#include <signal.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+static struct option longopts[] = {
+ { "nofollow", no_argument, NULL, 'h' },
+ { "-", no_argument, NULL, '-' },
+ { NULL, 0, NULL, 0}
+};
+
static void
usage(void)
{
- (void)fprintf(stderr, "usage: runat <file> "
+ (void)fprintf(stderr, "usage: runat [-h/--nofollow] [--] <file> "
"<shell command>\n");
exit(1);
}
@@ -26,15 +34,28 @@ usage(void)
int
main(int argc, char *argv[])
{
- int i, file_fd, nameddir_fd, outsiz;
+ int ch, file_fd, flags, i, longindex, nameddir_fd, outsiz;
char *buf;
long named_enabled;
size_t pos, siz;
+ bool done_args;
- if (argc <= 2)
- usage();
- argv++;
- argc--;
+ flags = O_RDONLY | O_CLOEXEC | O_PATH;
+ done_args = false;
+ while (!done_args && (ch = getopt_long(argc, argv, "h-", longopts,
+ &longindex)) != -1)
+ switch (ch) {
+ case 'h':
+ flags |= O_NOFOLLOW;
+ break;
+ case '-':
+ done_args = true;
+ break;
+ default:
+ usage();
+ }
+ argv += optind;
+ argc -= optind;
if (argc < 2)
usage();
@@ -61,7 +82,7 @@ main(int argc, char *argv[])
}
buf[pos - 1] = '\0';
- file_fd = open(argv[0], O_RDONLY | O_CLOEXEC, 0);
+ file_fd = open(argv[0], flags, 0);
if (file_fd < 0)
err(1, "Cannot open %s", argv[0]);
nameddir_fd = openat(file_fd, ".", O_RDONLY | O_CLOEXEC | O_NAMEDATTR,
diff --git a/usr.bin/rup/rup.c b/usr.bin/rup/rup.c
index 5f605f55b413..d53d4ebcd28e 100644
--- a/usr.bin/rup/rup.c
+++ b/usr.bin/rup/rup.c
@@ -206,7 +206,7 @@ allhosts(void)
clnt_stat = clnt_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS,
(xdrproc_t)xdr_void, NULL,
(xdrproc_t)xdr_statstime, &host_stat,
- (resultproc_t)rstat_reply);
+ (clnt_broadcast_resultproc_t)rstat_reply);
if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT)
errx(1, "%s", clnt_sperrno(clnt_stat));
}
diff --git a/usr.bin/rusers/rusers.c b/usr.bin/rusers/rusers.c
index 413de53c304b..c23b79240fad 100644
--- a/usr.bin/rusers/rusers.c
+++ b/usr.bin/rusers/rusers.c
@@ -208,7 +208,7 @@ allhosts(void)
clnt_stat = clnt_broadcast(RUSERSPROG, RUSERSVERS_IDLE,
RUSERSPROC_NAMES, (xdrproc_t)xdr_void, NULL,
(xdrproc_t)xdr_utmpidlearr, (char *)&up,
- (resultproc_t)rusers_reply);
+ (clnt_broadcast_resultproc_t)rusers_reply);
if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT)
errx(1, "%s", clnt_sperrno(clnt_stat));
}
diff --git a/usr.bin/sockstat/main.c b/usr.bin/sockstat/main.c
index 32b1ac1a8d20..ea4449300866 100644
--- a/usr.bin/sockstat/main.c
+++ b/usr.bin/sockstat/main.c
@@ -928,6 +928,7 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
struct sockaddr_un *sun;
int error, off, port = 0;
char addrstr[NI_MAXHOST] = "";
+ bool needs_ipv6_brackets = false;
switch (ss->ss_family) {
case AF_INET:
@@ -938,6 +939,8 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
case AF_INET6:
if (IN6_IS_ADDR_UNSPECIFIED(&sstosin6(ss)->sin6_addr))
addrstr[0] = '*';
+ else
+ needs_ipv6_brackets = true;
port = ntohs(sstosin6(ss)->sin6_port);
break;
case AF_UNIX:
@@ -946,7 +949,7 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
if (is_xo_style_encoding) {
xo_emit("{:path/%.*s}", sun->sun_len - off,
sun->sun_path);
- return 0;
+ return (0);
}
return snprintf(buf, bufsize, "%.*s",
sun->sun_len - off, sun->sun_path);
@@ -962,6 +965,11 @@ formataddr(struct sockaddr_storage *ss, char *buf, size_t bufsize)
xo_emit("{:port/%d}", port);
return (0);
}
+ if (needs_ipv6_brackets) {
+ if (port == 0)
+ return (snprintf(buf, bufsize, "[%s]:*", addrstr));
+ return (snprintf(buf, bufsize, "[%s]:%d", addrstr, port));
+ }
if (port == 0)
return (snprintf(buf, bufsize, "%s:*", addrstr));
return (snprintf(buf, bufsize, "%s:%d", addrstr, port));
diff --git a/usr.bin/tar/tests/functional_test.sh b/usr.bin/tar/tests/functional_test.sh
index 39a73abd0a79..11f3cb6dd122 100755
--- a/usr.bin/tar/tests/functional_test.sh
+++ b/usr.bin/tar/tests/functional_test.sh
@@ -25,9 +25,9 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
-export BSDTAR=$(which tar)
SRCDIR=$(atf_get_srcdir)
TESTER="${SRCDIR}/bsdtar_test"
+export BSDTAR=$(which tar)
check()
{
@@ -41,7 +41,7 @@ atf_init_test_cases()
# Redirect stderr to stdout for the usage message because if you don't
# kyua list/kyua test will break:
# https://github.com/jmmv/kyua/issues/149
- testcases=$(${TESTER} -h 2>&1 | awk 'p != 0 && $1 ~ /^[0-9]+:/ { print $NF } /Available tests:/ { p=1 }')
+ testcases=$(${TESTER} -l 2>&1 | awk '/^ [0-9]+: / { print $2 }')
for testcase in ${testcases}; do
atf_test_case ${testcase}
eval "${testcase}_body() { check ${testcase}; }"
diff --git a/usr.bin/touch/tests/touch_test.sh b/usr.bin/touch/tests/touch_test.sh
index da39abef622e..811d74983020 100644
--- a/usr.bin/touch/tests/touch_test.sh
+++ b/usr.bin/touch/tests/touch_test.sh
@@ -12,6 +12,12 @@ atf_check_mtime()
atf_check -o inline:"$((mtime))\n" stat -f%m "$filename"
}
+atf_check_atime()
+{
+ local atime=$1 filename=$2
+ atf_check -o inline:"$((atime))\n" stat -f%a "$filename"
+}
+
atf_test_case touch_none
touch_none_head()
{
@@ -144,6 +150,61 @@ touch_nocreate_body()
atf_check -s exit:1 test -f bar
}
+atf_test_case touch_symlink_h_flag
+touch_symlink_h_flag_head()
+{
+ atf_set descr "Update time of symlink but not file pointed to"
+}
+touch_symlink_h_flag_body()
+{
+ atf_check touch -t 200406151337 pointed
+ atf_check ln -s pointed symlink
+ atf_check touch -t 197209071337 -h symlink
+ atf_check_mtime 1087306620 pointed
+ atf_check_mtime 84721020 symlink
+}
+
+atf_test_case touch_symlink_no_h_flag
+touch_symlink_no_h_flag_head()
+{
+ atf_set descr "Update time of file pointed to but not symlink"
+}
+touch_symlink_no_h_flag_body()
+{
+ atf_check touch -t 200406151337 pointed
+ atf_check ln -s pointed symlink
+ local orig_mtime=$(stat -f %m symlink)
+ atf_check touch -t 197209071337 symlink
+ atf_check_mtime 84721020 pointed
+ atf_check_mtime $orig_mtime symlink
+}
+
+atf_test_case touch_just_atime
+touch_just_atime_head()
+{
+ atf_set descr "Update just access time of file (-a)"
+}
+touch_just_atime_body()
+{
+ atf_check touch -t 200406151337 file
+ atf_check touch -at 197209071337 file
+ atf_check_mtime 1087306620 file
+ atf_check_atime 84721020 file
+}
+
+atf_test_case touch_just_mtime
+touch_just_mtime_head()
+{
+ atf_set descr "Update just modify time of file (-m)"
+}
+touch_just_mtime_body()
+{
+ atf_check touch -t 200406151337 file
+ atf_check touch -mt 197209071337 file
+ atf_check_mtime 84721020 file
+ atf_check_atime 1087306620 file
+}
+
atf_init_test_cases()
{
atf_add_test_case touch_none
@@ -153,5 +214,8 @@ atf_init_test_cases()
atf_add_test_case touch_relative
atf_add_test_case touch_copy
atf_add_test_case touch_nocreate
- # TODO: add test cases for -a, -h, -m
+ atf_add_test_case touch_symlink_h_flag
+ atf_add_test_case touch_symlink_no_h_flag
+ atf_add_test_case touch_just_atime
+ atf_add_test_case touch_just_mtime
}
diff --git a/usr.bin/touch/touch.c b/usr.bin/touch/touch.c
index 70257e320a60..2be2e369596c 100644
--- a/usr.bin/touch/touch.c
+++ b/usr.bin/touch/touch.c
@@ -163,19 +163,14 @@ main(int argc, char *argv[])
/* Create the file. */
fd = open(*argv,
O_WRONLY | O_CREAT, DEFFILEMODE);
- if (fd == -1) {
+ if (fd < 0 || fstat(fd, &sb) < 0) {
rval = 1;
warn("%s", *argv);
+ if (fd >= 0)
+ (void)close(fd);
continue;
}
- if (fstat(fd, &sb) < 0) {
- warn("%s", *argv);
- rval = 1;
- }
- if (close(fd) < 0) {
- warn("%s", *argv);
- rval = 1;
- }
+ (void)close(fd);
/* If using the current time, we're done. */
if (!timeset)
diff --git a/usr.bin/tr/tr.c b/usr.bin/tr/tr.c
index d31a51a73542..75b7cd8be7c0 100644
--- a/usr.bin/tr/tr.c
+++ b/usr.bin/tr/tr.c
@@ -242,6 +242,40 @@ main(int argc, char **argv)
break;
} while (s2.state == CCLASS_LOWER && s2.cnt > 1);
goto again;
+ } else if (s1.state == CCLASS &&
+ s2.state == CCLASS_UPPER &&
+ s1.cnt == 1 && s2.cnt == 1) {
+ do {
+ ch = towupper(s1.lastch);
+ cmap_add(map, s1.lastch, ch);
+ if (sflag && iswupper(ch))
+ cset_add(squeeze, ch);
+ if (!next(&s1))
+ goto endloop;
+ } while (s1.state == CCLASS && s1.cnt > 1);
+ /* skip upper set */
+ do {
+ if (!next(&s2))
+ break;
+ } while (s2.state == CCLASS_UPPER && s2.cnt > 1);
+ goto again;
+ } else if (s1.state == CCLASS &&
+ s2.state == CCLASS_LOWER &&
+ s1.cnt == 1 && s2.cnt == 1) {
+ do {
+ ch = towlower(s1.lastch);
+ cmap_add(map, s1.lastch, ch);
+ if (sflag && iswlower(ch))
+ cset_add(squeeze, ch);
+ if (!next(&s1))
+ goto endloop;
+ } while (s1.state == CCLASS && s1.cnt > 1);
+ /* skip lower set */
+ do {
+ if (!next(&s2))
+ break;
+ } while (s2.state == CCLASS_LOWER && s2.cnt > 1);
+ goto again;
} else {
cmap_add(map, s1.lastch, s2.lastch);
if (sflag)
diff --git a/usr.bin/unzip/tests/functional_test.sh b/usr.bin/unzip/tests/functional_test.sh
index e668453d8882..c6b25cfc2e7e 100755
--- a/usr.bin/unzip/tests/functional_test.sh
+++ b/usr.bin/unzip/tests/functional_test.sh
@@ -46,7 +46,7 @@ atf_init_test_cases()
# Redirect stderr to stdout for the usage message because if you don't
# kyua list/kyua test will break:
# https://github.com/jmmv/kyua/issues/149
- testcases=$(${TESTER} -h 2>&1 | awk 'p != 0 && $1 ~ /^[0-9]+:/ { print $NF } /Available tests:/ { p=1 }')
+ testcases=$(${TESTER} -l 2>&1 | awk '/^ [0-9]+: / { print $2 }')
for testcase in ${testcases}; do
atf_test_case ${testcase}
eval "${testcase}_body() { check ${testcase}; }"
diff --git a/usr.bin/vtfontcvt/vtfontcvt.c b/usr.bin/vtfontcvt/vtfontcvt.c
index 773072813d8a..1e388ef36276 100644
--- a/usr.bin/vtfontcvt/vtfontcvt.c
+++ b/usr.bin/vtfontcvt/vtfontcvt.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
* Copyright (c) 2009, 2014 The FreeBSD Foundation
*
* This software was developed by Ed Schouten under sponsorship from the
diff --git a/usr.bin/xinstall/tests/install_test.sh b/usr.bin/xinstall/tests/install_test.sh
index 0f1f93ab4c63..3cea648aa805 100755
--- a/usr.bin/xinstall/tests/install_test.sh
+++ b/usr.bin/xinstall/tests/install_test.sh
@@ -512,6 +512,42 @@ set_optional_exec_body()
atf_check test ! -x testfile
}
+atf_test_case metalog
+metalog_head() {
+ atf_set "descr" "Test metalog generation"
+}
+metalog_body() {
+ atf_check install -M metalog -D dst -m 0755 -d dst
+ echo ". type=dir mode=0755" >expect
+ atf_check install -M metalog -D dst -m 0705 -d dst/dir
+ echo "./dir type=dir mode=0705" >>expect
+ atf_check -o save:file echo "Hello, world!"
+ atf_check install -M metalog -D dst -m 0604 file dst/dir
+ echo "./dir/file type=file mode=0604 size=14" >>expect
+ atf_check install -M metalog -D dst -lrs dir/file dst/"li nk"
+ echo "./li\040nk type=link mode=0755 link=dir/file" >>expect
+ atf_check mtree -f expect -p dst
+ atf_check -o file:expect cat metalog
+}
+
+atf_test_case digest
+digest_head() {
+ atf_set "descr" "Compute digest while copying"
+}
+digest_body() {
+ atf_check mkdir src dst
+ atf_check -e ignore dd if=/dev/random of=src/file bs=1m count=1
+ for alg in md5 rmd160 sha1 sha256 sha512 ; do
+ rm -f dst/file digest metalog
+ atf_check -o save:digest $alg -q src/file
+ atf_check install -M metalog -D dst -h $alg -m 0644 src/file dst
+ echo -n "./file type=file mode=0644 size=1048576 $alg=" >expect
+ cat digest >>expect
+ atf_check cmp src/file dst/file
+ atf_check -o file:expect cat metalog
+ done
+}
+
atf_init_test_cases() {
atf_add_test_case copy_to_empty
atf_add_test_case copy_to_nonexistent
@@ -557,4 +593,6 @@ atf_init_test_cases() {
atf_add_test_case set_owner_group_mode
atf_add_test_case set_owner_group_mode_unpriv
atf_add_test_case set_optional_exec
+ atf_add_test_case metalog
+ atf_add_test_case digest
}
diff --git a/usr.bin/xinstall/xinstall.c b/usr.bin/xinstall/xinstall.c
index 28b546bc80c2..1aed8c1b24e4 100644
--- a/usr.bin/xinstall/xinstall.c
+++ b/usr.bin/xinstall/xinstall.c
@@ -140,7 +140,7 @@ static char *destdir, *digest, *fflags, *metafile, *tags;
static int compare(int, const char *, size_t, int, const char *, size_t,
char **);
-static char *copy(int, const char *, int, const char *, off_t);
+static char *copy(int, const char *, int, const char *);
static int create_tempfile(const char *, char *, size_t);
static char *quiet_mktemp(char *template);
static char *digest_file(const char *);
@@ -877,7 +877,7 @@ install(const char *from_name, const char *to_name, u_long fset, u_int flags)
}
if (!stripped) {
digestresult = copy(from_fd, from_name, to_fd,
- tempfile, from_sb.st_size);
+ tempfile);
}
}
}
@@ -1175,8 +1175,7 @@ create_tempfile(const char *path, char *temp, size_t tsize)
* copy from one file to another
*/
static char *
-copy(int from_fd, const char *from_name, int to_fd, const char *to_name,
- off_t size)
+copy(int from_fd, const char *from_name, int to_fd, const char *to_name)
{
static char *buf = NULL;
static size_t bufsize;
@@ -1198,8 +1197,8 @@ copy(int from_fd, const char *from_name, int to_fd, const char *to_name,
if (digesttype == DIGEST_NONE) {
do {
ret = copy_file_range(from_fd, NULL, to_fd, NULL,
- (size_t)size, 0);
- } while (ret > 0);
+ SSIZE_MAX, 0);
+ } while (ret > 0 || (ret < 0 && errno == EINTR));
if (ret == 0)
goto done;
if (errno != EINVAL) {
@@ -1227,28 +1226,29 @@ copy(int from_fd, const char *from_name, int to_fd, const char *to_name,
if (buf == NULL)
err(1, "Not enough memory");
}
- while ((nr = read(from_fd, buf, bufsize)) > 0) {
- if ((nw = write(to_fd, buf, nr)) != nr) {
+ for (;;) {
+ if ((nr = read(from_fd, buf, bufsize)) < 0) {
+ if (errno == EINTR)
+ continue;
serrno = errno;
(void)unlink(to_name);
- if (nw >= 0) {
- errx(EX_OSERR,
- "short write to %s: %jd bytes written, "
- "%jd bytes asked to write",
- to_name, (uintmax_t)nw,
- (uintmax_t)size);
- } else {
+ errno = serrno;
+ err(EX_OSERR, "%s", from_name);
+ }
+ if (nr <= 0)
+ break;
+ digest_update(&ctx, buf, nr);
+ while (nr > 0) {
+ if ((nw = write(to_fd, buf, nr)) < 0) {
+ if (errno == EINTR)
+ continue;
+ serrno = errno;
+ (void)unlink(to_name);
errno = serrno;
err(EX_OSERR, "%s", to_name);
}
+ nr -= nw;
}
- digest_update(&ctx, buf, nr);
- }
- if (nr != 0) {
- serrno = errno;
- (void)unlink(to_name);
- errno = serrno;
- err(EX_OSERR, "%s", from_name);
}
#ifndef BOOTSTRAP_XINSTALL
done:
diff --git a/usr.bin/yes/Makefile b/usr.bin/yes/Makefile
index b1d4075b5917..545c95d00624 100644
--- a/usr.bin/yes/Makefile
+++ b/usr.bin/yes/Makefile
@@ -1,3 +1,7 @@
+.include <src.opts.mk>
+
PROG= yes
+HAS_TESTS=
+SUBDIR.${MK_TESTS}= tests
.include <bsd.prog.mk>
diff --git a/usr.bin/yes/tests/Makefile b/usr.bin/yes/tests/Makefile
new file mode 100644
index 000000000000..874a1bc21751
--- /dev/null
+++ b/usr.bin/yes/tests/Makefile
@@ -0,0 +1,4 @@
+PACKAGE= tests
+ATF_TESTS_SH= yes_test
+
+.include <bsd.test.mk>
diff --git a/usr.bin/yes/tests/yes_test.sh b/usr.bin/yes/tests/yes_test.sh
new file mode 100644
index 000000000000..f4c04e186536
--- /dev/null
+++ b/usr.bin/yes/tests/yes_test.sh
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2026 Klara, Inc.
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+atf_test_case none
+none_head()
+{
+ atf_set "descr" "No arguments"
+}
+none_body()
+{
+ atf_check \
+ -o inline:"y\ny\ny\ny\ny\n" \
+ -x "yes | head -5"
+}
+
+atf_test_case one
+one_head()
+{
+ atf_set "descr" "One argument"
+}
+one_body()
+{
+ local y="Hello, world!"
+ atf_check \
+ -o inline:"${y}\n${y}\n${y}\n${y}\n${y}\n" \
+ -x "yes '${y}' | head -5"
+}
+
+atf_test_case multi
+multi_head()
+{
+ atf_set "descr" "Multiple arguments"
+}
+multi_body()
+{
+ set -- The Magic Words are Squeamish Ossifrage
+ local y="$*"
+ atf_check \
+ -o inline:"${y}\n${y}\n${y}\n${y}\n${y}\n" \
+ -x "yes $* | head -5"
+}
+
+atf_test_case argv
+argv_head()
+{
+ atf_set "descr" "Verify that argv is unmolested"
+}
+argv_body()
+{
+ yes y >/dev/null &
+ local pid=$!
+ atf_check -o inline:"yes y\n" ps -o args= $pid
+ kill $pid
+ wait
+}
+
+atf_test_case stdout
+stdout_head()
+{
+ atf_set descr "Error writing to stdout"
+}
+stdout_body()
+{
+ (
+ trap "" PIPE
+ # Give true(1) some time to exit.
+ sleep 1
+ yes 2>stderr
+ echo $? >result
+ ) | true
+ atf_check -o inline:"1\n" cat result
+ atf_check -o match:"stdout" cat stderr
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case none
+ atf_add_test_case one
+ atf_add_test_case multi
+ atf_add_test_case argv
+ atf_add_test_case stdout
+}
diff --git a/usr.bin/yes/yes.1 b/usr.bin/yes/yes.1
index 8ed8beab0d28..689031345dc3 100644
--- a/usr.bin/yes/yes.1
+++ b/usr.bin/yes/yes.1
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd June 4, 2014
+.Dd March 2, 2026
.Dt YES 1
.Os
.Sh NAME
@@ -33,7 +33,7 @@
.Nd be repetitively affirmative
.Sh SYNOPSIS
.Nm
-.Op Ar expletive
+.Op Ar expletive ...
.Sh DESCRIPTION
The
.Nm
@@ -42,6 +42,8 @@ utility outputs
or, by default,
.Dq y ,
forever.
+If multiple arguments are given, they are concatenated into a single
+space-separated string.
.Sh SEE ALSO
.Xr jot 1 ,
.Xr seq 1
diff --git a/usr.bin/yes/yes.c b/usr.bin/yes/yes.c
index d9e896b6ea27..86022c82f453 100644
--- a/usr.bin/yes/yes.c
+++ b/usr.bin/yes/yes.c
@@ -31,44 +31,76 @@
#include <capsicum_helpers.h>
#include <err.h>
+#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+/*
+ * Default expletive
+ */
+#define EXP "y\n"
+#define EXPLEN strlen(EXP)
+
+/*
+ * Optimum and maximum buffer size. The optimum is just a little less
+ * than the default value of kern.ipc.pipe_mindirect; writing more than
+ * that is significantly slower, but we want to get as close as possible
+ * to minimize the number of system calls. The maximum is enough for a
+ * maximal command line plus a newline and terminating NUL.
+ */
+#define OPTBUF 8190
+#define MAXBUF (ARG_MAX + 2)
+
int
main(int argc, char **argv)
{
- char buf[8192];
- char y[2] = { 'y', '\n' };
- char * exp = y;
- size_t buflen = 0;
- size_t explen = sizeof(y);
- size_t more;
- ssize_t ret;
+ static char buf[MAXBUF] = EXP;
+ char *end = buf + sizeof(buf), *exp, *pos = buf + EXPLEN;
+ size_t buflen, explen = EXPLEN;
+ ssize_t wlen = 0;
if (caph_limit_stdio() < 0 || caph_enter() < 0)
err(1, "capsicum");
- if (argc > 1) {
- exp = argv[1];
- explen = strlen(exp) + 1;
- exp[explen - 1] = '\n';
- }
+ argc -= 1;
+ argv += 1;
- if (explen <= sizeof(buf)) {
- while (buflen < sizeof(buf) - explen) {
- memcpy(buf + buflen, exp, explen);
- buflen += explen;
+ /* Assemble the expletive */
+ if (argc > 0) {
+ /* Copy positional arguments into expletive buffer */
+ for (pos = buf, end = buf + sizeof(buf);
+ argc > 0 && pos < end; argc--, argv++) {
+ /* Separate with spaces */
+ if (pos > buf)
+ *pos++ = ' ';
+ exp = *argv;
+ while (*exp != '\0' && pos < end)
+ *pos++ = *exp++;
}
- exp = buf;
- explen = buflen;
+ /* This should not be possible, but check anyway */
+ if (pos > end - 2)
+ pos = end - 2;
+ *pos++ = '\n';
+ explen = pos - buf;
}
- more = explen;
- while ((ret = write(STDOUT_FILENO, exp + (explen - more), more)) > 0)
- if ((more -= ret) == 0)
- more = explen;
+ /*
+ * Double until we're past OPTBUF, then reduce buflen to exactly
+ * OPTBUF. It doesn't matter if that's not a multiple of explen;
+ * the modulo operation in the write loop will take care of that.
+ */
+ for (buflen = explen; buflen < OPTBUF; pos += buflen, buflen += buflen)
+ memcpy(pos, buf, buflen);
+ if (explen < OPTBUF && buflen > OPTBUF)
+ buflen = OPTBUF;
+ /* Dump it to stdout */
+ end = (pos = buf) + buflen;
+ do {
+ pos = buf + (pos - buf + wlen) % explen;
+ wlen = write(STDOUT_FILENO, pos, end - pos);
+ } while (wlen > 0);
err(1, "stdout");
/*NOTREACHED*/
}