aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ObsoleteFiles.inc3
-rw-r--r--contrib/atf/.cirrus.yml26
-rw-r--r--contrib/atf/.gitignore25
-rw-r--r--contrib/atf/.travis.yml25
-rw-r--r--contrib/atf/FREEBSD-Xlist2
-rw-r--r--contrib/atf/NEWS200
-rw-r--r--contrib/atf/README37
-rw-r--r--contrib/atf/README.md43
-rw-r--r--contrib/atf/atf-c++/atf-c++.34
-rw-r--r--contrib/atf/atf-c++/check.cpp3
-rw-r--r--contrib/atf/atf-c++/check.hpp3
-rw-r--r--contrib/atf/atf-c++/detail/Kyuafile1
-rw-r--r--contrib/atf/atf-c++/detail/application.cpp16
-rw-r--r--contrib/atf/atf-c++/detail/application.hpp1
-rw-r--r--contrib/atf/atf-c++/detail/auto_array.hpp175
-rw-r--r--contrib/atf/atf-c++/detail/auto_array_test.cpp302
-rw-r--r--contrib/atf/atf-c++/detail/fs.cpp1
-rw-r--r--contrib/atf/atf-c++/detail/process.cpp22
-rw-r--r--contrib/atf/atf-c++/detail/process.hpp3
-rw-r--r--contrib/atf/atf-c++/detail/process_test.cpp32
-rw-r--r--contrib/atf/atf-c++/detail/test_helpers.hpp4
-rw-r--r--contrib/atf/atf-c++/detail/text.cpp8
-rw-r--r--contrib/atf/atf-c++/detail/text.hpp8
-rw-r--r--contrib/atf/atf-c++/detail/text_test.cpp21
-rw-r--r--contrib/atf/atf-c++/tests.cpp48
-rw-r--r--contrib/atf/atf-c++/tests_test.cpp4
-rw-r--r--contrib/atf/atf-c/.gitignore1
-rw-r--r--contrib/atf/atf-c/atf-c.322
-rw-r--r--contrib/atf/atf-c/build.c2
-rw-r--r--contrib/atf/atf-c/check.c1
-rw-r--r--contrib/atf/atf-c/defs.h.in1
-rw-r--r--contrib/atf/atf-c/detail/dynstr.c35
-rw-r--r--contrib/atf/atf-c/detail/dynstr_test.c21
-rw-r--r--contrib/atf/atf-c/detail/env.c41
-rw-r--r--contrib/atf/atf-c/detail/fs.c57
-rw-r--r--contrib/atf/atf-c/detail/fs_test.c11
-rw-r--r--contrib/atf/atf-c/detail/list.c5
-rw-r--r--contrib/atf/atf-c/detail/map.c22
-rw-r--r--contrib/atf/atf-c/detail/map_test.c1
-rw-r--r--contrib/atf/atf-c/detail/process.c59
-rw-r--r--contrib/atf/atf-c/detail/process.h3
-rw-r--r--contrib/atf/atf-c/detail/process_test.c57
-rw-r--r--contrib/atf/atf-c/detail/sanity_test.c9
-rw-r--r--contrib/atf/atf-c/detail/text.c1
-rw-r--r--contrib/atf/atf-c/detail/tp_main.c59
-rw-r--r--contrib/atf/atf-c/error.c10
-rw-r--r--contrib/atf/atf-c/macros.h8
-rw-r--r--contrib/atf/atf-c/tc.c71
-rw-r--r--contrib/atf/atf-c/tc.h2
-rw-r--r--contrib/atf/atf-c/tc_test.c86
-rw-r--r--contrib/atf/atf-c/tp.c3
-rw-r--r--contrib/atf/atf-c/tp.h2
-rw-r--r--contrib/atf/atf-c/tp_test.c1
-rw-r--r--contrib/atf/atf-c/utils.c72
-rw-r--r--contrib/atf/atf-c/utils.h1
-rw-r--r--contrib/atf/atf-sh/.gitignore2
-rw-r--r--contrib/atf/atf-sh/Kyuafile1
-rw-r--r--contrib/atf/atf-sh/Kyuafile.in11
-rw-r--r--contrib/atf/atf-sh/atf-check.142
-rw-r--r--contrib/atf/atf-sh/atf-check.cpp67
-rw-r--r--contrib/atf/atf-sh/atf-check_test.sh4
-rw-r--r--contrib/atf/atf-sh/atf-sh.32
-rw-r--r--contrib/atf/atf-sh/atf-sh.cpp52
-rw-r--r--contrib/atf/atf-sh/integration_test.sh19
-rw-r--r--contrib/atf/atf-sh/kmod_test.sh55
-rw-r--r--contrib/atf/atf-sh/libatf-sh.subr40
-rw-r--r--contrib/atf/config.h132
-rw-r--r--contrib/atf/doc/.gitignore1
-rw-r--r--contrib/atf/doc/atf-test-case.7 (renamed from contrib/atf/doc/atf-test-case.4)14
-rw-r--r--contrib/atf/test-programs/srcdir_test.sh10
-rw-r--r--lib/atf/Makefile.inc2
-rw-r--r--libexec/atf/Makefile.inc2
-rw-r--r--share/doc/atf/Makefile2
-rw-r--r--share/man/man4/Makefile8
-rw-r--r--share/man/man7/Makefile1
75 files changed, 939 insertions, 1209 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 2550c5ab3d12..e81cb57152ae 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -55,6 +55,9 @@
OLD_FILES+=usr/bin/lesskey
OLD_FILES+=usr/share/man/man1/lesskey.1.gz
+# 20260921: atf-0.26 release
+OLD_FILES+=usr/share/doc/atf/README
+
# 20260813: lib9p.so becomes a private library
OLD_LIBS+=usr/lib/lib9p.so.1
diff --git a/contrib/atf/.cirrus.yml b/contrib/atf/.cirrus.yml
deleted file mode 100644
index fd9b6e4a47df..000000000000
--- a/contrib/atf/.cirrus.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-env:
- CIRRUS_CLONE_DEPTH: 1
- ARCH: amd64
-
-task:
- matrix:
- - name: 13.0-CURRENT
- freebsd_instance:
- image_family: freebsd-13-0-snap
- - name: 12.2-STABLE
- freebsd_instance:
- image_family: freebsd-12-2-snap
- - name: 12.1-RELEASE
- freebsd_instance:
- image_family: freebsd-12-1
- install_script:
- - sed -i.bak -e 's,pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly,pkg+http://pkg.FreeBSD.org/\${ABI}/latest,' /etc/pkg/FreeBSD.conf
- - ASSUME_ALWAYS_YES=yes pkg bootstrap -f
- - pkg install -y autoconf automake libtool kyua
- script:
- - env JUNIT_OUTPUT=$(pwd)/test-results.xml ./admin/travis-build.sh
- always:
- junit_artifacts:
- path: "test-results.xml"
- type: text/xml
- format: junit
diff --git a/contrib/atf/.gitignore b/contrib/atf/.gitignore
deleted file mode 100644
index 396785ce2052..000000000000
--- a/contrib/atf/.gitignore
+++ /dev/null
@@ -1,25 +0,0 @@
-*.la
-*.lo
-*.o
-*.pc
-*_helper
-*_helpers
-*_test
-.deps
-.dirstamp
-.libs
-
-Makefile
-Makefile.in
-aclocal.m4
-autom4te.cache
-config.h
-config.h.in
-config.h.in~
-config.log
-config.status
-configure
-installcheck.log
-libtool
-stamp-h1
-testsuite.log
diff --git a/contrib/atf/.travis.yml b/contrib/atf/.travis.yml
deleted file mode 100644
index 1949aae54468..000000000000
--- a/contrib/atf/.travis.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-language: cpp
-
-compiler:
- - gcc
- - clang
-
-before_install:
- - ./admin/travis-install-deps.sh
-
-env:
- - ARCH=amd64 AS_ROOT=no
- - ARCH=amd64 AS_ROOT=yes
- - ARCH=i386 AS_ROOT=no
-
-matrix:
- exclude:
- - compiler: clang
- env: ARCH=i386 AS_ROOT=no
-
-script:
- - ./admin/travis-build.sh
-
-notifications:
- email:
- - atf-log@googlegroups.com
diff --git a/contrib/atf/FREEBSD-Xlist b/contrib/atf/FREEBSD-Xlist
index 05ea871eb95c..06fef93a4024 100644
--- a/contrib/atf/FREEBSD-Xlist
+++ b/contrib/atf/FREEBSD-Xlist
@@ -2,7 +2,7 @@
*/Makefile*
*/*.m4
*/*.pc.in
-INSTALL
+INSTALL.md
Makefile*
aclocal.m4
admin/
diff --git a/contrib/atf/NEWS b/contrib/atf/NEWS
index 671ee81ff6ff..e1c9e5f512f5 100644
--- a/contrib/atf/NEWS
+++ b/contrib/atf/NEWS
@@ -1,26 +1,140 @@
-Major changes between releases Automated Testing Framework
-===========================================================================
+# Major changes between releases
+
+## Changes in version 0.26
+
+Released on 2026/09/22.
+
+### Developer Workflow Changes
+
+* #189: Automate uploading release assets
+* #190: INSTALL.md: sync content with version from lutok
+* #191: [CI] Minor tweaks
+
+### Feature Enhancements
+
+* #192: Add kmod support on FreeBSD
+
+**Full Changelog**: https://github.com/freebsd/atf/compare/atf-0.25...atf-0.26
+
+## Changes in version 0.25
+
+Released on 2026/09/02.
+
+### Bugfixes
+* #187: Fix the build on NetBSD by renaming a variable added in version 0.24.
+
+### Developer Workflow Changes
+* #185: The version of LLVM used in macOS runners was bumped from 19 to 20
+
+**Full Changelog**: https://github.com/freebsd/atf/compare/atf-0.24...atf-0.25
+
+## Changes in version 0.24
+
+Released on August, 17, 2026
+
+### Major Changes
+* This version of ATF requires C++-20 to build/function.
+* This version of ATF focused heavily on correctness and memory management
+ issues discussed in #77. While most of the issues are believed to be resolved,
+ some issues may still remain.
+* The `atf::text::duplicate(..)` API and tests were removed.
+
+### Feature Enhancements
+* Issue #105: Widen our process status capabilties
+
+### Docs
+* Issue #107: Clarify the semantics of ATF_{CHECK,REQUIRE}_ERRNO()
+* Issue #124: atf-check.1: Add missing -r flag to synopsis
+* Issue #127: atf-c.3: Fix test case addition in ATF_TP_ADD_TCS synopsis example
+
+### Developer Workflow Changes
+* GitHub Actions support was added.
+* Cirrus CI support was removed.
+* FreeBSD vmactions CI support was added.
+* ASAN/LSAN/UBSAN support was added for Linux and macOS.
+* (Initial) runtime code coverage support was added.
+* (Initial) pre-commit support was added.
+
+**Full Changelog**: https://github.com/freebsd/atf/compare/atf-0.23...atf-0.24
+
+## Changes in version 0.23
+
+Released on March, 29, 2025
-Changes in version 0.22
-***********************
+* Issue #101: fix release tarballs by using `make dist` instead of
+ alternative ad hoc method.
-STILL UNDER DEVELOPMENT; NOT RELEASED YET.
-DON'T FORGET TO BUMP THE -version-info PRE-RELEASE IF NECESSARY!
+* Issue #76: `atf_check`: fix `std::length_error` thrown from `temp_file`.
+
+* #87: Update documentation/build files to point to FreeBSD repo/mailing lists.
+
+* #86: Improve diagnostics when paths cannot be opened
+
+* #85: various build-related changes. Highlights:
+ * Remove leftover references of `auto_array` (bugfix).
+ * Remove the `atf-*-api` manpages (enhancement).
+ * Require -std=C++14 with ATF (enhancement).
+ * Expose `WCOREDUMP(..)` on platforms that support it (bugfix).
+ * Add `__attribute__((nonnull))` support (enhancement).
+ * Restore `AC_PROG_CPP` (bugfix).
+
+### General fixes
+
+* Fix various style issues which were blocking `make dist` from completing
+ cleanly.
+
+* Fix `atf_utils_file_exists` declaration in atf-c(3).
+
+* Fix various memory leaks and logic errors.
+
+* `atf-test-case(4)`: update reference to the "descr" metadata property so it's
+ marked Optional.
+
+* `atf-check.cpp`: remove unnecessary data copy in `temp_file`.
+
+## Changes in version 0.22
+
+Released on November 25th, 2024.
* Issue #23: Fix double-free triggered by atf_map_insert in low memory
scenarios, caused by an overlook in the atf_list code.
-* Issue #29: Fixed various typos and formatting errors in manual pages.
-
* Issue #31: Added require.progs metadata properties to the tests that
need a compiler to run.
* Added the atf_check_not_equal function to atf-sh to check for
unequal values.
+* Add `-r timeout` flag to `atf-check`.
+
+* Open results files before executing tests to fix an issue ATF tests that
+ adjust the processes' Capsicum rights as part of the testcase(s)
+ executed.
+
+* Add Cirrus CI integration for FreeBSD CI/CD support.
+
+* Address compilation issues on OpenSolaris distributions.
+
+* Replace `auto_array` with `std::vector` (fixes modern C++ compliance).
+
+* Replace `auto_ptr` with `std::unique_ptr` (fixes modern C++ compliance).
+
+* Update autotools idioms and requirements. The minimum required version of
+ autoconf is now 2.68.
+
+* Modify `ATF_CHECK*` and `ATF_REQUIRE*` macros to avoid double
+ evaluation/allow the gcc toolchain to detect accidental single
+ assignment typos.
+
+* Always define CPP to fix use of ATF_BUILD_CPP when the user did not
+ define CPP when invoking the configure script.
+
+### General fixes
+
+* Fix various typos and formatting errors in manual pages and markdown
+ documents.
-Changes in version 0.21
-***********************
+## Changes in version 0.21
Released on October 23rd, 2014.
@@ -76,8 +190,7 @@ Released on October 23rd, 2014.
* Issue #19: Removed stale references to atf-config and atf-run.
-Changes in version 0.20
-***********************
+## Changes in version 0.20
Experimental version released on February 7th, 2014.
@@ -92,8 +205,7 @@ the 'tools' directory for your own consumption.
that ships with FreeBSD 11.0-CURRENT.
-Changes in version 0.19
-***********************
+## Changes in version 0.19
Experimental version released on February 7th, 2014.
@@ -112,7 +224,7 @@ does not depend on any internal details of atf-c++ any longer.
* Project hosting moved from Google Code (as a subproject of Kyua) to
GitHub (as a first-class project). The main reason for the change is
the suppression of binary downloads in Google Code on Jan 15th, 2014.
- See https://github.com/jmmv/atf/
+ See https://github.com/freebsd/atf/
* Removed builtin help from atf-sh(1) and atf-check(1) for simplicity
reasons. In other words, their -h option is gone.
@@ -124,8 +236,7 @@ does not depend on any internal details of atf-c++ any longer.
atf-c++ would break the stale tools.
-Changes in version 0.18
-***********************
+## Changes in version 0.18
Experimental version released on November 16th, 2013.
@@ -142,8 +253,7 @@ Experimental version released on November 16th, 2013.
* NetBSD PR bin/48285: Fixed atf_check examples in atf-sh-api(3).
-Changes in version 0.17
-***********************
+## Changes in version 0.17
Experimental version released on February 14th, 2013.
@@ -176,8 +286,7 @@ Experimental version released on February 14th, 2013.
cases from breaking xsltproc later.
-Changes in version 0.16
-***********************
+## Changes in version 0.16
Experimental version released on July 10th, 2012.
@@ -211,8 +320,7 @@ Experimental version released on July 10th, 2012.
lives in a subcomponent of the Kyua project.
-Changes in version 0.15
-***********************
+## Changes in version 0.15
Experimental version released on January 16th, 2012.
@@ -248,8 +356,7 @@ Experimental version released on January 16th, 2012.
mangle our report.
-Changes in version 0.14
-***********************
+## Changes in version 0.14
Experimental version released on June 14th, 2011.
@@ -277,8 +384,7 @@ Experimental version released on June 14th, 2011.
case to run.
-Changes in version 0.13
-***********************
+## Changes in version 0.13
Experimental version released on March 31st, 2011.
@@ -323,8 +429,7 @@ The changes in this release are:
instead of just listing them as having 0 test cases.
-Changes in version 0.12
-***********************
+## Changes in version 0.12
Experimental version released on November 7th, 2010.
@@ -359,8 +464,7 @@ Experimental version released on November 7th, 2010.
general, not be blindly run as root in the first place.
-Changes in version 0.11
-***********************
+## Changes in version 0.11
Experimental version released on October 20th, 2010.
@@ -382,8 +486,7 @@ Experimental version released on October 20th, 2010.
* Fixed the XSTL and CSS stylesheets to support expected failures.
-Changes in version 0.10
-***********************
+## Changes in version 0.10
Experimental version released on July 2nd, 2010.
@@ -410,7 +513,7 @@ Miscellaneous features
take the expected exception as the first argument and the statement to
execute as the second argument.
-Changes in atf-check
+### Changes in atf-check
* Changed atf-check to support negating the status and output checks by
prefixing them with not- and added support to specify multiple checkers
@@ -463,8 +566,7 @@ Code simplifications and cleanups
easier to maintain.
-Changes in version 0.9
-**********************
+## Changes in version 0.9
Experimental version released on June 3rd, 2010.
@@ -491,8 +593,7 @@ Experimental version released on June 3rd, 2010.
ATF_TEST_CASE_WITHOUT_HEAD.
-Changes in version 0.8
-**********************
+## Changes in version 0.8
Experimental version released on May 7th, 2010.
@@ -541,8 +642,7 @@ Experimental version released on May 7th, 2010.
name of their own.
-Changes in version 0.7
-**********************
+## Changes in version 0.7
Experimental version released on December 22nd, 2009.
@@ -571,8 +671,7 @@ Experimental version released on December 22nd, 2009.
* Fixed many memory and object leaks.
-Changes in version 0.6
-**********************
+## Changes in version 0.6
Experimental version released on January 18th, 2009.
@@ -605,8 +704,7 @@ Experimental version released on January 18th, 2009.
_STREQ_MSG.
-Changes in version 0.5
-**********************
+## Changes in version 0.5
Experimental version released on May 1st, 2008.
@@ -632,8 +730,7 @@ Experimental version released on May 1st, 2008.
executed multiple times to comply with the user's requests.
-Changes in version 0.4
-**********************
+## Changes in version 0.4
Experimental version released on February 4th, 2008.
@@ -665,8 +762,7 @@ Experimental version released on February 4th, 2008.
were likely affected too.
-Changes in version 0.3
-**********************
+## Changes in version 0.3
Experimental version released on November 11th, 2007.
@@ -699,8 +795,7 @@ Experimental version released on November 11th, 2007.
incomplete.
-Changes in version 0.2
-**********************
+## Changes in version 0.2
Experimental version released on September 20th, 2007.
@@ -731,8 +826,7 @@ Experimental version released on September 20th, 2007.
* Multiple bug fixes and improvements all around.
-Changes in version 0.1
-**********************
+## Changes in version 0.1
Experimental version released on August 20th, 2007.
@@ -741,4 +835,4 @@ Experimental version released on August 20th, 2007.
===========================================================================
-vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2
+# vim: syntax=markdown:textwidth=75:expandtab:shiftwidth=2:softtabstop=2
diff --git a/contrib/atf/README b/contrib/atf/README
deleted file mode 100644
index d3b03edb9419..000000000000
--- a/contrib/atf/README
+++ /dev/null
@@ -1,37 +0,0 @@
-Introductory information Automated Testing Framework
-===========================================================================
-
-
-Introduction
-************
-
-The Automated Testing Framework (ATF) is a collection of libraries to
-implement test programs in a variety of languages. At the moment, ATF
-offers C, C++ and POSIX shell bindings with which to implement tests.
-These bindings all offer a similar set of functionality and any test
-program written with them exposes a consistent user interface.
-
-ATF-based test programs rely on a separate runtime engine to execute them.
-The runtime engine is in charge of isolating the test programs from the
-rest of the system to ensure that their results are deterministic and that
-they cannot affect the running system. The runtime engine is also
-responsible for gathering the results of all tests and composing reports.
-The current runtime of choice is Kyua.
-
-
-Other documents
-***************
-
-* AUTHORS: List of authors and contributors for this project.
-
-* COPYING: License information.
-
-* INSTALL: Compilation and installation instructions. These is not the
- standard document shipped with many packages, so be sure to read it for
- things that are specific to ATF's build.
-
-* NEWS: List of major changes between formal, published releases.
-
-
-===========================================================================
-vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2
diff --git a/contrib/atf/README.md b/contrib/atf/README.md
index d245552f35c9..0513546fc7cc 100644
--- a/contrib/atf/README.md
+++ b/contrib/atf/README.md
@@ -12,36 +12,57 @@ interface** to allow both humans and automation to run the tests.
ATF-based test programs **rely on an execution engine** to be run and
this execution engine is *not* shipped with ATF.
-**[Kyua](https://github.com/jmmv/kyua/) is the engine of choice.**
+**[Kyua](https://github.com/freebsd/kyua/) is the engine of choice.**
## Download
Formal releases for source files are available for download from GitHub:
-* [atf 0.20](../../releases/tag/atf-0.20), released on February 7th, 2014.
+* [atf 0.25](../../releases/tag/atf-0.25), released on September 2nd, 2026.
## Installation
You are encouraged to install binary packages for your operating system
wherever available:
-* Fedora 20 and above: install the `atf` package with `yum install atf`.
-
* FreeBSD 10.0 and above: install the `atf` package with `pkg install atf`.
* NetBSD with pkgsrc: install the `pkgsrc/devel/atf` package.
* OpenBSD: install the `devel/atf` package with `pkg_add atf`.
+* Ubuntu: install the `libatf-dev` and `atf-sh` packages with
+ `apt install libatf-dev atf-sh`.
+
Should you want to build and install ATF from the source tree provided
-here, follow the instructions in the [INSTALL file](INSTALL).
+here, follow the instructions in the [INSTALL file](INSTALL.md).
+
+## More Reading
+
+* AUTHORS: List of authors and contributors for this project.
+
+* COPYING: License information.
+
+* INSTALL.md: Compilation and installation instructions. These is not the
+ standard document shipped with many packages, so be sure to read it for
+ things that are specific to ATF's build.
+
+* NEWS.md: List of major changes between formal, published releases.
+
+## Other documents
+
+* `AUTHORS`: List of authors and contributors for this project.
+
+* `COPYING`: License information.
+
+* `INSTALL.md`: Compilation and installation instructions. These is not the
+ standard document shipped with many packages, so be sure to read it for
+ things that are specific to ATF's build.
+
+* `NEWS.md`: List of major changes between formal, published releases.
## Support
Please use the
-[atf-discuss mailing list](https://groups.google.com/forum/#!forum/atf-discuss)
-for any support inquiries related to `atf-c`, `atf-c++` or `atf-sh`.
-
-If you have any questions on Kyua proper, please use the
-[kyua-discuss mailing list](https://groups.google.com/forum/#!forum/kyua-discuss)
-instead.
+[FreeBSD-testing@FreeBSD.org](mailto:FreeBSD-testing@FreeBSD.org) mailing list
+for any support inquiries related to `atf-c`, `atf-c++`, `atf-sh`, or `kyua`.
diff --git a/contrib/atf/atf-c++/atf-c++.3 b/contrib/atf/atf-c++/atf-c++.3
index bb83e6214622..2254d481efff 100644
--- a/contrib/atf/atf-c++/atf-c++.3
+++ b/contrib/atf/atf-c++/atf-c++.3
@@ -22,7 +22,7 @@
.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.Dd May 11, 2025
+.Dd October 13, 2014
.Dt ATF-C++ 3
.Os
.Sh NAME
@@ -285,6 +285,8 @@ additional kernel modules in the test case's body by using the
.Fn require_kmod
function, which takes the name of a single module.
If it is not found, the test case will be automatically skipped.
+This feature is only available on
+.Fx .
.Ss Requiring programs
Aside from the
.Va require.progs
diff --git a/contrib/atf/atf-c++/check.cpp b/contrib/atf/atf-c++/check.cpp
index 5d8580023a15..78da33fa9620 100644
--- a/contrib/atf/atf-c++/check.cpp
+++ b/contrib/atf/atf-c++/check.cpp
@@ -150,5 +150,6 @@ impl::exec(const atf::process::argv_array& argva)
if (atf_is_error(err))
throw_atf_error(err);
- return std::unique_ptr< impl::check_result >(new impl::check_result(&result));
+ return std::unique_ptr< impl::check_result >(
+ new impl::check_result(&result));
}
diff --git a/contrib/atf/atf-c++/check.hpp b/contrib/atf/atf-c++/check.hpp
index 4d7f079d1ac1..bcf9cb647f29 100644
--- a/contrib/atf/atf-c++/check.hpp
+++ b/contrib/atf/atf-c++/check.hpp
@@ -71,7 +71,8 @@ class check_result {
check_result(const atf_check_result_t* result);
friend check_result test_constructor(const char* const*);
- friend std::unique_ptr< check_result > exec(const atf::process::argv_array&);
+ friend std::unique_ptr< check_result >
+ exec(const atf::process::argv_array&);
public:
//!
diff --git a/contrib/atf/atf-c++/detail/Kyuafile b/contrib/atf/atf-c++/detail/Kyuafile
index fc799e64df69..425595cef644 100644
--- a/contrib/atf/atf-c++/detail/Kyuafile
+++ b/contrib/atf/atf-c++/detail/Kyuafile
@@ -3,7 +3,6 @@ syntax("kyuafile", 1)
test_suite("atf")
atf_test_program{name="application_test"}
-atf_test_program{name="auto_array_test"}
atf_test_program{name="env_test"}
atf_test_program{name="exceptions_test"}
atf_test_program{name="fs_test"}
diff --git a/contrib/atf/atf-c++/detail/application.cpp b/contrib/atf/atf-c++/detail/application.cpp
index 37086eb3ae8c..3eeb8f966cf9 100644
--- a/contrib/atf/atf-c++/detail/application.cpp
+++ b/contrib/atf/atf-c++/detail/application.cpp
@@ -37,6 +37,7 @@ extern "C" {
#include <cstdio>
#include <cstdlib>
#include <cstring>
+#include <filesystem>
#include <iostream>
extern "C" {
@@ -205,19 +206,8 @@ impl::app::run(int argc, char* const* argv)
m_argc = argc;
m_argv = argv;
- m_argv0 = m_argv[0];
-
- m_prog_name = std::strrchr(m_argv[0], '/');
- if (m_prog_name == NULL)
- m_prog_name = m_argv[0];
- else
- m_prog_name++;
-
- // Libtool workaround: if running from within the source tree (binaries
- // that are not installed yet), skip the "lt-" prefix added to files in
- // the ".libs" directory to show the real (not temporary) name.
- if (std::strncmp(m_prog_name, "lt-", 3) == 0)
- m_prog_name += 3;
+ auto m_prog_filename = std::filesystem::path(m_argv[0]).filename();
+ m_prog_name = m_prog_filename.c_str();
const std::string bug =
std::string("This is probably a bug in ") + m_prog_name +
diff --git a/contrib/atf/atf-c++/detail/application.hpp b/contrib/atf/atf-c++/detail/application.hpp
index cdb4073ad807..ad068467ac3a 100644
--- a/contrib/atf/atf-c++/detail/application.hpp
+++ b/contrib/atf/atf-c++/detail/application.hpp
@@ -81,7 +81,6 @@ protected:
int m_argc;
char* const* m_argv;
- const char* m_argv0;
const char* m_prog_name;
std::string m_description;
std::string m_manpage;
diff --git a/contrib/atf/atf-c++/detail/auto_array.hpp b/contrib/atf/atf-c++/detail/auto_array.hpp
deleted file mode 100644
index b434a5808235..000000000000
--- a/contrib/atf/atf-c++/detail/auto_array.hpp
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright (c) 2007 The NetBSD Foundation, Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
-// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#if !defined(ATF_CXX_DETAIL_AUTO_ARRAY_HPP)
-#define ATF_CXX_DETAIL_AUTO_ARRAY_HPP
-
-#include <cstddef>
-
-namespace atf {
-
-// ------------------------------------------------------------------------
-// The "auto_array" class.
-// ------------------------------------------------------------------------
-
-template< class T >
-struct auto_array_ref {
- T* m_ptr;
-
- explicit auto_array_ref(T*);
-};
-
-template< class T >
-auto_array_ref< T >::auto_array_ref(T* ptr) :
- m_ptr(ptr)
-{
-}
-
-template< class T >
-class auto_array {
- T* m_ptr;
-
-public:
- auto_array(T* = NULL) throw();
- auto_array(auto_array< T >&) throw();
- auto_array(auto_array_ref< T >) throw();
- ~auto_array(void) throw();
-
- T* get(void) throw();
- const T* get(void) const throw();
- T* release(void) throw();
- void reset(T* = NULL) throw();
-
- auto_array< T >& operator=(auto_array< T >&) throw();
- auto_array< T >& operator=(auto_array_ref< T >) throw();
-
- T& operator[](int) throw();
- operator auto_array_ref< T >(void) throw();
-};
-
-template< class T >
-auto_array< T >::auto_array(T* ptr)
- throw() :
- m_ptr(ptr)
-{
-}
-
-template< class T >
-auto_array< T >::auto_array(auto_array< T >& ptr)
- throw() :
- m_ptr(ptr.release())
-{
-}
-
-template< class T >
-auto_array< T >::auto_array(auto_array_ref< T > ref)
- throw() :
- m_ptr(ref.m_ptr)
-{
-}
-
-template< class T >
-auto_array< T >::~auto_array(void)
- throw()
-{
- if (m_ptr != NULL)
- delete [] m_ptr;
-}
-
-template< class T >
-T*
-auto_array< T >::get(void)
- throw()
-{
- return m_ptr;
-}
-
-template< class T >
-const T*
-auto_array< T >::get(void)
- const throw()
-{
- return m_ptr;
-}
-
-template< class T >
-T*
-auto_array< T >::release(void)
- throw()
-{
- T* ptr = m_ptr;
- m_ptr = NULL;
- return ptr;
-}
-
-template< class T >
-void
-auto_array< T >::reset(T* ptr)
- throw()
-{
- if (m_ptr != NULL)
- delete [] m_ptr;
- m_ptr = ptr;
-}
-
-template< class T >
-auto_array< T >&
-auto_array< T >::operator=(auto_array< T >& ptr)
- throw()
-{
- reset(ptr.release());
- return *this;
-}
-
-template< class T >
-auto_array< T >&
-auto_array< T >::operator=(auto_array_ref< T > ref)
- throw()
-{
- if (m_ptr != ref.m_ptr) {
- delete [] m_ptr;
- m_ptr = ref.m_ptr;
- }
- return *this;
-}
-
-template< class T >
-T&
-auto_array< T >::operator[](int pos)
- throw()
-{
- return m_ptr[pos];
-}
-
-template< class T >
-auto_array< T >::operator auto_array_ref< T >(void)
- throw()
-{
- return auto_array_ref< T >(release());
-}
-
-} // namespace atf
-
-#endif // !defined(ATF_CXX_DETAIL_AUTO_ARRAY_HPP)
diff --git a/contrib/atf/atf-c++/detail/auto_array_test.cpp b/contrib/atf/atf-c++/detail/auto_array_test.cpp
deleted file mode 100644
index aaad90e15295..000000000000
--- a/contrib/atf/atf-c++/detail/auto_array_test.cpp
+++ /dev/null
@@ -1,302 +0,0 @@
-// Copyright (c) 2007 The NetBSD Foundation, Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-// 1. Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
-// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
-// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
-// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "atf-c++/detail/auto_array.hpp"
-
-extern "C" {
-#include <sys/types.h>
-}
-
-#include <iostream>
-
-#include <atf-c++.hpp>
-
-extern "C" {
-#include "atf-c/defs.h"
-}
-
-// ------------------------------------------------------------------------
-// Tests for the "auto_array" class.
-// ------------------------------------------------------------------------
-
-class test_array {
-public:
- int m_value;
-
- static ssize_t m_nblocks;
-
- static
- atf::auto_array< test_array >
- do_copy(atf::auto_array< test_array >& ta)
- {
- return atf::auto_array< test_array >(ta);
- }
-
- void* operator new(size_t size ATF_DEFS_ATTRIBUTE_UNUSED)
- {
- ATF_FAIL("New called but should have been new[]");
- return new int(5);
- }
-
- void* operator new[](size_t size)
- {
- m_nblocks++;
- void* mem = ::operator new(size);
- std::cout << "Allocated 'test_array' object " << mem << "\n";
- return mem;
- }
-
- void operator delete(void* mem ATF_DEFS_ATTRIBUTE_UNUSED)
- {
- ATF_FAIL("Delete called but should have been delete[]");
- }
-
- void operator delete[](void* mem)
- {
- std::cout << "Releasing 'test_array' object " << mem << "\n";
- if (m_nblocks == 0)
- ATF_FAIL("Unbalanced delete[]");
- m_nblocks--;
- ::operator delete(mem);
- }
-};
-
-ssize_t test_array::m_nblocks = 0;
-
-ATF_TEST_CASE(auto_array_scope);
-ATF_TEST_CASE_HEAD(auto_array_scope)
-{
- set_md_var("descr", "Tests the automatic scope handling in the "
- "auto_array smart pointer class");
-}
-ATF_TEST_CASE_BODY(auto_array_scope)
-{
- using atf::auto_array;
-
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- {
- auto_array< test_array > t(new test_array[10]);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
-}
-
-ATF_TEST_CASE(auto_array_copy);
-ATF_TEST_CASE_HEAD(auto_array_copy)
-{
- set_md_var("descr", "Tests the auto_array smart pointer class' copy "
- "constructor");
-}
-ATF_TEST_CASE_BODY(auto_array_copy)
-{
- using atf::auto_array;
-
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- {
- auto_array< test_array > t1(new test_array[10]);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
-
- {
- auto_array< test_array > t2(t1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
-}
-
-ATF_TEST_CASE(auto_array_copy_ref);
-ATF_TEST_CASE_HEAD(auto_array_copy_ref)
-{
- set_md_var("descr", "Tests the auto_array smart pointer class' copy "
- "constructor through the auxiliary auto_array_ref object");
-}
-ATF_TEST_CASE_BODY(auto_array_copy_ref)
-{
- using atf::auto_array;
-
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- {
- auto_array< test_array > t1(new test_array[10]);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
-
- {
- auto_array< test_array > t2 = test_array::do_copy(t1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
-}
-
-ATF_TEST_CASE(auto_array_get);
-ATF_TEST_CASE_HEAD(auto_array_get)
-{
- set_md_var("descr", "Tests the auto_array smart pointer class' get "
- "method");
-}
-ATF_TEST_CASE_BODY(auto_array_get)
-{
- using atf::auto_array;
-
- test_array* ta = new test_array[10];
- auto_array< test_array > t(ta);
- ATF_REQUIRE_EQ(t.get(), ta);
-}
-
-ATF_TEST_CASE(auto_array_release);
-ATF_TEST_CASE_HEAD(auto_array_release)
-{
- set_md_var("descr", "Tests the auto_array smart pointer class' release "
- "method");
-}
-ATF_TEST_CASE_BODY(auto_array_release)
-{
- using atf::auto_array;
-
- test_array* ta1 = new test_array[10];
- {
- auto_array< test_array > t(ta1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- test_array* ta2 = t.release();
- ATF_REQUIRE_EQ(ta2, ta1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- delete [] ta1;
-}
-
-ATF_TEST_CASE(auto_array_reset);
-ATF_TEST_CASE_HEAD(auto_array_reset)
-{
- set_md_var("descr", "Tests the auto_array smart pointer class' reset "
- "method");
-}
-ATF_TEST_CASE_BODY(auto_array_reset)
-{
- using atf::auto_array;
-
- test_array* ta1 = new test_array[10];
- test_array* ta2 = new test_array[10];
- ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
-
- {
- auto_array< test_array > t(ta1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 2);
- t.reset(ta2);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- t.reset();
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
-}
-
-ATF_TEST_CASE(auto_array_assign);
-ATF_TEST_CASE_HEAD(auto_array_assign)
-{
- set_md_var("descr", "Tests the auto_array smart pointer class' "
- "assignment operator");
-}
-ATF_TEST_CASE_BODY(auto_array_assign)
-{
- using atf::auto_array;
-
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- {
- auto_array< test_array > t1(new test_array[10]);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
-
- {
- auto_array< test_array > t2;
- t2 = t1;
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
-}
-
-ATF_TEST_CASE(auto_array_assign_ref);
-ATF_TEST_CASE_HEAD(auto_array_assign_ref)
-{
- set_md_var("descr", "Tests the auto_array smart pointer class' "
- "assignment operator through the auxiliary auto_array_ref "
- "object");
-}
-ATF_TEST_CASE_BODY(auto_array_assign_ref)
-{
- using atf::auto_array;
-
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- {
- auto_array< test_array > t1(new test_array[10]);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
-
- {
- auto_array< test_array > t2;
- t2 = test_array::do_copy(t1);
- ATF_REQUIRE_EQ(test_array::m_nblocks, 1);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
- }
- ATF_REQUIRE_EQ(test_array::m_nblocks, 0);
-}
-
-ATF_TEST_CASE(auto_array_access);
-ATF_TEST_CASE_HEAD(auto_array_access)
-{
- set_md_var("descr", "Tests the auto_array smart pointer class' access "
- "operator");
-}
-ATF_TEST_CASE_BODY(auto_array_access)
-{
- using atf::auto_array;
-
- auto_array< test_array > t(new test_array[10]);
-
- for (int i = 0; i < 10; i++)
- t[i].m_value = i * 2;
-
- for (int i = 0; i < 10; i++)
- ATF_REQUIRE_EQ(t[i].m_value, i * 2);
-}
-
-// ------------------------------------------------------------------------
-// Main.
-// ------------------------------------------------------------------------
-
-ATF_INIT_TEST_CASES(tcs)
-{
- // Add the test for the "auto_array" class.
- ATF_ADD_TEST_CASE(tcs, auto_array_scope);
- ATF_ADD_TEST_CASE(tcs, auto_array_copy);
- ATF_ADD_TEST_CASE(tcs, auto_array_copy_ref);
- ATF_ADD_TEST_CASE(tcs, auto_array_get);
- ATF_ADD_TEST_CASE(tcs, auto_array_release);
- ATF_ADD_TEST_CASE(tcs, auto_array_reset);
- ATF_ADD_TEST_CASE(tcs, auto_array_assign);
- ATF_ADD_TEST_CASE(tcs, auto_array_assign_ref);
- ATF_ADD_TEST_CASE(tcs, auto_array_access);
-}
diff --git a/contrib/atf/atf-c++/detail/fs.cpp b/contrib/atf/atf-c++/detail/fs.cpp
index bcef9204d129..74bacf26a421 100644
--- a/contrib/atf/atf-c++/detail/fs.cpp
+++ b/contrib/atf/atf-c++/detail/fs.cpp
@@ -32,7 +32,6 @@
extern "C" {
#include <sys/param.h>
#include <sys/types.h>
-#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dirent.h>
diff --git a/contrib/atf/atf-c++/detail/process.cpp b/contrib/atf/atf-c++/detail/process.cpp
index 8139536d39e3..25516059c884 100644
--- a/contrib/atf/atf-c++/detail/process.cpp
+++ b/contrib/atf/atf-c++/detail/process.cpp
@@ -46,31 +46,29 @@ namespace impl = atf::process;
// ------------------------------------------------------------------------
template< class C >
-atf::auto_array< const char* >
+std::vector<const char*>
collection_to_argv(const C& c)
{
- atf::auto_array< const char* > argv(new const char*[c.size() + 1]);
+ std::vector<const char*> argv;
+ argv.reserve(c.size() + 1);
- std::size_t pos = 0;
- for (typename C::const_iterator iter = c.begin(); iter != c.end();
- iter++) {
- argv[pos] = (*iter).c_str();
- pos++;
+ for (const auto& item : c) {
+ argv.push_back(item.c_str());
}
- INV(pos == c.size());
- argv[pos] = NULL;
+ argv.push_back(nullptr);
return argv;
}
-template< class C >
+template<class C>
C
argv_to_collection(const char* const* argv)
{
C c;
- for (const char* const* iter = argv; *iter != NULL; iter++)
+ for (const char* const* iter = argv; *iter != nullptr; iter++) {
c.push_back(std::string(*iter));
+ }
return c;
}
@@ -123,7 +121,7 @@ const char* const*
impl::argv_array::exec_argv(void)
const
{
- return m_exec_argv.get();
+ return m_exec_argv.data();
}
impl::argv_array::size_type
diff --git a/contrib/atf/atf-c++/detail/process.hpp b/contrib/atf/atf-c++/detail/process.hpp
index 0d4989a4f40b..78bd55fd0f05 100644
--- a/contrib/atf/atf-c++/detail/process.hpp
+++ b/contrib/atf/atf-c++/detail/process.hpp
@@ -36,7 +36,6 @@ extern "C" {
#include <string>
#include <vector>
-#include <atf-c++/detail/auto_array.hpp>
#include <atf-c++/detail/exceptions.hpp>
#include <atf-c++/detail/fs.hpp>
@@ -58,7 +57,7 @@ class argv_array {
// std::tr1::shared_array instead when it becomes widely available.
// The reason would be to remove all copy constructors and assignment
// operators from this class.
- auto_array< const char* > m_exec_argv;
+ std::vector< const char* > m_exec_argv;
void ctor_init_exec_argv(void);
public:
diff --git a/contrib/atf/atf-c++/detail/process_test.cpp b/contrib/atf/atf-c++/detail/process_test.cpp
index 97f9a08e2504..69cd79d3f628 100644
--- a/contrib/atf/atf-c++/detail/process_test.cpp
+++ b/contrib/atf/atf-c++/detail/process_test.cpp
@@ -196,22 +196,19 @@ ATF_TEST_CASE_BODY(argv_array_assign)
const char* const carray1[] = { "arg1", NULL };
const char* const carray2[] = { "arg1", "arg2", NULL };
- std::unique_ptr< argv_array > argv1(new argv_array(carray1));
- std::unique_ptr< argv_array > argv2(new argv_array(carray2));
+ argv_array argv1 = argv_array(carray1);
+ argv_array argv2 = argv_array(carray2);
- *argv2 = *argv1;
- ATF_REQUIRE_EQ(argv2->size(), argv1->size());
- ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
+ argv2 = argv1;
+ ATF_REQUIRE_EQ(argv2.size(), argv1.size());
+ ATF_REQUIRE(std::strcmp(argv2[0], argv1[0]) == 0);
- ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv());
- argv1.release();
+ ATF_REQUIRE(argv2.exec_argv() != argv1.exec_argv());
{
- const char* const* eargv2 = argv2->exec_argv();
+ const char* const* eargv2 = argv2.exec_argv();
ATF_REQUIRE(std::strcmp(eargv2[0], carray1[0]) == 0);
ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL));
}
-
- argv2.release();
}
ATF_TEST_CASE(argv_array_copy);
@@ -226,21 +223,18 @@ ATF_TEST_CASE_BODY(argv_array_copy)
const char* const carray[] = { "arg0", NULL };
- std::unique_ptr< argv_array > argv1(new argv_array(carray));
- std::unique_ptr< argv_array > argv2(new argv_array(*argv1));
+ argv_array argv1 = argv_array(carray);
+ argv_array argv2 = argv1;
- ATF_REQUIRE_EQ(argv2->size(), argv1->size());
- ATF_REQUIRE(std::strcmp((*argv2)[0], (*argv1)[0]) == 0);
+ ATF_REQUIRE_EQ(argv2.size(), argv1.size());
+ ATF_REQUIRE(std::strcmp(argv2[0], argv1[0]) == 0);
- ATF_REQUIRE(argv2->exec_argv() != argv1->exec_argv());
- argv1.release();
+ ATF_REQUIRE(argv2.exec_argv() != argv1.exec_argv());
{
- const char* const* eargv2 = argv2->exec_argv();
+ const char* const* eargv2 = argv2.exec_argv();
ATF_REQUIRE(std::strcmp(eargv2[0], carray[0]) == 0);
ATF_REQUIRE_EQ(eargv2[1], static_cast< const char* >(NULL));
}
-
- argv2.release();
}
ATF_TEST_CASE(argv_array_exec_argv);
diff --git a/contrib/atf/atf-c++/detail/test_helpers.hpp b/contrib/atf/atf-c++/detail/test_helpers.hpp
index c1171801a3a7..1c4c316f4714 100644
--- a/contrib/atf/atf-c++/detail/test_helpers.hpp
+++ b/contrib/atf/atf-c++/detail/test_helpers.hpp
@@ -45,8 +45,6 @@
{ \
set_md_var("descr", "Tests that the " hdrname " file can be " \
"included on its own, without any prerequisites"); \
- const std::string cxx = atf::env::get("ATF_BUILD_CXX", ATF_BUILD_CXX); \
- set_md_var("require.progs", cxx); \
} \
ATF_TEST_CASE_BODY(name) \
{ \
@@ -58,8 +56,6 @@
ATF_TEST_CASE_HEAD(name) \
{ \
set_md_var("descr", descr); \
- const std::string cxx = atf::env::get("ATF_BUILD_CXX", ATF_BUILD_CXX); \
- set_md_var("require.progs", cxx); \
} \
ATF_TEST_CASE_BODY(name) \
{ \
diff --git a/contrib/atf/atf-c++/detail/text.cpp b/contrib/atf/atf-c++/detail/text.cpp
index 35a0beca95b9..524788a41971 100644
--- a/contrib/atf/atf-c++/detail/text.cpp
+++ b/contrib/atf/atf-c++/detail/text.cpp
@@ -42,14 +42,6 @@ extern "C" {
namespace impl = atf::text;
#define IMPL_NAME "atf::text"
-char*
-impl::duplicate(const char* str)
-{
- char* copy = new char[std::strlen(str) + 1];
- std::strcpy(copy, str);
- return copy;
-}
-
bool
impl::match(const std::string& str, const std::string& regex)
{
diff --git a/contrib/atf/atf-c++/detail/text.hpp b/contrib/atf/atf-c++/detail/text.hpp
index 63c3190a37c1..2e07df2cf4e9 100644
--- a/contrib/atf/atf-c++/detail/text.hpp
+++ b/contrib/atf/atf-c++/detail/text.hpp
@@ -39,14 +39,6 @@ namespace atf {
namespace text {
//!
-//! \brief Duplicates a C string using the new[] allocator.
-//!
-//! Replaces the functionality of strdup by using the new[] allocator and
-//! thus allowing the resulting memory to be managed by utils::auto_array.
-//!
-char* duplicate(const char*);
-
-//!
//! \brief Joins multiple words into a string.
//!
//! Joins a list of words into a string, separating them using the provided
diff --git a/contrib/atf/atf-c++/detail/text_test.cpp b/contrib/atf/atf-c++/detail/text_test.cpp
index 49d37741b414..108241130f5d 100644
--- a/contrib/atf/atf-c++/detail/text_test.cpp
+++ b/contrib/atf/atf-c++/detail/text_test.cpp
@@ -35,26 +35,6 @@
// Test cases for the free functions.
// ------------------------------------------------------------------------
-ATF_TEST_CASE(duplicate);
-ATF_TEST_CASE_HEAD(duplicate)
-{
- set_md_var("descr", "Tests the duplicate function");
-}
-ATF_TEST_CASE_BODY(duplicate)
-{
- using atf::text::duplicate;
-
- const char* orig = "foo";
-
- char* copy = duplicate(orig);
- ATF_REQUIRE_EQ(std::strlen(copy), 3);
- ATF_REQUIRE(std::strcmp(copy, "foo") == 0);
-
- std::strcpy(copy, "bar");
- ATF_REQUIRE(std::strcmp(copy, "bar") == 0);
- ATF_REQUIRE(std::strcmp(orig, "foo") == 0);
-}
-
ATF_TEST_CASE(join);
ATF_TEST_CASE_HEAD(join)
{
@@ -373,7 +353,6 @@ ATF_TEST_CASE_BODY(to_type)
ATF_INIT_TEST_CASES(tcs)
{
// Add the test cases for the free functions.
- ATF_ADD_TEST_CASE(tcs, duplicate);
ATF_ADD_TEST_CASE(tcs, join);
ATF_ADD_TEST_CASE(tcs, match);
ATF_ADD_TEST_CASE(tcs, split);
diff --git a/contrib/atf/atf-c++/tests.cpp b/contrib/atf/atf-c++/tests.cpp
index a9f5d4a5fe2c..cb0d735f5a06 100644
--- a/contrib/atf/atf-c++/tests.cpp
+++ b/contrib/atf/atf-c++/tests.cpp
@@ -58,7 +58,6 @@ extern "C" {
}
#include "atf-c++/detail/application.hpp"
-#include "atf-c++/detail/auto_array.hpp"
#include "atf-c++/detail/env.hpp"
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/fs.hpp"
@@ -123,13 +122,7 @@ static void
set_program_name(const char* argv0)
{
const std::string program_name = atf::fs::path(argv0).leaf_name();
- // Libtool workaround: if running from within the source tree (binaries
- // that are not installed yet), skip the "lt-" prefix added to files in
- // the ".libs" directory to show the real (not temporary) name.
- if (program_name.substr(0, 3) == "lt-")
- Program_Name = program_name.substr(3);
- else
- Program_Name = program_name;
+ Program_Name = program_name;
}
bool
@@ -207,22 +200,22 @@ impl::tc::init(const vars_map& config)
{
atf_error_t err;
- auto_array< const char * > array(new const char*[(config.size() * 2) + 1]);
- const char **ptr = array.get();
+ std::vector< const char * > array;
+ array.reserve((config.size() * 2) + 1);
+
for (vars_map::const_iterator iter = config.begin();
iter != config.end(); iter++) {
- *ptr = (*iter).first.c_str();
- *(ptr + 1) = (*iter).second.c_str();
- ptr += 2;
+ array.push_back((*iter).first.c_str());
+ array.push_back((*iter).second.c_str());
}
- *ptr = NULL;
+ array.push_back(nullptr);
wraps[&pimpl->m_tc] = this;
cwraps[&pimpl->m_tc] = this;
err = atf_tc_init(&pimpl->m_tc, pimpl->m_ident.c_str(), pimpl->wrap_head,
pimpl->wrap_body, pimpl->m_has_cleanup ? pimpl->wrap_cleanup : NULL,
- array.get());
+ array.data());
if (atf_is_error(err))
throw_atf_error(err);
}
@@ -273,6 +266,7 @@ impl::tc::get_md_vars(void)
char **ptr;
for (ptr = array; *ptr != NULL; ptr += 2)
vars[*ptr] = *(ptr + 1);
+ atf_utils_free_charpp(array);
} catch (...) {
atf_utils_free_charpp(array);
throw;
@@ -461,9 +455,7 @@ init_tcs(void (*add_tcs)(tc_vector&), tc_vector& tcs,
const atf::tests::vars_map& vars)
{
add_tcs(tcs);
- for (tc_vector::iterator iter = tcs.begin(); iter != tcs.end(); iter++) {
- impl::tc* tc = *iter;
-
+ for (auto& tc : tcs) {
tc->init(vars);
}
}
@@ -616,27 +608,25 @@ safe_main(int argc, char** argv, void (*add_tcs)(tc_vector&))
int errcode;
- tc_vector tcs;
if (lflag) {
if (argc > 0)
throw usage_error("Cannot provide test case names with -l");
-
- init_tcs(add_tcs, tcs, vars);
- errcode = list_tcs(tcs);
} else {
if (argc == 0)
throw usage_error("Must provide a test case name");
else if (argc > 1)
throw usage_error("Cannot provide more than one test case name");
INV(argc == 1);
-
- init_tcs(add_tcs, tcs, vars);
- errcode = run_tc(tcs, argv[0], resfile);
}
- for (tc_vector::iterator iter = tcs.begin(); iter != tcs.end(); iter++) {
- impl::tc* tc = *iter;
-
- delete tc;
+ tc_vector tcs;
+ try {
+ init_tcs(add_tcs, tcs, vars);
+ errcode = lflag ? list_tcs(tcs) : run_tc(tcs, argv[0], resfile);
+ } catch (...) {
+ for (auto& tc: tcs) {
+ delete tc;
+ }
+ throw;
}
return errcode;
diff --git a/contrib/atf/atf-c++/tests_test.cpp b/contrib/atf/atf-c++/tests_test.cpp
index ed9fef0d0140..98b4da70d247 100644
--- a/contrib/atf/atf-c++/tests_test.cpp
+++ b/contrib/atf/atf-c++/tests_test.cpp
@@ -163,6 +163,10 @@ ATF_TEST_CASE_BODY(atf_tp_writer)
expss << "descr: second test case\n";
CHECK;
+ w.tc_meta_data("require.kmods", "/nonexistent");
+ expss << "require.kmods: /nonexistent\n";
+ CHECK;
+
w.tc_meta_data("require.progs", "/bin/cp");
expss << "require.progs: /bin/cp\n";
CHECK;
diff --git a/contrib/atf/atf-c/.gitignore b/contrib/atf/atf-c/.gitignore
deleted file mode 100644
index e7f0fb647c32..000000000000
--- a/contrib/atf/atf-c/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-defs.h
diff --git a/contrib/atf/atf-c/atf-c.3 b/contrib/atf/atf-c/atf-c.3
index 153c09fb0f7e..02f06483646f 100644
--- a/contrib/atf/atf-c/atf-c.3
+++ b/contrib/atf/atf-c/atf-c.3
@@ -22,7 +22,7 @@
.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.Dd June 12, 2025
+.Dd October 10, 2025
.Dt ATF-C 3
.Os
.Sh NAME
@@ -244,7 +244,7 @@
.Fa "const char *contents"
.Fa "..."
.Fc
-.Ft void
+.Ft bool
.Fo atf_utils_file_exists
.Fa "const char *file"
.Fc
@@ -326,9 +326,9 @@ ATF_TC_BODY(tc3, tc)
ATF_TP_ADD_TCS(tp)
{
- ATF_TP_ADD_TC(tcs, tc1);
- ATF_TP_ADD_TC(tcs, tc2);
- ATF_TP_ADD_TC(tcs, tc3);
+ ATF_TP_ADD_TC(tp, tc1);
+ ATF_TP_ADD_TC(tp, tc2);
+ ATF_TP_ADD_TC(tp, tc3);
... add additional test cases ...
return atf_no_error();
@@ -447,6 +447,8 @@ additional kernel modules in the test case's body by using the
.Fn atf_tc_require_kmod
function, which takes the name of a single kernel module.
If it is not found, the test case will be automatically skipped.
+This feature is only available on
+.Fx .
.Ss Requiring programs
Aside from the
.Va require.progs
@@ -620,12 +622,10 @@ observed integer in the second parameter.
.Fn ATF_CHECK_ERRNO
and
.Fn ATF_REQUIRE_ERRNO
-take, first, the error code that the check is expecting to find in the
-.Va errno
-variable and, second, a boolean expression that, if evaluates to true,
-means that a call failed and
+take an expected error code and a boolean expression, and fail the
+test if either the expression is false or
.Va errno
-has to be checked against the first value.
+is not equal to the expected error code.
.Ss Utility functions
The following functions are provided as part of the
.Nm
@@ -782,7 +782,7 @@ those spawned by
.Fc
.Bd -ragged -offset indent
Waits and validates the result of a subprocess spawned with
-.Fn atf_utils_fork .
+.Fn atf_utils_wait .
The validation involves checking that the subprocess exited cleanly and returned
the code specified in
.Fa expected_exit_status
diff --git a/contrib/atf/atf-c/build.c b/contrib/atf/atf-c/build.c
index c119fc97a214..ce0188a62db1 100644
--- a/contrib/atf/atf-c/build.c
+++ b/contrib/atf/atf-c/build.c
@@ -83,7 +83,7 @@ append_optargs(const char *const optargs[], atf_list_t *argv)
err = atf_no_error();
while (*optargs != NULL && !atf_is_error(err)) {
- err = append_arg1(strdup(*optargs), argv);
+ err = append_arg1(*optargs, argv);
optargs++;
}
diff --git a/contrib/atf/atf-c/check.c b/contrib/atf/atf-c/check.c
index 1aec01bcca6b..f80e08f0fdde 100644
--- a/contrib/atf/atf-c/check.c
+++ b/contrib/atf/atf-c/check.c
@@ -348,6 +348,7 @@ atf_check_result_fini(atf_check_result_t *r)
atf_list_fini(&r->pimpl->m_argv);
free(r->pimpl);
+ r->pimpl = NULL;
}
const char *
diff --git a/contrib/atf/atf-c/defs.h.in b/contrib/atf/atf-c/defs.h.in
index 6059e7fdb0e6..5346e56ac9c9 100644
--- a/contrib/atf/atf-c/defs.h.in
+++ b/contrib/atf/atf-c/defs.h.in
@@ -27,6 +27,7 @@
#define ATF_C_DEFS_H
#define ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(a, b) @ATTRIBUTE_FORMAT_PRINTF@
+#define ATF_DEFS_ATTRIBUTE_NONNULL @ATTRIBUTE_NONNULL@
#define ATF_DEFS_ATTRIBUTE_NORETURN @ATTRIBUTE_NORETURN@
#define ATF_DEFS_ATTRIBUTE_UNUSED @ATTRIBUTE_UNUSED@
diff --git a/contrib/atf/atf-c/detail/dynstr.c b/contrib/atf/atf-c/detail/dynstr.c
index 424a1c9dac73..8e61104ef77f 100644
--- a/contrib/atf/atf-c/detail/dynstr.c
+++ b/contrib/atf/atf-c/detail/dynstr.c
@@ -45,22 +45,18 @@ atf_error_t
resize(atf_dynstr_t *ad, size_t newsize)
{
char *newdata;
- atf_error_t err;
PRE(newsize > ad->m_datasize);
- newdata = (char *)malloc(newsize);
- if (newdata == NULL) {
- err = atf_no_memory_error();
- } else {
- strcpy(newdata, ad->m_data);
- free(ad->m_data);
- ad->m_data = newdata;
- ad->m_datasize = newsize;
- err = atf_no_error();
- }
+ newdata = realloc(ad->m_data, newsize);
+ if (newdata == NULL)
+ return atf_no_memory_error();
- return err;
+ newdata[newsize - 1] = '\0';
+ ad->m_data = newdata;
+ ad->m_datasize = newsize;
+
+ return atf_no_error();
}
static
@@ -117,21 +113,16 @@ const size_t atf_dynstr_npos = SIZE_MAX;
atf_error_t
atf_dynstr_init(atf_dynstr_t *ad)
{
- atf_error_t err;
- ad->m_data = (char *)malloc(sizeof(char));
- if (ad->m_data == NULL) {
- err = atf_no_memory_error();
- goto out;
- }
+ ad->m_data = malloc(sizeof(char));
+ if (ad->m_data == NULL)
+ return atf_no_memory_error();
ad->m_data[0] = '\0';
ad->m_datasize = 1;
ad->m_length = 0;
- err = atf_no_error();
-out:
- return err;
+ return atf_no_error();
}
atf_error_t
@@ -158,6 +149,7 @@ atf_dynstr_init_ap(atf_dynstr_t *ad, const char *fmt, va_list ap)
va_end(ap2);
if (ret < 0) {
free(ad->m_data);
+ ad->m_data = NULL;
err = atf_libc_error(errno, "Cannot format string");
goto out;
}
@@ -278,6 +270,7 @@ atf_dynstr_fini(atf_dynstr_t *ad)
{
INV(ad->m_data != NULL);
free(ad->m_data);
+ ad->m_data = NULL;
}
char *
diff --git a/contrib/atf/atf-c/detail/dynstr_test.c b/contrib/atf/atf-c/detail/dynstr_test.c
index 25127529f81b..2a12be23ae5a 100644
--- a/contrib/atf/atf-c/detail/dynstr_test.c
+++ b/contrib/atf/atf-c/detail/dynstr_test.c
@@ -43,6 +43,8 @@
* Constructors and destructors.
*/
+#define MAXLEN 8192
+
ATF_TC(init);
ATF_TC_HEAD(init, tc)
{
@@ -173,13 +175,12 @@ ATF_TC_HEAD(init_rep, tc)
}
ATF_TC_BODY(init_rep, tc)
{
- const size_t maxlen = 8192;
- char buf[maxlen + 1];
+ char buf[MAXLEN + 1];
size_t i;
buf[0] = '\0';
- for (i = 0; i < maxlen; i++) {
+ for (i = 0; i < MAXLEN; i++) {
atf_dynstr_t str;
RE(atf_dynstr_init_rep(&str, i, 'a'));
@@ -371,15 +372,14 @@ static
void
check_append(atf_error_t (*append)(atf_dynstr_t *, const char *, ...))
{
- const size_t maxlen = 8192;
- char buf[maxlen + 1];
+ char buf[MAXLEN + 1];
size_t i;
atf_dynstr_t str;
printf("Appending with plain string\n");
buf[0] = '\0';
RE(atf_dynstr_init(&str));
- for (i = 0; i < maxlen; i++) {
+ for (i = 0; i < MAXLEN; i++) {
if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
fprintf(stderr, "Failed at iteration %zd\n", i);
atf_tc_fail("Failed to append character at iteration %zd", i);
@@ -393,7 +393,7 @@ check_append(atf_error_t (*append)(atf_dynstr_t *, const char *, ...))
printf("Appending with formatted string\n");
buf[0] = '\0';
RE(atf_dynstr_init(&str));
- for (i = 0; i < maxlen; i++) {
+ for (i = 0; i < MAXLEN; i++) {
if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
fprintf(stderr, "Failed at iteration %zd\n", i);
atf_tc_fail("Failed to append character at iteration %zd", i);
@@ -471,15 +471,14 @@ static
void
check_prepend(atf_error_t (*prepend)(atf_dynstr_t *, const char *, ...))
{
- const size_t maxlen = 8192;
- char buf[maxlen + 1];
+ char buf[MAXLEN + 1];
size_t i;
atf_dynstr_t str;
printf("Prepending with plain string\n");
buf[0] = '\0';
RE(atf_dynstr_init(&str));
- for (i = 0; i < maxlen; i++) {
+ for (i = 0; i < MAXLEN; i++) {
if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
fprintf(stderr, "Failed at iteration %zd\n", i);
atf_tc_fail("Failed to prepend character at iteration %zd", i);
@@ -499,7 +498,7 @@ check_prepend(atf_error_t (*prepend)(atf_dynstr_t *, const char *, ...))
printf("Prepending with formatted string\n");
buf[0] = '\0';
RE(atf_dynstr_init(&str));
- for (i = 0; i < maxlen; i++) {
+ for (i = 0; i < MAXLEN; i++) {
if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
fprintf(stderr, "Failed at iteration %zd\n", i);
atf_tc_fail("Failed to prepend character at iteration %zd", i);
diff --git a/contrib/atf/atf-c/detail/env.c b/contrib/atf/atf-c/detail/env.c
index 8ee3d697c223..36de217c353c 100644
--- a/contrib/atf/atf-c/detail/env.c
+++ b/contrib/atf/atf-c/detail/env.c
@@ -25,10 +25,6 @@
#include "atf-c/detail/env.h"
-#if defined(HAVE_CONFIG_H)
-#include "config.h"
-#endif
-
#include <errno.h>
#include <stdlib.h>
@@ -65,25 +61,11 @@ atf_env_set(const char *name, const char *val)
{
atf_error_t err;
-#if defined(HAVE_SETENV)
if (setenv(name, val, 1) == -1)
- err = atf_libc_error(errno, "Cannot set environment variable "
- "'%s' to '%s'", name, val);
+ err = atf_libc_error(errno,
+ "Cannot set environment variable '%s' to '%s'", name, val);
else
err = atf_no_error();
-#elif defined(HAVE_PUTENV)
- char *buf;
-
- err = atf_text_format(&buf, "%s=%s", name, val);
- if (!atf_is_error(err)) {
- if (putenv(buf) == -1)
- err = atf_libc_error(errno, "Cannot set environment variable "
- "'%s' to '%s'", name, val);
- free(buf);
- }
-#else
-# error "Don't know how to set an environment variable."
-#endif
return err;
}
@@ -91,24 +73,7 @@ atf_env_set(const char *name, const char *val)
atf_error_t
atf_env_unset(const char *name)
{
- atf_error_t err;
-#if defined(HAVE_UNSETENV)
unsetenv(name);
- err = atf_no_error();
-#elif defined(HAVE_PUTENV)
- char *buf;
-
- err = atf_text_format(&buf, "%s=", name);
- if (!atf_is_error(err)) {
- if (putenv(buf) == -1)
- err = atf_libc_error(errno, "Cannot unset environment variable"
- " '%s'", name);
- free(buf);
- }
-#else
-# error "Don't know how to unset an environment variable."
-#endif
-
- return err;
+ return (atf_no_error());
}
diff --git a/contrib/atf/atf-c/detail/fs.c b/contrib/atf/atf-c/detail/fs.c
index 6ea825aa8e56..34a2cb321c7e 100644
--- a/contrib/atf/atf-c/detail/fs.c
+++ b/contrib/atf/atf-c/detail/fs.c
@@ -31,7 +31,6 @@
#include <sys/types.h>
#include <sys/param.h>
-#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
@@ -59,7 +58,6 @@ static atf_error_t do_mkdtemp(char *);
static atf_error_t normalize(atf_dynstr_t *, char *);
static atf_error_t normalize_ap(atf_dynstr_t *, const char *, va_list);
static void replace_contents(atf_fs_path_t *, const char *);
-static const char *stat_type_to_string(const int);
/* ---------------------------------------------------------------------
* The "unknown_file_type" error type.
@@ -109,16 +107,12 @@ atf_error_t
copy_contents(const atf_fs_path_t *p, char **buf)
{
atf_error_t err;
- char *str;
- str = (char *)malloc(atf_dynstr_length(&p->m_data) + 1);
- if (str == NULL)
+ *buf = strdup(atf_fs_path_cstring(p));
+ if (*buf == NULL)
err = atf_no_memory_error();
- else {
- strcpy(str, atf_dynstr_cstring(&p->m_data));
- *buf = str;
+ else
err = atf_no_error();
- }
return err;
}
@@ -211,6 +205,7 @@ normalize_ap(atf_dynstr_t *d, const char *p, va_list ap)
else {
err = normalize(d, str);
free(str);
+ str = NULL;
}
out:
@@ -231,36 +226,6 @@ replace_contents(atf_fs_path_t *p, const char *buf)
INV(!atf_is_error(err));
}
-static
-const char *
-stat_type_to_string(const int type)
-{
- const char *str;
-
- if (type == atf_fs_stat_blk_type)
- str = "block device";
- else if (type == atf_fs_stat_chr_type)
- str = "character device";
- else if (type == atf_fs_stat_dir_type)
- str = "directory";
- else if (type == atf_fs_stat_fifo_type)
- str = "named pipe";
- else if (type == atf_fs_stat_lnk_type)
- str = "symbolic link";
- else if (type == atf_fs_stat_reg_type)
- str = "regular file";
- else if (type == atf_fs_stat_sock_type)
- str = "socket";
- else if (type == atf_fs_stat_wht_type)
- str = "whiteout";
- else {
- UNREACHABLE;
- str = NULL;
- }
-
- return str;
-}
-
/* ---------------------------------------------------------------------
* The "atf_fs_path" type.
* --------------------------------------------------------------------- */
@@ -730,15 +695,14 @@ atf_fs_mkdtemp(atf_fs_path_t *p)
err = do_mkdtemp(buf);
if (atf_is_error(err))
- goto out_buf;
+ goto out;
replace_contents(p, buf);
INV(!atf_is_error(err));
-out_buf:
- free(buf);
out:
- umask(mask);
+ (void)umask(mask);
+ free(buf);
return err;
}
@@ -759,16 +723,15 @@ atf_fs_mkstemp(atf_fs_path_t *p, int *fdout)
err = do_mkstemp(buf, &fd);
if (atf_is_error(err))
- goto out_buf;
+ goto out;
replace_contents(p, buf);
*fdout = fd;
INV(!atf_is_error(err));
-out_buf:
- free(buf);
out:
- umask(mask);
+ (void)umask(mask);
+ free(buf);
return err;
}
diff --git a/contrib/atf/atf-c/detail/fs_test.c b/contrib/atf/atf-c/detail/fs_test.c
index a9cc34a4f48b..937cf193aa91 100644
--- a/contrib/atf/atf-c/detail/fs_test.c
+++ b/contrib/atf/atf-c/detail/fs_test.c
@@ -901,8 +901,8 @@ do_umask_check(atf_error_t (*const mk_func)(atf_fs_path_t *),
const char *exp_name)
{
atf_fs_path_t path;
- int pre_mask, post_mask;
atf_error_t err;
+ mode_t pre_mask, post_mask;
printf("Creating temporary %s with umask %05o\n", exp_name, test_mask);
@@ -1039,9 +1039,12 @@ ATF_TC_BODY(mkstemp_umask, tc)
RE(atf_fs_path_init_fmt(&p, "testfile.XXXXXX"));
- do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00100, "regular file");
- do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00200, "regular file");
- do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00400, "regular file");
+ do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00100,
+ "regular file");
+ do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00200,
+ "regular file");
+ do_umask_check(mkstemp_discard_fd, atf_fs_unlink, &p, 00400,
+ "regular file");
atf_fs_path_fini(&p);
}
diff --git a/contrib/atf/atf-c/detail/list.c b/contrib/atf/atf-c/detail/list.c
index 7ac9f1fc948b..15b34cf17ba6 100644
--- a/contrib/atf/atf-c/detail/list.c
+++ b/contrib/atf/atf-c/detail/list.c
@@ -84,8 +84,10 @@ static
void
delete_entry(struct list_entry *le)
{
- if (le->m_managed)
+ if (le->m_managed) {
free(le->m_object);
+ le->m_object = NULL;
+ }
free(le);
}
@@ -204,6 +206,7 @@ atf_list_init(atf_list_t *l)
leend = new_entry(NULL, false);
if (leend == NULL) {
free(lebeg);
+ lebeg = NULL;
return atf_no_memory_error();
}
diff --git a/contrib/atf/atf-c/detail/map.c b/contrib/atf/atf-c/detail/map.c
index ae11a44f35f8..67f744e31318 100644
--- a/contrib/atf/atf-c/detail/map.c
+++ b/contrib/atf/atf-c/detail/map.c
@@ -188,7 +188,12 @@ atf_map_init_charpp(atf_map_t *m, const char *const *array)
}
ptr++;
- err = atf_map_insert(m, key, strdup(value), true);
+ char *tmp_value = strdup(value);
+ if (tmp_value == NULL) {
+ err = atf_no_memory_error();
+ break;
+ }
+ err = atf_map_insert(m, key, tmp_value, true);
}
}
@@ -206,9 +211,12 @@ atf_map_fini(atf_map_t *m)
atf_list_for_each(iter, &m->m_list) {
struct map_entry *me = atf_list_iter_data(iter);
- if (me->m_managed)
+ if (me->m_managed) {
free(me->m_value);
+ me->m_value = NULL;
+ }
free(me->m_key);
+ me->m_key = NULL;
free(me);
}
atf_list_fini(&m->m_list);
@@ -353,9 +361,11 @@ atf_map_insert(atf_map_t *m, const char *key, void *value, bool managed)
iter = atf_map_find(m, key);
if (atf_equal_map_iter_map_iter(iter, atf_map_end(m))) {
me = new_entry(key, value, managed);
- if (me == NULL)
+ if (me == NULL) {
err = atf_no_memory_error();
- else {
+ if (managed)
+ free(value);
+ } else {
err = atf_list_append(&m->m_list, me, false);
if (atf_is_error(err)) {
if (managed)
@@ -364,8 +374,10 @@ atf_map_insert(atf_map_t *m, const char *key, void *value, bool managed)
}
} else {
me = iter.m_entry;
- if (me->m_managed)
+ if (me->m_managed) {
free(me->m_value);
+ me->m_value = NULL;
+ }
INV(strcmp(me->m_key, key) == 0);
me->m_value = value;
diff --git a/contrib/atf/atf-c/detail/map_test.c b/contrib/atf/atf-c/detail/map_test.c
index 0982e20f7dd5..e8030328784c 100644
--- a/contrib/atf/atf-c/detail/map_test.c
+++ b/contrib/atf/atf-c/detail/map_test.c
@@ -108,6 +108,7 @@ ATF_TC_BODY(map_init_charpp_short, tc)
atf_error_t err = atf_map_init_charpp(&map, array);
ATF_REQUIRE(atf_is_error(err));
ATF_REQUIRE(atf_error_is(err, "libc"));
+ atf_error_free(err);
}
/*
diff --git a/contrib/atf/atf-c/detail/process.c b/contrib/atf/atf-c/detail/process.c
index a6189bf78e20..539e39ac058b 100644
--- a/contrib/atf/atf-c/detail/process.c
+++ b/contrib/atf/atf-c/detail/process.c
@@ -23,6 +23,8 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+#include "config.h"
+
#include "atf-c/detail/process.h"
#include <sys/types.h>
@@ -42,7 +44,7 @@
/* This prototype is not in the header file because this is a private
* function; however, we need to access it during testing. */
-atf_error_t atf_process_status_init(atf_process_status_t *, int);
+atf_error_t atf_process_status_init(atf_process_status_t *, siginfo_t *);
/* ---------------------------------------------------------------------
* The "stream_prepare" auxiliary type.
@@ -65,6 +67,8 @@ stream_prepare_init(stream_prepare_t *sp, const atf_process_stream_t *sb)
const int type = atf_process_stream_type(sb);
sp->m_sb = sb;
+ sp->m_pipefds[0] = -1;
+ sp->m_pipefds[1] = -1;
sp->m_pipefds_ok = false;
if (type == atf_process_stream_type_capture) {
@@ -186,10 +190,10 @@ atf_process_stream_type(const atf_process_stream_t *sb)
* --------------------------------------------------------------------- */
atf_error_t
-atf_process_status_init(atf_process_status_t *s, int status)
+atf_process_status_init(atf_process_status_t *s, siginfo_t *info)
{
- s->m_status = status;
+ s->m_info = *info;
return atf_no_error();
}
@@ -201,43 +205,36 @@ atf_process_status_fini(atf_process_status_t *s ATF_DEFS_ATTRIBUTE_UNUSED)
bool
atf_process_status_exited(const atf_process_status_t *s)
{
- int mutable_status = s->m_status;
- return WIFEXITED(mutable_status);
+ return s->m_info.si_code == CLD_EXITED;
}
int
atf_process_status_exitstatus(const atf_process_status_t *s)
{
PRE(atf_process_status_exited(s));
- int mutable_status = s->m_status;
- return WEXITSTATUS(mutable_status);
+ return s->m_info.si_status;
}
bool
atf_process_status_signaled(const atf_process_status_t *s)
{
- int mutable_status = s->m_status;
- return WIFSIGNALED(mutable_status);
+ /* Issue #187: `si_code` is a macro on NetBSD. */
+ int code = s->m_info.si_code;
+ return code == CLD_KILLED || code == CLD_DUMPED;
}
int
atf_process_status_termsig(const atf_process_status_t *s)
{
PRE(atf_process_status_signaled(s));
- int mutable_status = s->m_status;
- return WTERMSIG(mutable_status);
+ return s->m_info.si_status;
}
bool
atf_process_status_coredump(const atf_process_status_t *s)
{
PRE(atf_process_status_signaled(s));
-#if defined(WCOREDUMP)
- int mutable_status = s->m_status;
- return WCOREDUMP(mutable_status);
-#else
- return false;
-#endif
+ return s->m_info.si_code == CLD_DUMPED;
}
/* ---------------------------------------------------------------------
@@ -245,14 +242,12 @@ atf_process_status_coredump(const atf_process_status_t *s)
* --------------------------------------------------------------------- */
static
-atf_error_t
+void
atf_process_child_init(atf_process_child_t *c)
{
c->m_pid = 0;
c->m_stdout = -1;
c->m_stderr = -1;
-
- return atf_no_error();
}
static
@@ -269,14 +264,14 @@ atf_error_t
atf_process_child_wait(atf_process_child_t *c, atf_process_status_t *s)
{
atf_error_t err;
- int status;
+ siginfo_t info;
- if (waitpid(c->m_pid, &status, 0) == -1)
+ if (waitid(P_PID, c->m_pid, &info, WEXITED) == -1)
err = atf_libc_error(errno, "Failed waiting for process %d",
c->m_pid);
else {
atf_process_child_fini(c);
- err = atf_process_status_init(s, status);
+ err = atf_process_status_init(s, &info);
}
return err;
@@ -347,7 +342,7 @@ child_connect(const stream_prepare_t *sp, int procfd)
err = safe_dup(sp->m_sb->m_fd, procfd);
} else if (type == atf_process_stream_type_redirect_path) {
int aux = open(atf_fs_path_cstring(sp->m_sb->m_path),
- O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
if (aux == -1)
err = atf_libc_error(errno, "Could not create %s",
atf_fs_path_cstring(sp->m_sb->m_path));
@@ -387,25 +382,17 @@ parent_connect(const stream_prepare_t *sp, int *fd)
}
static
-atf_error_t
+void
do_parent(atf_process_child_t *c,
const pid_t pid,
const stream_prepare_t *outsp,
const stream_prepare_t *errsp)
{
- atf_error_t err;
-
- err = atf_process_child_init(c);
- if (atf_is_error(err))
- goto out;
c->m_pid = pid;
parent_connect(outsp, &c->m_stdout);
parent_connect(errsp, &c->m_stderr);
-
-out:
- return err;
}
static
@@ -481,7 +468,7 @@ fork_with_streams(atf_process_child_t *c,
abort();
err = atf_no_error();
} else {
- err = do_parent(c, pid, &outsp, &errsp);
+ do_parent(c, pid, &outsp, &errsp);
if (atf_is_error(err))
goto err_errpipe;
}
@@ -528,6 +515,8 @@ atf_process_fork(atf_process_child_t *c,
atf_process_stream_t inherit_outsb, inherit_errsb;
const atf_process_stream_t *real_outsb, *real_errsb;
+ atf_process_child_init(c);
+
real_outsb = NULL; /* Shut up GCC warning. */
err = init_stream_w_default(outsb, &inherit_outsb, &real_outsb);
if (atf_is_error(err))
@@ -665,7 +654,7 @@ atf_process_exec_list(atf_process_status_t *s,
err = atf_process_exec_array(s, prog, argv2, outsb, errsb, prehook);
- free(argv2);
out:
+ free(argv2);
return err;
}
diff --git a/contrib/atf/atf-c/detail/process.h b/contrib/atf/atf-c/detail/process.h
index 81158d0a5a41..1efbaa2eec10 100644
--- a/contrib/atf/atf-c/detail/process.h
+++ b/contrib/atf/atf-c/detail/process.h
@@ -28,6 +28,7 @@
#include <sys/types.h>
+#include <signal.h>
#include <stdbool.h>
#include <atf-c/detail/fs.h>
@@ -76,7 +77,7 @@ int atf_process_stream_type(const atf_process_stream_t *);
* --------------------------------------------------------------------- */
struct atf_process_status {
- int m_status;
+ siginfo_t m_info;
};
typedef struct atf_process_status atf_process_status_t;
diff --git a/contrib/atf/atf-c/detail/process_test.c b/contrib/atf/atf-c/detail/process_test.c
index 82a911df68cd..1fa880b88932 100644
--- a/contrib/atf/atf-c/detail/process_test.c
+++ b/contrib/atf/atf-c/detail/process_test.c
@@ -26,9 +26,6 @@
#include "atf-c/detail/process.h"
#include <sys/types.h>
-#ifdef __FreeBSD__
-#include <sys/sysctl.h>
-#endif
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
@@ -47,7 +44,7 @@
#include "atf-c/detail/sanity.h"
#include "atf-c/detail/test_helpers.h"
-atf_error_t atf_process_status_init(atf_process_status_t *, int);
+atf_error_t atf_process_status_init(atf_process_status_t *, siginfo_t *);
/* ---------------------------------------------------------------------
* Auxiliary functions for testing of 'atf_process_fork'.
@@ -166,6 +163,7 @@ capture_stream_fini(void *v)
}
free(s->m_msg);
+ s->m_msg = NULL;
atf_process_stream_fini(&s->m_base.m_sb);
}
@@ -576,23 +574,19 @@ child_sigterm(void)
}
static
-int
-fork_and_wait_child(void (*child_func)(void))
+void
+fork_and_wait_child(void (*child_func)(void), siginfo_t *info)
{
pid_t pid;
- int status;
pid = fork();
ATF_REQUIRE(pid != -1);
if (pid == 0) {
- status = 0; /* Silence compiler warnings */
child_func();
UNREACHABLE;
} else {
- ATF_REQUIRE(waitpid(pid, &status, 0) != 0);
+ ATF_REQUIRE(waitid(P_PID, pid, info, WEXITED) != -1);
}
-
- return status;
}
ATF_TC(status_exited);
@@ -603,10 +597,12 @@ ATF_TC_HEAD(status_exited, tc)
}
ATF_TC_BODY(status_exited, tc)
{
+ siginfo_t info;
+
{
- const int rawstatus = fork_and_wait_child(child_exit_success);
+ fork_and_wait_child(child_exit_success, &info);
atf_process_status_t s;
- RE(atf_process_status_init(&s, rawstatus));
+ RE(atf_process_status_init(&s, &info));
ATF_CHECK(atf_process_status_exited(&s));
ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_SUCCESS);
ATF_CHECK(!atf_process_status_signaled(&s));
@@ -614,9 +610,9 @@ ATF_TC_BODY(status_exited, tc)
}
{
- const int rawstatus = fork_and_wait_child(child_exit_failure);
+ fork_and_wait_child(child_exit_failure, &info);
atf_process_status_t s;
- RE(atf_process_status_init(&s, rawstatus));
+ RE(atf_process_status_init(&s, &info));
ATF_CHECK(atf_process_status_exited(&s));
ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_FAILURE);
ATF_CHECK(!atf_process_status_signaled(&s));
@@ -632,10 +628,12 @@ ATF_TC_HEAD(status_signaled, tc)
}
ATF_TC_BODY(status_signaled, tc)
{
+ siginfo_t info;
+
{
- const int rawstatus = fork_and_wait_child(child_sigkill);
+ fork_and_wait_child(child_sigkill, &info);
atf_process_status_t s;
- RE(atf_process_status_init(&s, rawstatus));
+ RE(atf_process_status_init(&s, &info));
ATF_CHECK(!atf_process_status_exited(&s));
ATF_CHECK(atf_process_status_signaled(&s));
ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGKILL);
@@ -644,9 +642,9 @@ ATF_TC_BODY(status_signaled, tc)
}
{
- const int rawstatus = fork_and_wait_child(child_sigterm);
+ fork_and_wait_child(child_sigterm, &info);
atf_process_status_t s;
- RE(atf_process_status_init(&s, rawstatus));
+ RE(atf_process_status_init(&s, &info));
ATF_CHECK(!atf_process_status_exited(&s));
ATF_CHECK(atf_process_status_signaled(&s));
ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGTERM);
@@ -670,17 +668,22 @@ ATF_TC_BODY(status_coredump, tc)
atf_tc_skip("Cannot unlimit the core file size; check limits "
"manually");
-#ifdef __FreeBSD__
- int coredump_enabled;
- size_t ce_len = sizeof(coredump_enabled);
- if (sysctlbyname("kern.coredump", &coredump_enabled, &ce_len, NULL,
- 0) == 0 && !coredump_enabled)
- atf_tc_skip("Coredumps disabled");
+#if defined(__APPLE__)
+ /*
+ * The default security policy on macOS prevents this check from being
+ * tested (coredumps aren't generated for unsigned binaries).
+ *
+ * TODO(ngie,144): this test fails when run locally on my machines, but not
+ * in the GHA container images.
+ */
+ atf_tc_skip(
+ "atf_process_status_coredump check fails on macOS");
#endif
- const int rawstatus = fork_and_wait_child(child_sigquit);
+ siginfo_t info;
+ fork_and_wait_child(child_sigquit, &info);
atf_process_status_t s;
- RE(atf_process_status_init(&s, rawstatus));
+ RE(atf_process_status_init(&s, &info));
ATF_CHECK(!atf_process_status_exited(&s));
ATF_CHECK(atf_process_status_signaled(&s));
ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGQUIT);
diff --git a/contrib/atf/atf-c/detail/sanity_test.c b/contrib/atf/atf-c/detail/sanity_test.c
index a986c32ae3c8..7d4e39054d7e 100644
--- a/contrib/atf/atf-c/detail/sanity_test.c
+++ b/contrib/atf/atf-c/detail/sanity_test.c
@@ -85,6 +85,8 @@ do_test_child(void *v)
exit(EXIT_SUCCESS);
}
+#define MAX_LINES 3
+
static
void
do_test(enum type t, bool cond)
@@ -92,7 +94,7 @@ do_test(enum type t, bool cond)
atf_process_child_t child;
atf_process_status_t status;
int nlines;
- char *lines[3];
+ char *lines[MAX_LINES] = { 0 };
{
atf_process_stream_t outsb, errsb;
@@ -106,16 +108,17 @@ do_test(enum type t, bool cond)
}
nlines = 0;
- while (nlines < 3 && (lines[nlines] =
+ while (nlines < MAX_LINES && (lines[nlines] =
atf_utils_readline(atf_process_child_stderr(&child))) != NULL)
nlines++;
- ATF_REQUIRE(nlines == 0 || nlines == 3);
RE(atf_process_child_wait(&child, &status));
if (!cond) {
+ ATF_REQUIRE(nlines == MAX_LINES);
ATF_REQUIRE(atf_process_status_signaled(&status));
ATF_REQUIRE(atf_process_status_termsig(&status) == SIGABRT);
} else {
+ ATF_REQUIRE(nlines == 0);
ATF_REQUIRE(atf_process_status_exited(&status));
ATF_REQUIRE(atf_process_status_exitstatus(&status) == EXIT_SUCCESS);
}
diff --git a/contrib/atf/atf-c/detail/text.c b/contrib/atf/atf-c/detail/text.c
index 3b1d7e7fe2a4..f4da2c5a6990 100644
--- a/contrib/atf/atf-c/detail/text.c
+++ b/contrib/atf/atf-c/detail/text.c
@@ -56,6 +56,7 @@ atf_text_for_each_word(const char *instr, const char *sep,
}
free(str);
+ str = NULL;
out:
return err;
}
diff --git a/contrib/atf/atf-c/detail/tp_main.c b/contrib/atf/atf-c/detail/tp_main.c
index 439384b4950e..39cc29802f2d 100644
--- a/contrib/atf/atf-c/detail/tp_main.c
+++ b/contrib/atf/atf-c/detail/tp_main.c
@@ -198,8 +198,8 @@ params_fini(struct params *p)
atf_map_fini(&p->m_config);
atf_fs_path_fini(&p->m_resfile);
atf_fs_path_fini(&p->m_srcdir);
- if (p->m_tcname != NULL)
- free(p->m_tcname);
+ free(p->m_tcname);
+ p->m_tcname = NULL;
}
static
@@ -248,7 +248,7 @@ static
void
list_tcs(const atf_tp_t *tp)
{
- const atf_tc_t *const *tcs;
+ const atf_tc_t **tcs;
const atf_tc_t *const *tcsptr;
printf("Content-Type: application/X-atf-tp; version=\"1\"\n\n");
@@ -280,6 +280,8 @@ list_tcs(const atf_tp_t *tp)
atf_utils_free_charpp(vars);
}
+ free(tcs);
+ tcs = NULL;
}
/* ---------------------------------------------------------------------
@@ -288,19 +290,20 @@ list_tcs(const atf_tp_t *tp)
static
atf_error_t
-handle_tcarg(const char *tcarg, char **tcname, enum tc_part *tcpart)
+handle_tcarg(const char *tcarg, char **tcname_out, enum tc_part *tcpart)
{
+ char *delim, *tcname;
atf_error_t err;
- err = atf_no_error();
-
- *tcname = strdup(tcarg);
- if (*tcname == NULL) {
- err = atf_no_memory_error();
- goto out;
+ *tcname_out = NULL;
+ tcname = strdup(tcarg);
+ if (tcname == NULL) {
+ return atf_no_memory_error();
}
- char *delim = strchr(*tcname, ':');
+ err = atf_no_error();
+
+ delim = strchr(tcname, ':');
if (delim != NULL) {
*delim = '\0';
@@ -311,11 +314,12 @@ handle_tcarg(const char *tcarg, char **tcname, enum tc_part *tcpart)
*tcpart = CLEANUP;
} else {
err = usage_error("Invalid test case part `%s'", delim);
- goto out;
+ free(tcname);
}
}
-out:
+ if (!atf_is_error(err))
+ *tcname_out = tcname;
return err;
}
@@ -327,9 +331,7 @@ process_params(int argc, char **argv, struct params *p)
int ch;
int old_opterr;
- err = params_init(p, argv[0]);
- if (atf_is_error(err))
- goto out;
+ err = atf_no_error();
old_opterr = opterr;
opterr = 0;
@@ -387,10 +389,6 @@ process_params(int argc, char **argv, struct params *p)
}
}
- if (atf_is_error(err))
- params_fini(p);
-
-out:
return err;
}
@@ -484,12 +482,10 @@ run_tc(const atf_tp_t *tp, struct params *p, int *exitcode)
{
atf_error_t err;
- err = atf_no_error();
+ if (!atf_tp_has_tc(tp, p->m_tcname))
+ return usage_error("Unknown test case `%s'", p->m_tcname);
- if (!atf_tp_has_tc(tp, p->m_tcname)) {
- err = usage_error("Unknown test case `%s'", p->m_tcname);
- goto out;
- }
+ err = atf_no_error();
if (!atf_env_has("__RUNNING_INSIDE_ATF_RUN") || strcmp(atf_env_get(
"__RUNNING_INSIDE_ATF_RUN"), "internal-yes-value") != 0)
@@ -529,7 +525,6 @@ run_tc(const atf_tp_t *tp, struct params *p, int *exitcode)
}
INV(!atf_is_error(err));
-out:
return err;
}
@@ -544,10 +539,14 @@ controlled_main(int argc, char **argv,
atf_tp_t tp;
char **raw_config;
- err = process_params(argc, argv, &p);
+ err = params_init(&p, argv[0]);
if (atf_is_error(err))
goto out;
+ err = process_params(argc, argv, &p);
+ if (atf_is_error(err))
+ goto out_p;
+
err = handle_srcdir(&p);
if (atf_is_error(err))
goto out_p;
@@ -594,12 +593,6 @@ atf_tp_main(int argc, char **argv, atf_error_t (*add_tcs_hook)(atf_tp_t *))
else
progname++;
- /* Libtool workaround: if running from within the source tree (binaries
- * that are not installed yet), skip the "lt-" prefix added to files in
- * the ".libs" directory to show the real (not temporary) name. */
- if (strncmp(progname, "lt-", 3) == 0)
- progname += 3;
-
exitcode = EXIT_FAILURE; /* Silence GCC warning. */
err = controlled_main(argc, argv, add_tcs_hook, &exitcode);
if (atf_is_error(err)) {
diff --git a/contrib/atf/atf-c/error.c b/contrib/atf/atf-c/error.c
index 071daf6d2455..2cbee272700d 100644
--- a/contrib/atf/atf-c/error.c
+++ b/contrib/atf/atf-c/error.c
@@ -32,7 +32,7 @@
#include "atf-c/detail/sanity.h"
-/* Theoretically, there can only be a single error intance at any given
+/* Theoretically, there can only be a single error instance at any given
* point in time, because errors are raised at one point and must be
* handled immediately. If another error has to be raised during the
* handling process, something else has to be done with the previous
@@ -124,11 +124,13 @@ atf_error_free(atf_error_t err)
freeit = err->m_free;
- if (err->m_data != NULL)
- free(err->m_data);
+ free(err->m_data);
+ err->m_data = NULL;
- if (freeit)
+ if (freeit) {
free(err);
+ err = NULL;
+ }
error_on_flight = false;
}
diff --git a/contrib/atf/atf-c/macros.h b/contrib/atf/atf-c/macros.h
index abcb9f697907..94279a6a3057 100644
--- a/contrib/atf/atf-c/macros.h
+++ b/contrib/atf/atf-c/macros.h
@@ -129,26 +129,26 @@
#define ATF_REQUIRE_MSG(expression, fmt, ...) \
do { \
- if (!(expression)) \
+ if (expression) {} else \
atf_tc_fail_requirement(__FILE__, __LINE__, fmt, ##__VA_ARGS__); \
} while(0)
#define ATF_CHECK_MSG(expression, fmt, ...) \
do { \
- if (!(expression)) \
+ if (expression) {} else \
atf_tc_fail_check(__FILE__, __LINE__, fmt, ##__VA_ARGS__); \
} while(0)
#define ATF_REQUIRE(expression) \
do { \
- if (!(expression)) \
+ if (expression) {} else \
atf_tc_fail_requirement(__FILE__, __LINE__, "%s", \
#expression " not met"); \
} while(0)
#define ATF_CHECK(expression) \
do { \
- if (!(expression)) \
+ if (expression) {} else \
atf_tc_fail_check(__FILE__, __LINE__, "%s", \
#expression " not met"); \
} while(0)
diff --git a/contrib/atf/atf-c/tc.c b/contrib/atf/atf-c/tc.c
index 1cef6adbd82d..6ba0a7f2a3c8 100644
--- a/contrib/atf/atf-c/tc.c
+++ b/contrib/atf/atf-c/tc.c
@@ -26,7 +26,7 @@
#include "atf-c/tc.h"
#include <sys/types.h>
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__)
#include <sys/linker.h>
#include <sys/module.h>
#endif
@@ -107,9 +107,7 @@ static void format_reason_fmt(atf_dynstr_t *, const char *, const size_t,
static void errno_test(struct context *, const char *, const size_t,
const int, const char *, const bool,
void (*)(struct context *, atf_dynstr_t *));
-#ifdef __FreeBSD__
static atf_error_t check_kmod(struct context *, const char *);
-#endif
static atf_error_t check_prog_in_dir(const char *, void *);
static atf_error_t check_prog(struct context *, const char *);
@@ -144,7 +142,7 @@ context_set_resfile(struct context *ctx, const char *resfile)
else if (strcmp(resfile, "/dev/stderr") == 0)
ctx->resfilefd = STDERR_FILENO;
else
- ctx->resfilefd = open(resfile, O_WRONLY | O_CREAT | O_TRUNC,
+ ctx->resfilefd = open(resfile, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (ctx->resfilefd == -1) {
err = atf_libc_error(errno,
@@ -467,8 +465,8 @@ errno_test(struct context *ctx, const char *file, const size_t line,
}
}
-#ifdef __FreeBSD__
-static atf_error_t
+#if defined(__FreeBSD__)
+atf_error_t
check_kmod(struct context *ctx, const char *kmod)
{
struct kld_file_stat fstat = { .version = sizeof(fstat) };
@@ -478,26 +476,41 @@ check_kmod(struct context *ctx, const char *kmod)
int fid, mid;
for (fid = kldnext(0); fid > 0; fid = kldnext(fid)) {
- if (kldstat(fid, &fstat) != 0)
- continue;
- if (strcmp(fstat.name, kmod) == 0)
- goto done;
- if (strncmp(fstat.name, kmod, len) == 0 &&
- strcmp(fstat.name + len, ".ko") == 0)
- goto done;
- for (mid = kldfirstmod(fid); mid > 0; mid = modfnext(mid)) {
- if (modstat(mid, &mstat) != 0)
- continue;
- if (strcmp(mstat.name, kmod) == 0)
- goto done;
- }
+ if (kldstat(fid, &fstat) != 0)
+ continue;
+
+ if (strcmp(fstat.name, kmod) == 0)
+ goto done;
+
+ if (strncmp(fstat.name, kmod, len) == 0 &&
+ strcmp(fstat.name + len, ".ko") == 0)
+ goto done;
+
+ for (mid = kldfirstmod(fid); mid > 0; mid = modfnext(mid)) {
+ if (modstat(mid, &mstat) != 0)
+ continue;
+ if (strcmp(mstat.name, kmod) == 0)
+ goto done;
+ }
}
- format_reason_fmt(&reason, NULL, 0, "The required kmod %s "
- "is not loaded", kmod);
+ format_reason_fmt(&reason, NULL, 0,
+ "The required kmod %s is not loaded", kmod);
fail_requirement(ctx, &reason);
+
done:
return atf_no_error();
}
+#else
+atf_error_t
+check_kmod(struct context *ctx, const char *kmod ATF_DEFS_ATTRIBUTE_UNUSED)
+{
+ atf_dynstr_t reason;
+
+ format_reason_fmt(&reason, NULL, 0,
+ "This API is only available on FreeBSD");
+ fail_requirement(ctx, &reason);
+ return atf_no_error();
+}
#endif
struct prog_found_pair {
@@ -688,8 +701,10 @@ atf_tc_init_pack(atf_tc_t *tc, const atf_tc_pack_t *pack,
void
atf_tc_fini(atf_tc_t *tc)
{
+ atf_map_fini(&tc->pimpl->m_config);
atf_map_fini(&tc->pimpl->m_vars);
free(tc->pimpl);
+ tc->pimpl = NULL;
}
/*
@@ -851,8 +866,10 @@ atf_tc_set_md_var(atf_tc_t *tc, const char *name, const char *fmt, ...)
if (!atf_is_error(err))
err = atf_map_insert(&tc->pimpl->m_vars, name, value, true);
- else
+ else {
free(value);
+ value = NULL;
+ }
return err;
}
@@ -869,9 +886,7 @@ static void _atf_tc_fail_check(struct context *, const char *, const size_t,
static void _atf_tc_fail_requirement(struct context *, const char *,
const size_t, const char *, va_list) ATF_DEFS_ATTRIBUTE_NORETURN;
static void _atf_tc_pass(struct context *) ATF_DEFS_ATTRIBUTE_NORETURN;
-#ifdef __FreeBSD__
static void _atf_tc_require_kmod(struct context *, const char *);
-#endif
static void _atf_tc_require_prog(struct context *, const char *);
static void _atf_tc_skip(struct context *, const char *, va_list)
ATF_DEFS_ATTRIBUTE_NORETURN;
@@ -951,13 +966,11 @@ _atf_tc_pass(struct context *ctx)
UNREACHABLE;
}
-#ifdef __FreeBSD__
static void
-_atf_tc_require_kmod(struct context *ctx, const char *kmod)
+_atf_tc_require_kmod(struct context *ctx, const char *prog)
{
- check_fatal_error(check_kmod(ctx, kmod));
+ check_fatal_error(check_kmod(ctx, prog));
}
-#endif
static void
_atf_tc_require_prog(struct context *ctx, const char *prog)
@@ -1205,7 +1218,6 @@ atf_tc_pass(void)
_atf_tc_pass(&Current);
}
-#ifdef __FreeBSD__
void
atf_tc_require_kmod(const char *kmod)
{
@@ -1213,7 +1225,6 @@ atf_tc_require_kmod(const char *kmod)
_atf_tc_require_kmod(&Current, kmod);
}
-#endif
void
atf_tc_require_prog(const char *prog)
diff --git a/contrib/atf/atf-c/tc.h b/contrib/atf/atf-c/tc.h
index 5109102750c7..dda704f8cff8 100644
--- a/contrib/atf/atf-c/tc.h
+++ b/contrib/atf/atf-c/tc.h
@@ -106,9 +106,7 @@ void atf_tc_fail_nonfatal(const char *, ...)
ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 2);
void atf_tc_pass(void)
ATF_DEFS_ATTRIBUTE_NORETURN;
-#ifdef __FreeBSD__
void atf_tc_require_kmod(const char *);
-#endif
void atf_tc_require_prog(const char *);
void atf_tc_skip(const char *, ...)
ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 2)
diff --git a/contrib/atf/atf-c/tc_test.c b/contrib/atf/atf-c/tc_test.c
index 616c37e94e68..e896c6b3c2a1 100644
--- a/contrib/atf/atf-c/tc_test.c
+++ b/contrib/atf/atf-c/tc_test.c
@@ -156,6 +156,84 @@ ATF_TC_BODY(config, tcin)
atf_tc_fini(&tc);
}
+#if defined(__FreeBSD__)
+ATF_TC(require_kmod_basic);
+ATF_TC_HEAD(require_kmod_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "atf_require_kmod: ensures that a test continues if the target kmod "
+ "is found.");
+}
+ATF_TC_BODY(require_kmod_basic, tc)
+{
+#if 0
+ atf_tc_require_kmod("kernel");
+#endif
+}
+
+ATF_TC(require_kmod_negative);
+ATF_TC_HEAD(require_kmod_negative, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "atf_require_kmod: skips test if the target kmod is not found.");
+}
+ATF_TC_BODY(require_kmod_negative, tc)
+{
+ atf_tc_expect_fail("This should fail.");
+ atf_tc_require_kmod("nonexistent");
+}
+#endif
+
+ATF_TC(require_prog_absolute);
+ATF_TC_HEAD(require_prog_absolute, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "atf_require_prog: ensures that a test continues if the target program "
+ "is found (absolute).");
+}
+ATF_TC_BODY(require_prog_absolute, tc)
+{
+ atf_tc_require_prog("/bin/sh");
+}
+
+ATF_TC(require_prog_negative_absolute);
+ATF_TC_HEAD(require_prog_negative_absolute, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "atf_require_prog: skips test if the target program is not found "
+ "(absolute).");
+}
+ATF_TC_BODY(require_prog_negative_absolute, tc)
+{
+ atf_tc_expect_fail("This should fail.");
+ atf_tc_require_prog("/nonexistent");
+}
+
+ATF_TC(require_prog_negative_nonabsolute);
+ATF_TC_HEAD(require_prog_negative_nonabsolute, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "atf_require_prog: skips test if the target program is not found "
+ "(non-absolute).");
+}
+ATF_TC_BODY(require_prog_negative_nonabsolute, tc)
+{
+ atf_tc_expect_fail("This should fail.");
+ atf_tc_require_prog("nonexistent");
+}
+
+ATF_TC(require_prog_nonabsolute);
+ATF_TC_HEAD(require_prog_nonabsolute, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "atf_require_prog: ensures that a test continues if the target program "
+ "is found (non-absolute).");
+}
+ATF_TC_BODY(require_prog_nonabsolute, tc)
+{
+ atf_tc_require_prog("true");
+}
+
/* ---------------------------------------------------------------------
* Test cases for the free functions.
* --------------------------------------------------------------------- */
@@ -175,6 +253,14 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, init_pack);
ATF_TP_ADD_TC(tp, vars);
ATF_TP_ADD_TC(tp, config);
+#if defined(__FreeBSD__)
+ ATF_TP_ADD_TC(tp, require_kmod_basic);
+ ATF_TP_ADD_TC(tp, require_kmod_negative);
+#endif
+ ATF_TP_ADD_TC(tp, require_prog_absolute);
+ ATF_TP_ADD_TC(tp, require_prog_negative_absolute);
+ ATF_TP_ADD_TC(tp, require_prog_negative_nonabsolute);
+ ATF_TP_ADD_TC(tp, require_prog_nonabsolute);
/* Add the test cases for the free functions. */
/* TODO */
diff --git a/contrib/atf/atf-c/tp.c b/contrib/atf/atf-c/tp.c
index f4f225772ca2..e3155287d722 100644
--- a/contrib/atf/atf-c/tp.c
+++ b/contrib/atf/atf-c/tp.c
@@ -112,6 +112,7 @@ atf_tp_fini(atf_tp_t *tp)
atf_list_fini(&tp->pimpl->m_tcs);
free(tp->pimpl);
+ tp->pimpl = NULL;
}
/*
@@ -139,7 +140,7 @@ atf_tp_get_tc(const atf_tp_t *tp, const char *id)
return tc;
}
-const atf_tc_t *const *
+const atf_tc_t **
atf_tp_get_tcs(const atf_tp_t *tp)
{
const atf_tc_t **array;
diff --git a/contrib/atf/atf-c/tp.h b/contrib/atf/atf-c/tp.h
index c176f7d96f5e..121aaab3428e 100644
--- a/contrib/atf/atf-c/tp.h
+++ b/contrib/atf/atf-c/tp.h
@@ -50,7 +50,7 @@ void atf_tp_fini(atf_tp_t *);
char **atf_tp_get_config(const atf_tp_t *);
bool atf_tp_has_tc(const atf_tp_t *, const char *);
const struct atf_tc *atf_tp_get_tc(const atf_tp_t *, const char *);
-const struct atf_tc *const *atf_tp_get_tcs(const atf_tp_t *);
+const struct atf_tc **atf_tp_get_tcs(const atf_tp_t *);
/* Modifiers. */
atf_error_t atf_tp_add_tc(atf_tp_t *, struct atf_tc *);
diff --git a/contrib/atf/atf-c/tp_test.c b/contrib/atf/atf-c/tp_test.c
index de334a97483b..03ef4b2660fd 100644
--- a/contrib/atf/atf-c/tp_test.c
+++ b/contrib/atf/atf-c/tp_test.c
@@ -23,6 +23,7 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+#include "config.h"
#include "atf-c/tp.h"
#include <string.h>
diff --git a/contrib/atf/atf-c/utils.c b/contrib/atf/atf-c/utils.c
index d8355bc68936..70b68adf0943 100644
--- a/contrib/atf/atf-c/utils.c
+++ b/contrib/atf/atf-c/utils.c
@@ -32,6 +32,7 @@
#include <errno.h>
#include <fcntl.h>
#include <regex.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -59,16 +60,19 @@ init_out_filename(atf_dynstr_t *name, const pid_t pid, const char *suffix,
{
atf_error_t error;
- error = atf_dynstr_init_fmt(name, "atf_utils_fork_%d_%s.txt",
- (int)pid, suffix);
- if (atf_is_error(error)) {
- char buffer[1024];
- atf_error_format(error, buffer, sizeof(buffer));
- if (in_parent) {
- atf_tc_fail("Failed to create output file: %s", buffer);
- } else {
- err(EXIT_FAILURE, "Failed to create output file: %s", buffer);
- }
+ error = atf_dynstr_init_fmt(name, "atf_utils_fork_%d_%s.txt", pid, suffix);
+ if (!atf_is_error(error))
+ return;
+
+ char buffer[1024];
+
+ atf_error_format(error, buffer, sizeof(buffer));
+ atf_error_free(error);
+
+ if (in_parent) {
+ atf_tc_fail("Failed to create output file: %s", buffer);
+ } else {
+ err(EXIT_FAILURE, "Failed to create output file: %s", buffer);
}
}
@@ -104,8 +108,8 @@ grep_string(const char *regex, const char *str)
void
atf_utils_cat_file(const char *name, const char *prefix)
{
- const int fd = open(name, O_RDONLY);
- ATF_REQUIRE_MSG(fd != -1, "Cannot open %s", name);
+ const int fd = open(name, O_RDONLY | O_CLOEXEC);
+ ATF_REQUIRE_MSG(fd != -1, "Cannot open %s: %s", name, strerror(errno));
char buffer[1024];
ssize_t count;
@@ -145,7 +149,7 @@ atf_utils_cat_file(const char *name, const char *prefix)
bool
atf_utils_compare_file(const char *name, const char *contents)
{
- const int fd = open(name, O_RDONLY);
+ const int fd = open(name, O_RDONLY | O_CLOEXEC);
ATF_REQUIRE_MSG(fd != -1, "Cannot open %s", name);
const char *pos = contents;
@@ -173,11 +177,12 @@ atf_utils_compare_file(const char *name, const char *contents)
void
atf_utils_copy_file(const char *source, const char *destination)
{
- const int input = open(source, O_RDONLY);
+ const int input = open(source, O_RDONLY | O_CLOEXEC);
ATF_REQUIRE_MSG(input != -1, "Failed to open source file during "
"copy (%s)", source);
- const int output = open(destination, O_WRONLY | O_CREAT | O_TRUNC, 0777);
+ const int output = open(destination,
+ O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0777);
ATF_REQUIRE_MSG(output != -1, "Failed to open destination file during "
"copy (%s)", destination);
@@ -216,7 +221,7 @@ atf_utils_create_file(const char *name, const char *contents, ...)
va_end(ap);
ATF_REQUIRE(!atf_is_error(error));
- const int fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ const int fd = open(name, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
ATF_REQUIRE_MSG(fd != -1, "Cannot create file %s", name);
ATF_REQUIRE(write(fd, atf_dynstr_cstring(&formatted),
atf_dynstr_length(&formatted)) != -1);
@@ -234,14 +239,12 @@ bool
atf_utils_file_exists(const char *path)
{
const int ret = access(path, F_OK);
- if (ret == -1) {
- if (errno != ENOENT)
- atf_tc_fail("Failed to check the existence of %s: %s", path,
- strerror(errno));
- else
- return false;
- } else
+ if (ret != -1)
return true;
+ if (errno != ENOENT)
+ atf_tc_fail("Failed to check the existence of %s: %s", path,
+ strerror(errno));
+ return false;
}
/** Spawns a subprocess and redirects its output to files.
@@ -290,10 +293,13 @@ atf_utils_free_charpp(char **argv)
{
char **ptr;
- for (ptr = argv; *ptr != NULL; ptr++)
+ for (ptr = argv; *ptr != NULL; ptr++) {
free(*ptr);
+ *ptr = NULL;
+ }
free(argv);
+ argv = NULL;
}
/** Searches for a regexp in a file.
@@ -316,7 +322,8 @@ atf_utils_grep_file(const char *regex, const char *file, ...)
va_end(ap);
ATF_REQUIRE(!atf_is_error(error));
- ATF_REQUIRE((fd = open(file, O_RDONLY)) != -1);
+ fd = open(file, O_RDONLY | O_CLOEXEC);
+ ATF_REQUIRE_MSG(fd != -1, "Cannot open %s: %s", file, strerror(errno));
bool found = false;
char *line = NULL;
while (!found && (line = atf_utils_readline(fd)) != NULL) {
@@ -404,7 +411,8 @@ atf_utils_redirect(const int target_fd, const char *name)
else if (target_fd == STDERR_FILENO)
fflush(stderr);
- const int new_fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ const int new_fd = open(name, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
+ 0644);
if (new_fd == -1)
err(EXIT_FAILURE, "Cannot create %s", name);
if (new_fd != target_fd) {
@@ -425,8 +433,9 @@ void
atf_utils_wait(const pid_t pid, const int exitstatus, const char *expout,
const char *experr)
{
- int status;
- ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
+ siginfo_t info;
+ ATF_REQUIRE(waitid(P_PID, pid, &info, WEXITED) != -1);
+ ATF_REQUIRE(info.si_pid == pid);
atf_dynstr_t out_name;
init_out_filename(&out_name, pid, "out", true);
@@ -437,8 +446,8 @@ atf_utils_wait(const pid_t pid, const int exitstatus, const char *expout,
atf_utils_cat_file(atf_dynstr_cstring(&out_name), "subprocess stdout: ");
atf_utils_cat_file(atf_dynstr_cstring(&err_name), "subprocess stderr: ");
- ATF_REQUIRE(WIFEXITED(status));
- ATF_REQUIRE_EQ(exitstatus, WEXITSTATUS(status));
+ ATF_REQUIRE(info.si_code == CLD_EXITED);
+ ATF_REQUIRE_EQ(exitstatus, info.si_status);
const char *save_prefix = "save:";
const size_t save_prefix_length = strlen(save_prefix);
@@ -463,4 +472,7 @@ atf_utils_wait(const pid_t pid, const int exitstatus, const char *expout,
ATF_REQUIRE(unlink(atf_dynstr_cstring(&out_name)) != -1);
ATF_REQUIRE(unlink(atf_dynstr_cstring(&err_name)) != -1);
+
+ atf_dynstr_fini(&out_name);
+ atf_dynstr_fini(&err_name);
}
diff --git a/contrib/atf/atf-c/utils.h b/contrib/atf/atf-c/utils.h
index 422186a31e76..8764cc506105 100644
--- a/contrib/atf/atf-c/utils.h
+++ b/contrib/atf/atf-c/utils.h
@@ -26,6 +26,7 @@
#if !defined(ATF_C_UTILS_H)
#define ATF_C_UTILS_H
+#include <sys/types.h>
#include <stdbool.h>
#include <unistd.h>
diff --git a/contrib/atf/atf-sh/.gitignore b/contrib/atf/atf-sh/.gitignore
deleted file mode 100644
index a29438f1a9b8..000000000000
--- a/contrib/atf/atf-sh/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-atf-check
-atf-sh
diff --git a/contrib/atf/atf-sh/Kyuafile b/contrib/atf/atf-sh/Kyuafile
index 01a9253e7ebd..f128e3cb88a9 100644
--- a/contrib/atf/atf-sh/Kyuafile
+++ b/contrib/atf/atf-sh/Kyuafile
@@ -9,3 +9,4 @@ atf_test_program{name="config_test"}
atf_test_program{name="atf-check_test"}
atf_test_program{name="atf_check_test"}
atf_test_program{name="integration_test"}
+atf_test_program{name="kmod_test"}
diff --git a/contrib/atf/atf-sh/Kyuafile.in b/contrib/atf/atf-sh/Kyuafile.in
new file mode 100644
index 000000000000..01a9253e7ebd
--- /dev/null
+++ b/contrib/atf/atf-sh/Kyuafile.in
@@ -0,0 +1,11 @@
+syntax("kyuafile", 1)
+
+test_suite("atf")
+
+atf_test_program{name="tc_test"}
+atf_test_program{name="tp_test"}
+atf_test_program{name="normalize_test"}
+atf_test_program{name="config_test"}
+atf_test_program{name="atf-check_test"}
+atf_test_program{name="atf_check_test"}
+atf_test_program{name="integration_test"}
diff --git a/contrib/atf/atf-sh/atf-check.1 b/contrib/atf/atf-sh/atf-check.1
index b03058e8442c..18d000a8750c 100644
--- a/contrib/atf/atf-sh/atf-check.1
+++ b/contrib/atf/atf-sh/atf-check.1
@@ -22,7 +22,7 @@
.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.Dd June 21, 2020
+.Dd August 13, 2026
.Dt ATF-CHECK 1
.Os
.Sh NAME
@@ -34,11 +34,12 @@
.Op Fl o Ar action:arg ...
.Op Fl e Ar action:arg ...
.Op Fl x
+.Op Fl r Ar timeout[:interval]
.Ar command
.Sh DESCRIPTION
.Nm
executes a given command and analyzes its results, including
-exit code, stdout and stderr.
+exit code, stdout, and stderr.
.Pp
.Bf Em
Test cases must use
@@ -47,24 +48,27 @@ Test cases must use
builtin function instead of calling this utility directly.
.Ef
.Pp
-In the first synopsis form,
.Nm
will execute the provided command and apply checks specified
by arguments.
-By default it will act as if it was run with
+By default
+.Nm
+acts as if it was run with
.Fl s
.Ar exit:0
.Fl o
.Ar empty
.Fl e
.Ar empty .
-Multiple checks for the same output channel are allowed and, if specified,
-their results will be combined as a logical and (meaning that the output must
-match all the provided checks).
.Pp
-In the second synopsis form,
-.Nm
-will print information about all supported options and their purpose.
+.Fl o
+.Ar empty
+and
+.Fl e
+.Ar empty
+may be specified multiple times.
+If they are specified multiple times, the checks will be applied to
+the appropriate stream in the order they were provided.
.Pp
The following options are available:
.Bl -tag -width XqualXvalueXX
@@ -80,11 +84,11 @@ accepted.
.It Ar ignore
ignores the exit check.
.It Ar signal:<value>
-checks that the program exited due to a signal and that the signal that
-terminated it is
+checks that the program exited due to a signal, and (optionally) checks that the
+signal which terminated the process is
.Va value .
-The signal can be specified both as a number or as a name, or it can also
-be omitted altogether, in which case any signal is accepted.
+The signal can be specified as a number, a name, or it can be omitted
+altogether (in which case any signal is accepted).
.El
.Pp
Most of these checkers can be prefixed by the
@@ -112,7 +116,9 @@ Most of these checkers can be prefixed by the
.Sq not-
string, which effectively reverses the check.
.It Fl e Ar action:arg
-Analyzes standard error (syntax identical to above)
+Analyzes standard error.
+The usage is identical to
+.Fl o .
.It Fl x
Executes
.Ar command
@@ -150,15 +156,15 @@ instead of executing
directly:
.Bd -literal -offset indent
# Exit code 0, nothing on stdout/stderr
-atf_check 'true'
+atf_check true
# Typical usage if failure is expected
-atf_check -s not-exit:0 'false'
+atf_check -s not-exit:0 false
# Checking stdout/stderr
echo foobar >expout
atf_check -o file:expout -e inline:"xx\etyy\en" \e
- 'echo foobar ; printf "xx\etyy\en" >&2'
+ -x 'echo foobar ; printf "xx\etyy\en" >&2'
# Checking for a crash
atf_check -s signal:sigsegv my_program
diff --git a/contrib/atf/atf-sh/atf-check.cpp b/contrib/atf/atf-sh/atf-check.cpp
index 911e004432f3..819ff7e9c82b 100644
--- a/contrib/atf/atf-sh/atf-check.cpp
+++ b/contrib/atf/atf-sh/atf-check.cpp
@@ -30,6 +30,7 @@ extern "C" {
#include <limits.h>
#include <signal.h>
#include <stdint.h>
+#include <time.h>
#include <unistd.h>
}
@@ -46,7 +47,6 @@ extern "C" {
#include "atf-c++/check.hpp"
#include "atf-c++/detail/application.hpp"
-#include "atf-c++/detail/auto_array.hpp"
#include "atf-c++/detail/env.hpp"
#include "atf-c++/detail/exceptions.hpp"
#include "atf-c++/detail/fs.hpp"
@@ -74,12 +74,14 @@ struct status_check {
status_check_t type;
bool negated;
int value;
+ bool empty;
status_check(const status_check_t& p_type, const bool p_negated,
- const int p_value) :
+ const int p_value, const bool p_empty) :
type(p_type),
negated(p_negated),
- value(p_value)
+ value(p_value),
+ empty(p_empty)
{
}
};
@@ -119,23 +121,30 @@ public:
const atf::fs::path file = atf::fs::path(
atf::env::get("TMPDIR", "/tmp")) / pattern;
- atf::auto_array< char > buf(new char[file.str().length() + 1]);
- std::strcpy(buf.get(), file.c_str());
-
- m_fd = ::mkstemp(buf.get());
+ std::string file_s = file.str();
+ // C++14 returns const char* with `std::string::data()`.
+ //
+ // TODO(ngie): remove the else block and simplify once we are on C++17
+ // or later.
+#if __cplusplus >= 201703L
+ char *file_ch_arr = file_s.data();
+#else
+ char *file_ch_arr = &file_s[0];
+#endif
+ m_fd = ::mkstemp(file_ch_arr);
if (m_fd == -1)
throw atf::system_error("atf_check::temp_file::temp_file(" +
- file.str() + ")", "mkstemp(3) failed",
+ file_s + ")", "mkstemp(3) failed",
errno);
- m_path.reset(new atf::fs::path(buf.get()));
+ m_path.reset(new atf::fs::path(file_ch_arr));
}
~temp_file(void)
{
close();
try {
- remove(*m_path);
+ atf::fs::remove(*m_path);
} catch (const atf::system_error&) {
// Ignore deletion errors.
}
@@ -200,11 +209,11 @@ parse_exit_code(const std::string& str)
try {
const int value = atf::text::to_type< int >(str);
if (value < 0 || value > 255)
- throw std::runtime_error("Unused reason");
+ throw std::range_error("Unused reason");
return value;
- } catch (const std::runtime_error&) {
+ } catch (const std::range_error&) {
throw atf::application::usage_error("Invalid exit code for -s option; "
- "must be an integer in range 0-255");
+ "must be an integer in the range [0, 255]");
}
}
@@ -267,6 +276,7 @@ parse_status_check_arg(const std::string& arg)
const std::string value_str = (
delimiter == std::string::npos ? "" : arg.substr(delimiter + 1));
int value;
+ bool empty = false;
status_check_t type;
if (action == "eq") {
@@ -278,9 +288,10 @@ parse_status_check_arg(const std::string& arg)
value = parse_exit_code(value_str);
} else if (action == "exit") {
type = sc_exit;
- if (value_str.empty())
+ if (value_str.empty()) {
value = INT_MIN;
- else
+ empty = true;
+ } else
value = parse_exit_code(value_str);
} else if (action == "ignore") {
if (negated)
@@ -296,14 +307,15 @@ parse_status_check_arg(const std::string& arg)
value = parse_exit_code(value_str);
} else if (action == "signal") {
type = sc_signal;
- if (value_str.empty())
+ if (value_str.empty()) {
value = INT_MIN;
- else
+ empty = true;
+ } else
value = parse_signal(value_str);
} else
throw atf::application::usage_error("Invalid status checker");
- return status_check(type, negated, value);
+ return status_check(type, negated, value, empty);
}
static
@@ -435,8 +447,8 @@ execute_with_shell(char* const* argv)
{
const std::string cmd = flatten_argv(argv);
const std::string shell = atf::env::get("ATF_SHELL", ATF_SHELL);
-
const char* sh_argv[4];
+
sh_argv[0] = shell.c_str();
sh_argv[1] = "-c";
sh_argv[2] = cmd.c_str();
@@ -599,7 +611,7 @@ run_status_check(const status_check& sc, const atf::check::check_result& cr)
bool result;
if (sc.type == sc_exit) {
- if (cr.exited() && sc.value != INT_MIN) {
+ if (cr.exited() && !sc.empty) {
const int status = cr.exitcode();
if (!sc.negated && sc.value != status) {
@@ -614,7 +626,7 @@ run_status_check(const status_check& sc, const atf::check::check_result& cr)
result = false;
} else
result = true;
- } else if (cr.exited() && sc.value == INT_MIN) {
+ } else if (cr.exited() && sc.empty) {
result = true;
} else {
std::cerr << "Fail: program did not exit cleanly\n";
@@ -623,7 +635,7 @@ run_status_check(const status_check& sc, const atf::check::check_result& cr)
} else if (sc.type == sc_ignore) {
result = true;
} else if (sc.type == sc_signal) {
- if (cr.signaled() && sc.value != INT_MIN) {
+ if (cr.signaled() && !sc.empty) {
const int status = cr.termsig();
if (!sc.negated && sc.value != status) {
@@ -637,7 +649,7 @@ run_status_check(const status_check& sc, const atf::check::check_result& cr)
result = false;
} else
result = true;
- } else if (cr.signaled() && sc.value == INT_MIN) {
+ } else if (cr.signaled() && sc.empty) {
result = true;
} else {
std::cerr << "Fail: program did not receive a signal\n";
@@ -678,7 +690,7 @@ run_status_checks(const std::vector< status_check >& checks,
static
bool
-run_output_check(const output_check oc, const atf::fs::path& path,
+run_output_check(const output_check& oc, const atf::fs::path& path,
const std::string& stdxxx)
{
bool result;
@@ -903,9 +915,10 @@ atf_check::main(void)
int status = EXIT_FAILURE;
- if (m_status_checks.empty())
- m_status_checks.push_back(status_check(sc_exit, false, EXIT_SUCCESS));
- else if (m_status_checks.size() > 1) {
+ if (m_status_checks.empty()) {
+ m_status_checks.push_back(status_check(sc_exit, false, EXIT_SUCCESS,
+ false));
+ } else if (m_status_checks.size() > 1) {
// TODO: Remove this restriction.
throw atf::application::usage_error("Cannot specify -s more than once");
}
diff --git a/contrib/atf/atf-sh/atf-check_test.sh b/contrib/atf/atf-sh/atf-check_test.sh
index 91d024a85bcd..3d2e78438640 100644
--- a/contrib/atf/atf-sh/atf-check_test.sh
+++ b/contrib/atf/atf-sh/atf-check_test.sh
@@ -397,9 +397,9 @@ unusual_umask_head()
unusual_umask_body()
{
for mask in 022 027 0222 0177 0777 ; do
- umask $mask
+ umask ${mask}
${Atf_Check} true || \
- atf_fail "atf-check failed with umask $mask"
+ atf_fail "atf-check failed with umask ${mask}"
done
umask 022
}
diff --git a/contrib/atf/atf-sh/atf-sh.3 b/contrib/atf/atf-sh/atf-sh.3
index 5e53ceb45a06..42dbffc15f07 100644
--- a/contrib/atf/atf-sh/atf-sh.3
+++ b/contrib/atf/atf-sh/atf-sh.3
@@ -383,7 +383,7 @@ atf_check -s exit:0 -o file:expout -e empty echo foo
# Generate a file for later inspection
atf_check -s exit:0 -o save:stdout -e empty ls
-grep foo ls || atf_fail "foo file not found in listing"
+grep foo stdout || atf_fail "foo file not found in listing"
# Or just do the match along the way
atf_check -s exit:0 -o match:"^foo$" -e empty ls
diff --git a/contrib/atf/atf-sh/atf-sh.cpp b/contrib/atf/atf-sh/atf-sh.cpp
index 997557322e45..90d89745e713 100644
--- a/contrib/atf/atf-sh/atf-sh.cpp
+++ b/contrib/atf/atf-sh/atf-sh.cpp
@@ -31,6 +31,8 @@ extern "C" {
#include <cstdlib>
#include <cstring>
#include <iostream>
+#include <utility>
+#include <vector>
#include "atf-c++/detail/application.hpp"
#include "atf-c++/detail/env.hpp"
@@ -55,7 +57,7 @@ fix_plain_name(const char *filename)
}
static
-std::string*
+std::string
construct_script(const char* filename)
{
const std::string libexecdir = atf::env::get(
@@ -64,37 +66,35 @@ construct_script(const char* filename)
"ATF_PKGDATADIR", ATF_PKGDATADIR);
const std::string shell = atf::env::get("ATF_SHELL", ATF_SHELL);
- std::string* command = new std::string();
- command->reserve(512);
- (*command) += ("Atf_Check='" + libexecdir + "/atf-check' ; " +
- "Atf_Shell='" + shell + "' ; " +
- ". " + pkgdatadir + "/libatf-sh.subr ; " +
- ". " + fix_plain_name(filename) + " ; " +
- "main \"${@}\"");
+ std::string command;
+
+ command += ("Atf_Check='" + libexecdir + "/atf-check' ; " +
+ "Atf_Shell='" + shell + "' ; " +
+ ". " + pkgdatadir + "/libatf-sh.subr ; " +
+ ". " + fix_plain_name(filename) + " ; " +
+ "main \"${@}\"");
return command;
}
static
-const char**
+std::vector<std::string>
construct_argv(const std::string& shell, const int interpreter_argc,
const char* const* interpreter_argv)
{
PRE(interpreter_argc >= 1);
PRE(interpreter_argv[0] != NULL);
- const std::string* script = construct_script(interpreter_argv[0]);
+ std::string script = construct_script(interpreter_argv[0]);
- const int count = 4 + (interpreter_argc - 1) + 1;
- const char** argv = new const char*[count];
- argv[0] = shell.c_str();
- argv[1] = "-c";
- argv[2] = script->c_str();
- argv[3] = interpreter_argv[0];
+ std::vector<std::string> argv;
- for (int i = 1; i < interpreter_argc; i++)
- argv[4 + i - 1] = interpreter_argv[i];
+ argv.push_back(shell);
+ argv.push_back(std::string("-c"));
+ argv.push_back(std::move(script));
+ argv.push_back(std::string(interpreter_argv[0]));
- argv[count - 1] = NULL;
+ for (int i = 1; i < interpreter_argc; i++)
+ argv.push_back(interpreter_argv[i]);
return argv;
}
@@ -167,12 +167,18 @@ atf_sh::main(void)
throw std::runtime_error("The test program '" + script.str() + "' "
"does not exist");
- const char** argv = construct_argv(m_shell.str(), m_argc, m_argv);
- // Don't bother keeping track of the memory allocated by construct_argv:
- // we are going to exec or die immediately.
+ std::vector<std::string> argvv = construct_argv(m_shell.str(), m_argc,
+ m_argv);
+ std::vector<const char *> argv;
+
+ for (std::size_t i = 0; i < argvv.size(); i++)
+ argv.push_back(argvv[i].c_str());
+ argv.push_back(NULL);
- const int ret = execv(m_shell.c_str(), const_cast< char** >(argv));
+ const int ret = execv(m_shell.c_str(),
+ const_cast<char* const *>(argv.data()));
INV(ret == -1);
+
std::cerr << "Failed to execute " << m_shell.str() << ": "
<< std::strerror(errno) << "\n";
return EXIT_FAILURE;
diff --git a/contrib/atf/atf-sh/integration_test.sh b/contrib/atf/atf-sh/integration_test.sh
index 1150966f288f..909e8c4b57f6 100644
--- a/contrib/atf/atf-sh/integration_test.sh
+++ b/contrib/atf/atf-sh/integration_test.sh
@@ -147,6 +147,24 @@ EOF
"${ATF_SH}" -s ./custom-shell tp helper
}
+atf_test_case require_progs
+require_progs_body()
+{
+ cat | create_test_program tp <<EOF
+atf_test_case helper
+helper_head() {
+ atf_set "require.progs" "true"
+}
+helper_body() {
+ true
+}
+atf_init_test_cases() {
+ atf_add_test_case helper
+}
+EOF
+ atf_check -s eq:0 -o match:passed ./tp helper
+}
+
atf_init_test_cases()
{
atf_add_test_case no_args
@@ -155,6 +173,7 @@ atf_init_test_cases()
atf_add_test_case custom_shell__command_line
atf_add_test_case custom_shell__shebang
atf_add_test_case set_e
+ atf_add_test_case require_progs
}
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/contrib/atf/atf-sh/kmod_test.sh b/contrib/atf/atf-sh/kmod_test.sh
new file mode 100644
index 000000000000..b7856805063a
--- /dev/null
+++ b/contrib/atf/atf-sh/kmod_test.sh
@@ -0,0 +1,55 @@
+# Copyright (c) 2026 Enji Cooper <ngie@FreeBSD.org>.
+# All Rights Reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause
+
+atf_test_case atf_require_kmod_basic
+atf_require_kmod_basic_head()
+{
+ atf_set "descr" \
+ "Verifies that 'atf_require_kmod' functions in the positive case."
+}
+atf_require_kmod_basic_body()
+{
+ kldstat() {
+ true
+ }
+ atf_require_kmod "bogus"
+}
+
+atf_test_case atf_require_kmod_skip
+atf_require_kmod_skip_head()
+{
+ atf_set "descr" \
+ "atf_require_kmod: verifies the test is skipped when the kmods are " \
+ "not loaded."
+}
+atf_require_kmod_skip_body()
+{
+ kldstat() {
+ false
+ }
+ atf_expect_skip "Testcase should skip."
+ atf_require_kmod "bogus"
+}
+
+atf_test_case require_kmods_skip
+require_kmods_skip_head()
+{
+ atf_set "descr" \
+ "Verifies tests are skipped when the dependency isn't already loaded."
+ atf_set "require.kmods" "nonexistent"
+}
+require_kmods_skip_body()
+{
+ atf_fail "This should never be reached."
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case atf_require_kmod_basic
+ atf_add_test_case atf_require_kmod_skip
+ atf_add_test_case require_kmods_skip
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
diff --git a/contrib/atf/atf-sh/libatf-sh.subr b/contrib/atf/atf-sh/libatf-sh.subr
index b89060f8b00b..35810a63bae3 100644
--- a/contrib/atf/atf-sh/libatf-sh.subr
+++ b/contrib/atf/atf-sh/libatf-sh.subr
@@ -210,6 +210,19 @@ atf_expect_fail()
}
#
+# atf_expect_skip reason
+#
+# Sets the expectations to 'skip'.
+#
+atf_expect_skip()
+{
+ _atf_validate_expect
+
+ Expect=skip
+ Expect_Reason="${*}"
+}
+
+#
# atf_expect_pass
#
# Sets the expectations to 'pass'.
@@ -716,6 +729,11 @@ _atf_validate_expect()
atf_fail "Test case was expected to receive a termination signal" \
"but it continued execution"
;;
+ skip)
+ Expect=pass
+ atf_fail "Test case was supposed to be skipped but it continued " \
+ "execution"
+ ;;
timeout)
Expect=pass
atf_fail "Test case was expected to hang but it continued execution"
@@ -808,3 +826,25 @@ main()
}
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
+# BEGIN `FreeBSD.subr`.
+#
+# Copyright (c) 2026 Enji Cooper <ngie@FreeBSD.org>.
+# All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause
+
+atf_require_kmod_supported()
+{
+ true
+}
+
+# \brief FreeBSD specific helper routine for ensuring that a kmod has been
+# loaded.
+#
+# \param kmod a target kmod.
+atf_require_kmod()
+{
+ kldstat -q -m "${1}" || \
+ atf_skip "The required kmod ${1} is not loaded"
+}
+# END `FreeBSD.subr`.
diff --git a/contrib/atf/config.h b/contrib/atf/config.h
index a7094fca78cd..080a6ad6f8b8 100644
--- a/contrib/atf/config.h
+++ b/contrib/atf/config.h
@@ -7,6 +7,9 @@
/* Define to 1 if dirname takes a constant pointer */
/* #undef HAVE_CONST_DIRNAME */
+/* define if the compiler supports basic C++20 syntax */
+#define HAVE_CXX20 1
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
@@ -19,21 +22,18 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
+/* Define to 1 if you have the <minix/config.h> header file. */
+/* #undef HAVE_MINIX_CONFIG_H */
/* Define to 1 if getopt has optreset */
#define HAVE_OPTRESET 1
-/* Define to 1 if you have the `putenv' function. */
-#define HAVE_PUTENV 1
-
-/* Define to 1 if you have the `setenv' function. */
-#define HAVE_SETENV 1
-
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
@@ -52,12 +52,12 @@
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
-/* Define to 1 if you have the `unsetenv' function. */
-#define HAVE_UNSETENV 1
-
/* Define to 1 if vsnprintf is in std */
/* #undef HAVE_VSNPRINTF_IN_STD */
+/* Define to 1 if you have the <wchar.h> header file. */
+#define HAVE_WCHAR_H 1
+
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
@@ -65,7 +65,7 @@
#define PACKAGE "atf"
/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "atf-discuss@googlegroups.com"
+#define PACKAGE_BUGREPORT "freebsd-testing@freebsd.org"
/* Define to the copyright string applicable to this package. */
#define PACKAGE_COPYRIGHT "Copyright (c) 2007-2012 The NetBSD Foundation, Inc."
@@ -74,19 +74,117 @@
#define PACKAGE_NAME "Automated Testing Framework"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "Automated Testing Framework 0.21"
+#define PACKAGE_STRING "Automated Testing Framework 0.26"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "atf"
/* Define to the home page for this package. */
-#define PACKAGE_URL "https://github.com/jmmv/atf/"
+#define PACKAGE_URL "https://github.com/freebsd/atf/"
/* Define to the version of this package. */
-#define PACKAGE_VERSION "0.21"
+#define PACKAGE_VERSION "0.26"
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C89 standard headers exist (not just the ones
+ required in a freestanding environment). This macro is provided for
+ backward compatibility; new code need not use it. */
#define STDC_HEADERS 1
+/* Enable extensions on AIX, Interix, z/OS. */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable extensions on Cosmopolitan Libc. */
+#ifndef _COSMO_SOURCE
+# define _COSMO_SOURCE 1
+#endif
+/* Enable general extensions on macOS. */
+#ifndef _DARWIN_C_SOURCE
+# define _DARWIN_C_SOURCE 1
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable X/Open compliant socket functions that do not require linking
+ with -lxnet on HP-UX 11.11. */
+#ifndef _HPUX_ALT_XOPEN_SOCKET_API
+# define _HPUX_ALT_XOPEN_SOCKET_API 1
+#endif
+/* Identify the host operating system as Minix.
+ This macro does not affect the system headers' behavior.
+ A future release of Autoconf may stop defining this macro. */
+#ifndef _MINIX
+/* # undef _MINIX */
+#endif
+/* Enable general extensions on NetBSD.
+ Enable NetBSD compatibility extensions on Minix. */
+#ifndef _NETBSD_SOURCE
+# define _NETBSD_SOURCE 1
+#endif
+/* Enable OpenBSD compatibility extensions on NetBSD.
+ Oddly enough, this does nothing on OpenBSD. */
+#ifndef _OPENBSD_SOURCE
+# define _OPENBSD_SOURCE 1
+#endif
+/* Define to 1 if needed for POSIX-compatible behavior. */
+#ifndef _POSIX_SOURCE
+/* # undef _POSIX_SOURCE */
+#endif
+/* Define to 2 if needed for POSIX-compatible behavior. */
+#ifndef _POSIX_1_SOURCE
+/* # undef _POSIX_1_SOURCE */
+#endif
+/* Enable POSIX-compatible threading on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
+#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+# define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
+#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+# define __STDC_WANT_IEC_60559_BFP_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
+#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
+# define __STDC_WANT_IEC_60559_DFP_EXT__ 1
+#endif
+/* Enable extensions specified by C23 Annex F. */
+#ifndef __STDC_WANT_IEC_60559_EXT__
+# define __STDC_WANT_IEC_60559_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
+#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
+# define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1
+#endif
+/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */
+#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
+# define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
+#endif
+/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
+#ifndef __STDC_WANT_LIB_EXT2__
+# define __STDC_WANT_LIB_EXT2__ 1
+#endif
+/* Enable extensions specified by ISO/IEC 24747:2009. */
+#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
+# define __STDC_WANT_MATH_SPEC_FUNCS__ 1
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable X/Open extensions. Define to 500 only if necessary
+ to make mbstate_t available. */
+#ifndef _XOPEN_SOURCE
+/* # undef _XOPEN_SOURCE */
+#endif
+
+
/* Version number of package */
-#define VERSION "0.21"
+#define VERSION "0.26"
diff --git a/contrib/atf/doc/.gitignore b/contrib/atf/doc/.gitignore
deleted file mode 100644
index 7c3185645015..000000000000
--- a/contrib/atf/doc/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-atf.7
diff --git a/contrib/atf/doc/atf-test-case.4 b/contrib/atf/doc/atf-test-case.7
index 020d7035d198..e36b9c01a92d 100644
--- a/contrib/atf/doc/atf-test-case.4
+++ b/contrib/atf/doc/atf-test-case.7
@@ -22,8 +22,8 @@
.\" IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
.\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.Dd May 11, 2025
-.Dt ATF-TEST-CASE 4
+.Dd August 5, 2025
+.Dt ATF-TEST-CASE 7
.Os
.Sh NAME
.Nm atf-test-case
@@ -153,7 +153,7 @@ The following metadata properties can be exposed via the test case's head:
.Bl -tag -width requireXmachineXX
.It descr
Type: textual.
-Required.
+Optional.
.Pp
A brief textual description of the test case's purpose.
Will be shown to the user in reports.
@@ -223,14 +223,6 @@ The value can have a size suffix such as
or
.Sq T
to make the amount of bytes easier to type and read.
-.It require.kmods
-Type: textual.
-Optional.
-.Pp
-A whitespace separated list of kernel modules that must be present to
-execute the test case.
-If any of the required kernel modules is not found, the test case is
-.Em skipped .
.It require.progs
Type: textual.
Optional.
diff --git a/contrib/atf/test-programs/srcdir_test.sh b/contrib/atf/test-programs/srcdir_test.sh
index 90a468a8f069..2dbf08c9afef 100644
--- a/contrib/atf/test-programs/srcdir_test.sh
+++ b/contrib/atf/test-programs/srcdir_test.sh
@@ -70,16 +70,6 @@ libtool_body()
atf_check -s eq:1 -o empty -e ignore "${hp}" -r res srcdir_exists
atf_check -s eq:0 -o ignore -e empty grep "Cannot find datafile" res
done
-
- for hp in $(get_helpers c_helpers cpp_helpers); do
- h=${hp##*/}
- cp ${hp} tmp
- cp ${hp} tmp/.libs/lt-${h}
- atf_check -s eq:0 -o ignore -e ignore -x \
- "cd tmp && ./.libs/lt-${h} srcdir_exists"
- atf_check -s eq:1 -o empty -e ignore "${hp}" -r res srcdir_exists
- atf_check -s eq:0 -o ignore -e empty grep "Cannot find datafile" res
- done
}
atf_test_case sflag
diff --git a/lib/atf/Makefile.inc b/lib/atf/Makefile.inc
index af176036f136..81f248945572 100644
--- a/lib/atf/Makefile.inc
+++ b/lib/atf/Makefile.inc
@@ -28,4 +28,6 @@ PACKAGE?= atf
LIB_PACKAGE=
CFLAGS+= -DHAVE_CONFIG_H
+CXXSTD= gnu++20
+
WARNS?= 3
diff --git a/libexec/atf/Makefile.inc b/libexec/atf/Makefile.inc
index 5fd06c35cd09..52ecd1a7da34 100644
--- a/libexec/atf/Makefile.inc
+++ b/libexec/atf/Makefile.inc
@@ -28,6 +28,8 @@ PACKAGE?= atf
LIB_PACKAGE=
CFLAGS+= -DHAVE_CONFIG_H
+CXXSTD= gnu++20
+
WARNS?= 3
.include "../Makefile.inc"
diff --git a/share/doc/atf/Makefile b/share/doc/atf/Makefile
index e4a345f9b092..8c47bdcce3ae 100644
--- a/share/doc/atf/Makefile
+++ b/share/doc/atf/Makefile
@@ -30,7 +30,7 @@ ATFTOP= ${SRCTOP}/contrib/atf
FILESGROUPS= ATF
ATFDIR= ${SHAREDIR}/doc/atf
-ATF= AUTHORS COPYING NEWS README
+ATF= AUTHORS COPYING NEWS README.md
ATFPACKAGE= atf
.include <bsd.prog.mk>
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 8e044ac92366..4c1321c1d785 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -1090,14 +1090,6 @@ MAN+= mlx5ib.4
MAN+= mlx5io.4
.endif
-.if ${MK_TESTS} != "no"
-MANGROUPS+= ATF
-ATFTOP= ${SRCTOP}/contrib/atf
-.PATH: ${ATFTOP}/doc
-ATF= atf-test-case.4
-ATFPACKAGE= atf
-.endif
-
.if ${MK_PF} != "no"
_pf.4= pf.4
_pflog.4= pflog.4
diff --git a/share/man/man7/Makefile b/share/man/man7/Makefile
index 54aa60c9067a..9e833992b606 100644
--- a/share/man/man7/Makefile
+++ b/share/man/man7/Makefile
@@ -67,6 +67,7 @@ TESTS= tests.7
TESTSPACKAGE= tests
ATF= atf.7
+ATF= atf-test-case.7
ATFPACKAGE= atf
ATFPATH= ${SRCTOP}/contrib/atf