[Midnightbsd-cvs] src [11143] vendor/atf: initial import of atf

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Tue Jun 26 20:27:30 EDT 2018


Revision: 11143
          http://svnweb.midnightbsd.org/src/?rev=11143
Author:   laffer1
Date:     2018-06-26 20:27:29 -0400 (Tue, 26 Jun 2018)
Log Message:
-----------
initial import of atf

Added Paths:
-----------
    vendor/atf/
    vendor/atf/dist/
    vendor/atf/dist/AUTHORS
    vendor/atf/dist/COPYING
    vendor/atf/dist/Kyuafile
    vendor/atf/dist/NEWS
    vendor/atf/dist/README
    vendor/atf/dist/atf-c/
    vendor/atf/dist/atf-c/Kyuafile
    vendor/atf/dist/atf-c/atf-c.3
    vendor/atf/dist/atf-c/atf_c_test.c
    vendor/atf/dist/atf-c/build.c
    vendor/atf/dist/atf-c/build.h
    vendor/atf/dist/atf-c/build_test.c
    vendor/atf/dist/atf-c/check.c
    vendor/atf/dist/atf-c/check.h
    vendor/atf/dist/atf-c/check_test.c
    vendor/atf/dist/atf-c/defs.h
    vendor/atf/dist/atf-c/defs.h.in
    vendor/atf/dist/atf-c/detail/
    vendor/atf/dist/atf-c/detail/Kyuafile
    vendor/atf/dist/atf-c/detail/dynstr.c
    vendor/atf/dist/atf-c/detail/dynstr.h
    vendor/atf/dist/atf-c/detail/dynstr_test.c
    vendor/atf/dist/atf-c/detail/env.c
    vendor/atf/dist/atf-c/detail/env.h
    vendor/atf/dist/atf-c/detail/env_test.c
    vendor/atf/dist/atf-c/detail/fs.c
    vendor/atf/dist/atf-c/detail/fs.h
    vendor/atf/dist/atf-c/detail/fs_test.c
    vendor/atf/dist/atf-c/detail/list.c
    vendor/atf/dist/atf-c/detail/list.h
    vendor/atf/dist/atf-c/detail/list_test.c
    vendor/atf/dist/atf-c/detail/map.c
    vendor/atf/dist/atf-c/detail/map.h
    vendor/atf/dist/atf-c/detail/map_test.c
    vendor/atf/dist/atf-c/detail/process.c
    vendor/atf/dist/atf-c/detail/process.h
    vendor/atf/dist/atf-c/detail/process_helpers.c
    vendor/atf/dist/atf-c/detail/process_test.c
    vendor/atf/dist/atf-c/detail/sanity.c
    vendor/atf/dist/atf-c/detail/sanity.h
    vendor/atf/dist/atf-c/detail/sanity_test.c
    vendor/atf/dist/atf-c/detail/test_helpers.c
    vendor/atf/dist/atf-c/detail/test_helpers.h
    vendor/atf/dist/atf-c/detail/text.c
    vendor/atf/dist/atf-c/detail/text.h
    vendor/atf/dist/atf-c/detail/text_test.c
    vendor/atf/dist/atf-c/detail/tp_main.c
    vendor/atf/dist/atf-c/detail/user.c
    vendor/atf/dist/atf-c/detail/user.h
    vendor/atf/dist/atf-c/detail/user_test.c
    vendor/atf/dist/atf-c/detail/version_helper.c
    vendor/atf/dist/atf-c/error.c
    vendor/atf/dist/atf-c/error.h
    vendor/atf/dist/atf-c/error_fwd.h
    vendor/atf/dist/atf-c/error_test.c
    vendor/atf/dist/atf-c/h_build.h
    vendor/atf/dist/atf-c/macros.h
    vendor/atf/dist/atf-c/macros_h_test.c
    vendor/atf/dist/atf-c/macros_test.c
    vendor/atf/dist/atf-c/pkg_config_test.sh
    vendor/atf/dist/atf-c/tc.c
    vendor/atf/dist/atf-c/tc.h
    vendor/atf/dist/atf-c/tc_test.c
    vendor/atf/dist/atf-c/tp.c
    vendor/atf/dist/atf-c/tp.h
    vendor/atf/dist/atf-c/tp_test.c
    vendor/atf/dist/atf-c/unused_test.c
    vendor/atf/dist/atf-c/utils.c
    vendor/atf/dist/atf-c/utils.h
    vendor/atf/dist/atf-c/utils_test.c
    vendor/atf/dist/atf-c++/
    vendor/atf/dist/atf-c++/Kyuafile
    vendor/atf/dist/atf-c++/atf-c++.3
    vendor/atf/dist/atf-c++/atf_c++_test.cpp
    vendor/atf/dist/atf-c++/build.cpp
    vendor/atf/dist/atf-c++/build.hpp
    vendor/atf/dist/atf-c++/build_test.cpp
    vendor/atf/dist/atf-c++/check.cpp
    vendor/atf/dist/atf-c++/check.hpp
    vendor/atf/dist/atf-c++/check_test.cpp
    vendor/atf/dist/atf-c++/detail/
    vendor/atf/dist/atf-c++/detail/Kyuafile
    vendor/atf/dist/atf-c++/detail/application.cpp
    vendor/atf/dist/atf-c++/detail/application.hpp
    vendor/atf/dist/atf-c++/detail/application_test.cpp
    vendor/atf/dist/atf-c++/detail/auto_array.hpp
    vendor/atf/dist/atf-c++/detail/auto_array_test.cpp
    vendor/atf/dist/atf-c++/detail/env.cpp
    vendor/atf/dist/atf-c++/detail/env.hpp
    vendor/atf/dist/atf-c++/detail/env_test.cpp
    vendor/atf/dist/atf-c++/detail/exceptions.cpp
    vendor/atf/dist/atf-c++/detail/exceptions.hpp
    vendor/atf/dist/atf-c++/detail/exceptions_test.cpp
    vendor/atf/dist/atf-c++/detail/fs.cpp
    vendor/atf/dist/atf-c++/detail/fs.hpp
    vendor/atf/dist/atf-c++/detail/fs_test.cpp
    vendor/atf/dist/atf-c++/detail/process.cpp
    vendor/atf/dist/atf-c++/detail/process.hpp
    vendor/atf/dist/atf-c++/detail/process_test.cpp
    vendor/atf/dist/atf-c++/detail/sanity.hpp
    vendor/atf/dist/atf-c++/detail/test_helpers.cpp
    vendor/atf/dist/atf-c++/detail/test_helpers.hpp
    vendor/atf/dist/atf-c++/detail/text.cpp
    vendor/atf/dist/atf-c++/detail/text.hpp
    vendor/atf/dist/atf-c++/detail/text_test.cpp
    vendor/atf/dist/atf-c++/detail/version_helper.cpp
    vendor/atf/dist/atf-c++/macros.hpp
    vendor/atf/dist/atf-c++/macros_hpp_test.cpp
    vendor/atf/dist/atf-c++/macros_test.cpp
    vendor/atf/dist/atf-c++/pkg_config_test.sh
    vendor/atf/dist/atf-c++/tests.cpp
    vendor/atf/dist/atf-c++/tests.hpp
    vendor/atf/dist/atf-c++/tests_test.cpp
    vendor/atf/dist/atf-c++/unused_test.cpp
    vendor/atf/dist/atf-c++/utils.cpp
    vendor/atf/dist/atf-c++/utils.hpp
    vendor/atf/dist/atf-c++/utils_test.cpp
    vendor/atf/dist/atf-c++.hpp
    vendor/atf/dist/atf-c.h
    vendor/atf/dist/atf-sh/
    vendor/atf/dist/atf-sh/Kyuafile
    vendor/atf/dist/atf-sh/atf-check.1
    vendor/atf/dist/atf-sh/atf-check.cpp
    vendor/atf/dist/atf-sh/atf-check_test.sh
    vendor/atf/dist/atf-sh/atf-sh.1
    vendor/atf/dist/atf-sh/atf-sh.3
    vendor/atf/dist/atf-sh/atf-sh.cpp
    vendor/atf/dist/atf-sh/atf_check_test.sh
    vendor/atf/dist/atf-sh/config_test.sh
    vendor/atf/dist/atf-sh/integration_test.sh
    vendor/atf/dist/atf-sh/libatf-sh.subr
    vendor/atf/dist/atf-sh/misc_helpers.sh
    vendor/atf/dist/atf-sh/normalize_test.sh
    vendor/atf/dist/atf-sh/tc_test.sh
    vendor/atf/dist/atf-sh/tp_test.sh
    vendor/atf/dist/config.h
    vendor/atf/dist/doc/
    vendor/atf/dist/doc/atf-test-case.4
    vendor/atf/dist/doc/atf-test-program.1
    vendor/atf/dist/doc/atf.7.in
    vendor/atf/dist/test-programs/
    vendor/atf/dist/test-programs/Kyuafile
    vendor/atf/dist/test-programs/c_helpers.c
    vendor/atf/dist/test-programs/common.sh
    vendor/atf/dist/test-programs/config_test.sh
    vendor/atf/dist/test-programs/cpp_helpers.cpp
    vendor/atf/dist/test-programs/expect_test.sh
    vendor/atf/dist/test-programs/meta_data_test.sh
    vendor/atf/dist/test-programs/result_test.sh
    vendor/atf/dist/test-programs/sh_helpers.sh
    vendor/atf/dist/test-programs/srcdir_test.sh

Added: vendor/atf/dist/AUTHORS
===================================================================
--- vendor/atf/dist/AUTHORS	                        (rev 0)
+++ vendor/atf/dist/AUTHORS	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,30 @@
+Authors and contributors                        Automated Testing Framework
+===========================================================================
+
+
+* Julio Merino <jmmv at NetBSD.org>
+
+  Main developer.  He started the work on this project when he took part in
+  the Google Summer of Code 2007 program as a student.
+
+* Martin Husemann <martin at NetBSD.org>
+
+  Mentored this project during its development as part of the Google Summer
+  of Code 2007 program.
+
+* Lukasz Strzygowski <qx89l4 at gmail.com>
+
+  Participant of the Google Summer of Code 2008 program.  Mentored by The
+  NetBSD Foundation, he worked on the atfify NetBSD-SoC project and, as a
+  side-effect, he contributed to the ATF source code.  He developed the
+  initial version of the atf-check utility and started the addition of the
+  ATF_REQUIRE family of macros in the C interface.
+
+* Paul Goyette <pgoyette at NetBSD.org>
+
+  Implemented timestamping of test programs and test cases so that
+  atf-report can provide timings for their execution.
+
+
+===========================================================================
+vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2

Added: vendor/atf/dist/COPYING
===================================================================
--- vendor/atf/dist/COPYING	                        (rev 0)
+++ vendor/atf/dist/COPYING	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,100 @@
+Redistribution terms                            Automated Testing Framework
+===========================================================================
+
+
+License
+*******
+
+Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012 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.
+
+
+Copyright 2011, 2012 Google 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:
+
+* Redistributions of source code must retain the above copyright
+  notice, this list of conditions and the following disclaimer.
+
+* 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.
+
+* Neither the name of Google Inc. nor the names of its contributors
+  may be used to endorse or promote products derived from this software
+  without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
+
+
+Relicensed code
+***************
+
+The following code snippets have been taken from other projects.  Even
+though they were not originally licensed under the terms above, the
+original authors have agreed to relicense their work so that this project
+can be distributed under a single license.  This section is put here just to
+clarify this fact.
+
+* configure.ac, Makefile.am: The original versions were derived from the
+  ones in the XML Catalog Manager project, version 2.2.
+
+  Author: Julio Merino <jmmv at users.sourceforge.net>
+
+* atf-c/ui.c: The format_paragraph and format_text functions were
+  derived form the ones in the Monotone project, revision
+  3a0982da308228d796df35f98d787c5cff2bb5b6.
+
+  Author: Julio Merino <jmmv at NetBSD.org>
+
+* atf-c++/detail/io.hpp, atf-c++/detail/io.cpp, atf-c++/detail/io_test.cpp:
+  These files were derived from the file_handle, systembuf, pipe and pistream
+  classes and tests found in the Boost.Process library.
+
+  Author: Julio Merino <jmmv84 at gmail.com>
+
+* admin/check-style.sh, admin/check-style-common.awk,
+  admin/check-style-cpp.awk, admin/check-style-shell.awk: These files,
+  except the first one, were first implemented in the Buildtool project.
+  They were later adapted to be part of Boost.Process and, during that
+  process, the shell script was created.
+
+  Author: Julio Merino <jmmv84 at gmail.com>
+
+
+===========================================================================
+vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2

Added: vendor/atf/dist/Kyuafile
===================================================================
--- vendor/atf/dist/Kyuafile	                        (rev 0)
+++ vendor/atf/dist/Kyuafile	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,8 @@
+syntax("kyuafile", 1)
+
+test_suite("atf")
+
+include("atf-c/Kyuafile")
+include("atf-c++/Kyuafile")
+include("atf-sh/Kyuafile")
+include("test-programs/Kyuafile")

Added: vendor/atf/dist/NEWS
===================================================================
--- vendor/atf/dist/NEWS	                        (rev 0)
+++ vendor/atf/dist/NEWS	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,726 @@
+Major changes between releases                  Automated Testing Framework
+===========================================================================
+
+Changes in version 0.21
+***********************
+
+Released on October 23rd, 2014.
+
+* Restored the atf(7) manual page to serve as a reference to all the other
+  manual pages shipped by ATF.
+
+* Added the -s flag to atf-sh to support specifying the shell interpreter
+  to be used.
+
+* Removed ATF_WORKDIR.  The only remaining consumers have been converted to
+  use the standard TMPDIR environment variable.  As a benefit, and because
+  Kyua forces the TMPDIR to live within the test case's work directory,
+  any stale files left behind by ATF will be automatically cleaned up.
+
+* Documented the environment variables recognized by each component in the
+  relevant manual pages.  This information was lost with the atf-config(1)
+  removal.
+
+* Added a new "require.diskspace" metadata property to test cases so that
+  they can specify the minimum amount of disk space required for the test
+  to run.
+
+* Renamed the atf-{c,c++,sh}-api(3) manual pages to atf-{c,c++,sh}(3) for
+  discoverability purposes.  Symbolic links are provided for the time
+  being to still make the old names visible.
+
+* Issue #5: Recommend the (expected, actual) idiom for calls to the test
+  macros in the manual pages.
+
+* Issue #7: Stopped catching unhandled exceptions in atf-c++ tests.  This
+  propagates the crash to the caller, which in turn allows it to obtain
+  proper debugging information.  In particular, Kyua should now be able to
+  extract a stacktrace pinpointing the problem.
+
+* Issue #8: Fixed atf-c/macros_test:use test failures spotted by the clang
+  that ships with FreeBSD 11.0-CURRENT.
+
+* Issue #12: Improved documentation of atf-sh(3) and atf-check(1) by better
+  explaining how they relate to each other.
+
+* Issue #14: Stopped setting 'set -e' in atf-sh.  This setting was
+  initially added as a way to enable a "strict" mode in the library and to
+  make test cases fail fast when they run unprotected commands.  However,
+  doing so in the library is surprising as the responsibility of enabling
+  'set -e' should be on the user's code.  Also, 'set -e' introduces
+  inconsistent behavior on subshells and users do not expect that.
+
+* Issue #15: Fixed atf_utils_{fork,wait} to support nested calls.
+
+* Issue #16: Fixed test failures (by removing a long-standing hack) on
+  systems that lack \e support in printf(1).
+
+* Issue #19: Removed stale references to atf-config and atf-run.
+
+
+Changes in version 0.20
+***********************
+
+Experimental version released on February 7th, 2014.
+
+This is the first release without the code for the deprecated tools.  If
+you require such code, please fetch a copy of the 0.19 release and extract
+the 'tools' directory for your own consumption.
+
+* Removed the deprecated tools.  This includes atf-config, atf-report,
+  atf-run and atf-version.
+
+* Issue #8: Fixed atf-c/macros_test:use test failures spotted by the clang
+  that ships with FreeBSD 11.0-CURRENT.
+
+
+Changes in version 0.19
+***********************
+
+Experimental version released on February 7th, 2014.
+
+This is the last release to bundle the code for the deprecated tools.
+The next release will drop their code and will stop worrying about
+backwards compatibility between the ATF libraries and what the old tools
+may or may not support.
+
+If you still require the old tools for some reason, grab a copy of the
+'tools' directory now.  The code in this directory is standalone and
+does not depend on any internal details of atf-c++ any longer.
+
+* Various fixes and improvements to support running as part of the FreeBSD
+  test suite.
+
+* 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/
+
+* Removed builtin help from atf-sh(1) and atf-check(1) for simplicity
+  reasons.  In other words, their -h option is gone.
+
+* Moved the code of the deprecated tools into a 'tools' directory and
+  completely decoupled their code from the internals of atf-c++.  The
+  reason for this is to painlessly allow a third-party to maintain a
+  copy of these tools after we delete them because upcoming changes to
+  atf-c++ would break the stale tools.
+
+
+Changes in version 0.18
+***********************
+
+Experimental version released on November 16th, 2013.
+
+* Issue 45: Added require.memory support in atf-run for FreeBSD.
+
+* Fixed an issue with the handling of cin with libc++.
+
+* Issue 64: Fixed various mandoc formatting warnings.
+
+* NetBSD PR bin/48284: Made atf-check flush its progress message to
+  stdout so that an interrupted test case always shows the last message
+  being executed.
+
+* NetBSD PR bin/48285: Fixed atf_check examples in atf-sh-api(3).
+
+
+Changes in version 0.17
+***********************
+
+Experimental version released on February 14th, 2013.
+
+* Added the atf_utils_cat_file, atf_utils_compare_file,
+  atf_utils_copy_file, atf_utils_create_file, atf_utils_file_exists,
+  atf_utils_fork, atf_utils_grep_file, atf_utils_grep_string,
+  atf_utils_readline, atf_utils_redirect and atf_utils_wait utility
+  functions to atf-c-api.  Documented the already-public
+  atf_utils_free_charpp function.
+
+* Added the cat_file, compare_file, copy_file, create_file, file_exists,
+  fork, grep_collection, grep_file, grep_string, redirect and wait
+  functions to the atf::utils namespace of atf-c++-api.  These are
+  wrappers around the same functions added to the atf-c-api library.
+
+* Added the ATF_CHECK_MATCH, ATF_CHECK_MATCH_MSG, ATF_REQUIRE_MATCH and
+  ATF_REQUIRE_MATCH_MSG macros to atf-c to simplify the validation of a
+  string against a regular expression.
+
+* Miscellaneous fixes for manpage typos and compilation problems with
+  clang.
+
+* Added caching of the results of those configure tests that rely on
+  executing a test program.  This should help crossbuild systems by
+  providing a mechanism to pre-specify what the results should be.
+
+* PR bin/45690: Make atf-report convert any non-printable characters to
+  a plain-text representation (matching their corresponding hexadecimal
+  entities) in XML output files.  This is to prevent the output of test
+  cases from breaking xsltproc later.
+
+
+Changes in version 0.16
+***********************
+
+Experimental version released on July 10th, 2012.
+
+* Added a --enable-tools flag to configure to request the build of the
+  deprecated ATF tools, whose build is now disabled by default.  In order
+  to continue running tests, you should migrate to Kyua instead of enabling
+  the build of the deprecated tools.  The kyua-atf-compat package provides
+  transitional compatibility versions of atf-run and atf-report built on
+  top of Kyua.
+
+* Tweaked the ATF_TEST_CASE macro of atf-c++ so that the compiler can
+  detect defined but unused test cases.
+
+* PR bin/45859: Fixed some XSLT bugs that resulted in the tc-time and
+  tp-time XML tags leaking into the generated HTML file.  Also improved
+  the CSS file slightly to correct alignment and color issues with the
+  timestamps column.
+
+* Optimized atf-c++/macros.hpp so that GNU G++ consumes less memory during
+  compilation with GNU G++.
+
+* Flipped the default to building shared libraries for atf-c and atf-c++,
+  and started versioning them.  As a side-effect, this removes the
+  --enable-unstable-shared flag from configure that appears to not work any
+  more (under NetBSD).  Additionally, some distributions require the use of
+  shared libraries for proper dependency tracking (e.g. Fedora), so it is
+  better if we do the right versioning upstream.
+
+* Project hosting moved from an adhoc solution (custom web site and
+  Monotone repository) to Google Code (standard wiki and Git).  ATF now
+  lives in a subcomponent of the Kyua project.
+
+
+Changes in version 0.15
+***********************
+
+Experimental version released on January 16th, 2012.
+
+* Respect stdin in atf-check.  The previous release silenced stdin for any
+  processes spawned by atf, not only test programs, which caused breakage
+  in tests that pipe data through atf-check.
+
+* Performance improvements to atf-sh.
+
+* Enabled detection of unused parameters and variables in the code and
+  fixed all warnings.
+
+* Changed the behavior of "developer mode".  Compiler warnings are now
+  enabled unconditionally regardless of whether we are in developer mode or
+  not; developer mode is now only used to perform strict warning checks and
+  to enable assertions.  Additionally, developer mode is now only
+  automatically enabled when building from the repository, not for formal
+  releases.
+
+* Added new Autoconf M4 macros (ATF_ARG_WITH, ATF_CHECK_C and
+  ATF_CHECK_CXX) to provide a consistent way of defining a --with-arg flag
+  in configure scripts and detecting the presence of any of the ATF
+  bindings.  Note that ATF_CHECK_SH was already introduced in 0.14, but it
+  has now been modified to also honor --with-atf if instantiated.
+
+* Added timing support to atf-run / atf-report.
+
+* Added support for a 'require.memory' property, to specify the minimum
+  amount of physical memory needed by the test case to yield valid results.
+
+* PR bin/45690: Force an ISO-8859-1 encoding in the XML files generated by
+  atf-report so that invalid data in the output of test cases does not
+  mangle our report.
+
+
+Changes in version 0.14
+***********************
+
+Experimental version released on June 14th, 2011.
+
+* Added a pkg-config file for atf-sh and an aclocal file to ease the
+  detection of atf-sh from autoconf scripts.
+
+* Made the default test case body defined by atf_sh fail.  This is to
+  ensure that test cases are properly defined in test programs and helps
+  in catching typos in the names of the body functions.
+
+* PR bin/44882: Made atf-run connect the stdin of test cases to /dev/zero.
+  This provides more consistent results with "normal" execution (in
+  particular, when tests are executed detached from a terminal).
+
+* Made atf-run hardcode TZ=UTC for test cases.  It used to undefine TZ, but
+  that does not take into account that libc determines the current timezone
+  from a configuration file.
+
+* All test programs will now print a warning when they are not run through
+  atf-run(1) stating that this is unsupported and may deliver incorrect
+  results.
+
+* Added support for the 'require.files' test-case property.  This allows
+  test cases to specify installed files that must be present for the test
+  case to run.
+
+
+Changes in version 0.13
+***********************
+
+Experimental version released on March 31st, 2011.
+
+This is the first release after the creation of the Kyua project, a more
+modular and reliable replacement for ATF.  From now on, ATF will change to
+accomodate the transition to this new codebase, but ATF will still continue
+to see development in the short/medium term.  Check out the project page at
+http://code.google.com/p/kyua/ for more details.
+
+The changes in this release are:
+
+* Added support to run the tests with the Kyua runtime engine (kyua-cli), a
+  new package that aims to replace atf-run and atf-report.  The ATF tests
+  can be run with the new system by issuing a 'make installcheck-kyua' from
+  the top-level directory of the project (assuming the 'kyua' binary is
+  available during the configuration stage of ATF).
+
+* atf-run and atf-report are now in maintenance mode (but *not* deprecated
+  yet!).  Kyua already implements a new, much more reliable runtime engine
+  that provides similar features to these tools.  That said, it is not
+  complete yet so all development efforts should go towards it.
+
+* If GDB is installed, atf-run dumps the stack trace of crashing test
+  programs in an attempt to aid debugging.  Contributed by Antti Kantee.
+
+* Reverted default timeout change in previous release and reset its value
+  to 5 minutes.  This was causing several issues, specially when running
+  the existing NetBSD test suite in qemu.
+
+* Fixed the 'match' output checker in atf-check to properly validate the
+  last line of a file even if it does not have a newline.
+
+* Added the ATF_REQUIRE_IN and ATF_REQUIRE_NOT_IN macros to atf-c++ to
+  check for the presence (or lack thereof) of an element in a collection.
+
+* PR bin/44176: Fixed a race condition in atf-run that would crash atf-run
+  when the cleanup of a test case triggered asynchronous modifications to
+  its work directory (e.g. killing a daemon process that cleans up a pid
+  file in the work directory).
+
+* PR bin/44301: Fixed the sample XSLT file to report bogus test programs
+  instead of just listing them as having 0 test cases.
+
+
+Changes in version 0.12
+***********************
+
+Experimental version released on November 7th, 2010.
+
+* Added the ATF_REQUIRE_THROW_RE to atf-c++, which is the same as
+  ATF_REQUIRE_THROW but allows checking for the validity of the exception's
+  error message by means of a regular expression.
+
+* Added the ATF_REQUIRE_MATCH to atf-c++, which allows checking for a
+  regular expression match in a string.
+
+* Changed the default timeout for test cases from 5 minutes to 30 seconds.
+  30 seconds is long enough for virtually all tests to complete, and 5
+  minutes is a way too long pause in a test suite where a single test case
+  stalls.
+
+* Deprecated the use.fs property.  While this seemed like a good idea in
+  the first place to impose more control on what test cases can do, it
+  turns out to be bad.  First, use.fs=false prevents bogus test cases
+  from dumping core so after-the-fact debugging is harder.  Second,
+  supporting use.fs adds a lot of unnecessary complexity.  atf-run will
+  now ignore any value provided to use.fs and will allow test cases to
+  freely access the file system if they wish to.
+
+* Added the atf_tc_get_config_var_as_{bool,long}{,_wd} functions to the atf-c
+  library.  The 'text' module became private in 0.11 but was being used
+  externally to simplify the parsing of configuration variables.
+
+* Made atf-run recognize the 'unprivileged-user' configuration variable
+  and automatically drop root privileges when a test case sets
+  require.user=unprivileged.  Note that this is, by no means, done for
+  security purposes; this is just for user convenience; tests should, in
+  general, not be blindly run as root in the first place.
+
+
+Changes in version 0.11
+***********************
+
+Experimental version released on October 20th, 2010.
+
+* The ATF_CHECK* macros in atf-c++ were renamed to ATF_REQUIRE* to match
+  their counterparts in atf-c.
+
+* Clearly separated the modules in atf-c that are supposed to be public
+  from those that are implementation details.  The header files for the
+  internal modules are not installed any more.
+
+* Made the atf-check tool private.  It is only required by atf-sh and being
+  public has the danger of causing confusion.  Also, making it private
+  simplifies the public API of atf.
+
+* Changed atf-sh to enable per-command error checking (set -e) by default.
+  This catches many cases in which a test case is broken but it is not
+  reported as such because execution continues.
+
+* Fixed the XSTL and CSS stylesheets to support expected failures.
+
+
+Changes in version 0.10
+***********************
+
+Experimental version released on July 2nd, 2010.
+
+Miscellaneous features
+
+* Added expected failures support to test cases and atf-run.  These
+  include, for example, expected clean exits, expected reception of fatal
+  signals, expected timeouts and expected errors in condition checks.
+  These statuses can be used to denote test cases that are known to fail
+  due to a bug in the code they are testing.  atf-report reports these
+  tests separately but they do not count towards the failed test cases
+  amount.
+
+* Added the ATF_CHECK_ERRNO and ATF_REQUIRE_ERRNO to the C library to
+  allow easy checking of call failures that update errno.
+
+* Added the has.cleanup meta-data property to test caes that specifies
+  whether the test case has a cleanup routine or not; its value is
+  automatically set.  This property is read by atf-run to know if it has to
+  run the cleanup routine; skipping this run for every test case
+  significantly speeds up the run time of test suites.
+
+* Reversed the order of the ATF_CHECK_THROW macro in the C++ binding to
+  take the expected exception as the first argument and the statement to
+  execute as the second argument.
+
+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
+  for stdout and stderr, not only one.
+
+* Added the match output checker to atf-check to look for regular
+  expressions in the stdout and stderr of commands.
+
+* Modified the exit checks in atf-check to support checking for the
+  reception of signals.
+
+Code simplifications and cleanups
+
+* Removed usage messages from test programs to simplify the
+  implementation of every binding by a significant amount.  They just now
+  refer the user to the appropriate manual page and do not attempt to wrap
+  lines on terminal boundaries.  Test programs are not supposed to be run
+  by users directly so this minor interface regression is not important.
+
+* Removed the atf-format internal utility, which is unused after the
+  change documented above.
+
+* Removed the atf-cleanup internal utility.  It has been unused since the
+  test case isolation was moved to atf-run in 0.8
+
+* Splitted the Makefile.am into smaller files for easier maintenance and
+  dropped the use of M4.  Only affects users building from the repository
+  sources.
+
+* Intermixed tests with the source files in the source tree to provide
+  them more visibility and easier access.  The tests directory is gone from
+  the source tree and tests are now suffixed by _test, not prefixed by t_.
+
+* Simplifications to the atf-c library: removed the io, tcr and ui
+  modules as they had become unnecessary after all simplifications
+  introduced since the 0.8 release.
+
+* Removed the application/X-atf-tcr format introduced in 0.8 release.
+  Tests now print a much simplified format that is easy to parse and nicer
+  to read by end users.  As a side effect, the default for test cases is
+  now to print their results to stdout unless otherwise stated by providing
+  the -r flag.
+
+* Removed XML distribution documents and replaced them with plain-text
+  documents.  They provided little value and introduced a lot of complexity
+  to the build system.
+
+* Simplified the output of atf-version by not attempting to print a
+  revision number when building form a distfile.  Makes the build system
+  easier to maintain.
+
+
+Changes in version 0.9
+**********************
+
+Experimental version released on June 3rd, 2010.
+
+* Added atf-sh, an interpreter to process test programs written using
+  the shell API.  This is not really a shell interpreter by itself though:
+  it is just a wrapper around the system shell that eases the loading of
+  the necessary ATF libraries.
+
+* Removed atf-compile in favour of atf-sh.
+
+* Added the use.fs metadata property to test case, which is used to
+  specify which test cases require file system access.  This is to
+  highlight dependencies on external resources more clearly and to speed up
+  the execution of test suites by skipping the creation of many unnecessary
+  work directories.
+
+* Fixed test programs to get a sane default value for their source
+  directory.  This means that it should not be necessary any more to pass
+  -s when running test programs that do not live in the current directory.
+
+* Defining test case headers became optional.  This is trivial to achieve
+  in shell-based tests but a bit ugly in C and C++.  In C, use the new
+  ATF_TC_WITHOUT_HEAD macro to define the test case, and in C++ use
+  ATF_TEST_CASE_WITHOUT_HEAD.
+
+
+Changes in version 0.8
+**********************
+
+Experimental version released on May 7th, 2010.
+
+* Test programs no longer run several test cases in a row.  The execution
+  of a test program now requires a test case name, and that single test
+  case is executed.  To execute several test cases, use the atf-run utility
+  as usual.
+
+* Test programs no longer fork a subprocess to isolate the execution of
+  test cases.  They run the test case code in-process, and a crash of the
+  test case will result in a crash of the test program.  This is to ease
+  debugging of faulty test cases.
+
+* Test programs no longer isolate their test cases.  This means that they
+  will not create temporary directories nor sanitize the environment any
+  more.  Yes: running a test case that depends on system state by hand will
+  most likely yield different results depending on where (machine,
+  directory, user environment, etc.) it is run.  Isolation has been moved
+  to atf-run.
+
+* Test programs no longer print a cryptic format (application/X-atf-tcs)
+  on a special file channel.  They can now print whatever they want on the
+  screen.  Because test programs can now only run one test case every time,
+  providing controlled output is not necessary any more.
+
+* Test programs no longer write their status into a special file
+  descriptor.  Instead, they create a file with the results, which is later
+  parsed by atf-run.  This changes the semantics of the -r flag.
+
+* atf-run has been adjusted to perform the test case isolation.  As a
+  result, there is now a single canonical place that implements the
+  isolation of test caes.  In previous releases, the three language
+  bindings (C, C++ and shell) had to be kept in sync with each other (read:
+  not a nice thing to do at all).  As a side effect of this change, writing
+  bindings for other languages will be much, much easier from now on.
+
+* atf-run forks test programs on a test case basis, instead of on a test
+  program basis as it did before.  This is to provide the test case
+  isolation that was before implemented by the test programs themselves.
+
+* Removed the atf-exec tool.  This was used to implement test case
+  isolation in atf-sh, but it is now unnecessary.
+
+* It is now optional to define the descr meta-data property.  It has been
+  proven to be mostly useless, because test cases often carry a descriptive
+  name of their own.
+
+
+Changes in version 0.7
+**********************
+
+Experimental version released on December 22nd, 2009.
+
+* Added build-time checks to atf-c and atf-c++.  A binding for atf-sh
+  will come later.
+
+* Migrated all build-time checks for header files to proper ATF tests.
+  This demonstrates the use of the new feature described above.
+
+* Added an internal API for child process management.
+
+* Converted all plain-text distribution documents to a Docbook canonical
+  version, and include pre-generated plain text and HTML copies in the
+  distribution file.
+
+* Simplified the contents of the Makefile.am by regenerating it from a
+  canonical Makefile.am.m4 source.  As a side-effect, some dependency
+  specifications were fixed.
+
+* Migrated all checks from the check target to installcheck, as these
+  require ATF to be installed.
+
+* Fixed sign comparison mismatches triggered by the now-enabled
+  -Wsign-compare.
+
+* Fixed many memory and object leaks.
+
+
+Changes in version 0.6
+**********************
+
+Experimental version released on January 18th, 2009.
+
+* Make atf-exec be able to kill its child process after a certain period
+  of time; this is controlled through the new -t option.
+
+* Change atf-sh to use atf-exec's -t option to control the test case's
+  timeouts, instead of doing it internally.  Same behavior as before, but
+  noticeably faster.
+
+* atf-exec's -g option and atf-killpg are gone due to the previous
+  change.
+
+* Added the atf-check(1) tool, a program that executes a given command
+  and checks its exit code against a known value and allows the management
+  of stdout and stderr in multiple ways.  This replaces the previous
+  atf_check function in the atf-sh library and exposes this functionality
+  to both atf-c and atf-c++.
+
+* Added the ATF_REQUIRE family of macros to the C interface.  These help
+  in checking for fatal test conditions.  The old ATF_CHECK macros now
+  perform non-fatal checks only.  I.e. by using ATF_CHECK, the test case
+  can now continue its execution and the failures will not be reported
+  until the end of the whole run.
+
+* Extended the amount of ATF_CHECK_* C macros with new ones to provide
+  more features to the developer.  These also have their corresponding
+  counterparts in the ATF_REQUIRE_* family.  The new macros (listing the
+  suffixes only) are: _EQ (replaces _EQUAL), _EQ_MSG, _STREQ and
+  _STREQ_MSG.
+
+
+Changes in version 0.5
+**********************
+
+Experimental version released on May 1st, 2008.
+
+* Clauses 3 and 4 of the BSD license used by the project were dropped.
+  All the code is now under a 2-clause BSD license compatible with the GNU
+  General Public License (GPL).
+
+* Added a C-only binding so that binary test programs do not need to be
+  tied to C++ at all.  This binding is now known as the atf-c library.
+
+* Renamed the C++ binding to atf-c++ for consistency with the new atf-c.
+
+* Renamed the POSIX shell binding to atf-sh for consistency with the new
+  atf-c and atf-c++.
+
+* Added a -w flag to test programs through which it is possible to
+  specify the work directory to be used.  This was possible in prior
+  releases by defining the workdir configuration variable (-v workdir=...),
+  but was a conceptually incorrect mechanism.
+
+* Test programs now preserve the execution order of test cases when they
+  are given in the command line.  Even those mentioned more than once are
+  executed multiple times to comply with the user's requests.
+
+
+Changes in version 0.4
+**********************
+
+Experimental version released on February 4th, 2008.
+
+* Added two new manual pages, atf-c++-api and atf-sh-api, describing the
+  C++ and POSIX shell interfaces used to write test programs.
+
+* Added a pkg-config file, useful to get the flags to build against the
+  C++ library or to easily detect the presence of ATF.
+
+* Added a way for test cases to require a specific architecture and/or
+  machine type through the new 'require.arch' and 'require.machine'
+  meta-data properties, respectively.
+
+* Added the 'timeout' property to test cases, useful to set an
+  upper-bound limit for the test's run time and thus prevent global test
+  program stalls due to the test case's misbehavior.
+
+* Added the atf-exec(1) internal utility, used to execute a command
+  after changing the process group it belongs to.
+
+* Added the atf-killpg(1) internal utility, used to kill process groups.
+
+* Multiple portability fixes.  Of special interest, full support for
+  SunOS (Solaris Express Developer Edition 2007/09) using the Sun Studio 12
+  C++ compiler.
+
+* Fixed a serious bug that prevented atf-run(1) from working at all
+  under Fedora 8 x86_64.  Due to the nature of the bug, other platforms
+  were likely affected too.
+
+
+Changes in version 0.3
+**********************
+
+Experimental version released on November 11th, 2007.
+
+* Added XML output support to atf-report.  This is accompanied by a DTD
+  for the format's structure and sample XSLT/CSS files to post-process this
+  output and convert it to a plain HTML report.
+
+* Changed atf-run to add system information to the report it generates.
+  This is currently used by atf-report's XML output only, and is later
+  printed in the HTML reports in a nice and useful summary table.  The user
+  and system administrator are allowed to tune this feature by means of
+  hooks.
+
+* Removed the test cases' 'isolated' property.  This was intended to
+  avoid touching the file system at all when running the related test case,
+  but this has not been true for a long while: some control files are
+  unconditionally required for several purposes, and we cannot easily get
+  rid of them.  This way we remove several critical and delicate pieces of
+  code.
+
+* Improved atf-report's CSV output format to include information about
+  test programs too.
+
+* Fixed the tests that used atf-compile to not require this tool as a
+  helper.  Avoids systems without build-time utilities to skip many tests
+  that could otherwise be run.  (E.g. NetBSD without the comp.tgz set
+  installed.)
+
+* Many general cleanups: Fixed many pieces of code marked as ugly and/or
+  incomplete.
+
+
+Changes in version 0.2
+**********************
+
+Experimental version released on September 20th, 2007.
+
+* Test cases now get a known umask on entry.
+
+* atf-run now detects many unexpected failures caused by test programs and
+  reports them as bogus tests.  atf-report is able to handle these new
+  errors and nicely reports them to the user.
+
+* All the data formats read and written by the tools have been
+  documented and cleaned up.  These include those grammars that define how
+  the different components communicate with each other as well as the
+  format of files written by the developers and users: the Atffiles and the
+  configuration files.
+
+* Added the atf-version tool, a utility that displays information about
+  the currently installed version of ATF.
+
+* Test cases can now define an optional cleanup routine to undo their
+  actions regardless of their exit status.
+
+* atf-report now summarizes the list of failed (bogus) test programs
+  when using the ticker output format.
+
+* Test programs now capture some termination signals and clean up any
+  temporary files before exiting the program.
+
+* Multiple bug fixes and improvements all around.
+
+
+Changes in version 0.1
+**********************
+
+Experimental version released on August 20th, 2007.
+
+* First public version.  This was released coinciding with the end of the
+  Google Summer of Code 2007 program.
+
+
+===========================================================================
+vim: filetype=text:textwidth=75:expandtab:shiftwidth=2:softtabstop=2

Added: vendor/atf/dist/README
===================================================================
--- vendor/atf/dist/README	                        (rev 0)
+++ vendor/atf/dist/README	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,37 @@
+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

Added: vendor/atf/dist/atf-c/Kyuafile
===================================================================
--- vendor/atf/dist/atf-c/Kyuafile	                        (rev 0)
+++ vendor/atf/dist/atf-c/Kyuafile	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,15 @@
+syntax("kyuafile", 1)
+
+test_suite("atf")
+
+atf_test_program{name="atf_c_test"}
+atf_test_program{name="build_test"}
+atf_test_program{name="check_test"}
+atf_test_program{name="error_test"}
+atf_test_program{name="macros_test"}
+atf_test_program{name="pkg_config_test"}
+atf_test_program{name="tc_test"}
+atf_test_program{name="tp_test"}
+atf_test_program{name="utils_test"}
+
+include("detail/Kyuafile")

Added: vendor/atf/dist/atf-c/atf-c.3
===================================================================
--- vendor/atf/dist/atf-c/atf-c.3	                        (rev 0)
+++ vendor/atf/dist/atf-c/atf-c.3	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,793 @@
+.\" Copyright (c) 2008 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.
+.Dd April 5, 2017
+.Dt ATF-C 3
+.Os
+.Sh NAME
+.Nm atf-c ,
+.Nm ATF_CHECK ,
+.Nm ATF_CHECK_MSG ,
+.Nm ATF_CHECK_EQ ,
+.Nm ATF_CHECK_EQ_MSG ,
+.Nm ATF_CHECK_MATCH ,
+.Nm ATF_CHECK_MATCH_MSG ,
+.Nm ATF_CHECK_STREQ ,
+.Nm ATF_CHECK_STREQ_MSG ,
+.Nm ATF_CHECK_ERRNO ,
+.Nm ATF_REQUIRE ,
+.Nm ATF_REQUIRE_MSG ,
+.Nm ATF_REQUIRE_EQ ,
+.Nm ATF_REQUIRE_EQ_MSG ,
+.Nm ATF_REQUIRE_MATCH ,
+.Nm ATF_REQUIRE_MATCH_MSG ,
+.Nm ATF_REQUIRE_STREQ ,
+.Nm ATF_REQUIRE_STREQ_MSG ,
+.Nm ATF_REQUIRE_ERRNO ,
+.Nm ATF_TC ,
+.Nm ATF_TC_BODY ,
+.Nm ATF_TC_BODY_NAME ,
+.Nm ATF_TC_CLEANUP ,
+.Nm ATF_TC_CLEANUP_NAME ,
+.Nm ATF_TC_HEAD ,
+.Nm ATF_TC_HEAD_NAME ,
+.Nm ATF_TC_NAME ,
+.Nm ATF_TC_WITH_CLEANUP ,
+.Nm ATF_TC_WITHOUT_HEAD ,
+.Nm ATF_TP_ADD_TC ,
+.Nm ATF_TP_ADD_TCS ,
+.Nm atf_tc_get_config_var ,
+.Nm atf_tc_get_config_var_wd ,
+.Nm atf_tc_get_config_var_as_bool ,
+.Nm atf_tc_get_config_var_as_bool_wd ,
+.Nm atf_tc_get_config_var_as_long ,
+.Nm atf_tc_get_config_var_as_long_wd ,
+.Nm atf_no_error ,
+.Nm atf_tc_expect_death ,
+.Nm atf_tc_expect_exit ,
+.Nm atf_tc_expect_fail ,
+.Nm atf_tc_expect_pass ,
+.Nm atf_tc_expect_signal ,
+.Nm atf_tc_expect_timeout ,
+.Nm atf_tc_fail ,
+.Nm atf_tc_fail_nonfatal ,
+.Nm atf_tc_pass ,
+.Nm atf_tc_skip ,
+.Nm atf_utils_cat_file ,
+.Nm atf_utils_compare_file ,
+.Nm atf_utils_copy_file ,
+.Nm atf_utils_create_file ,
+.Nm atf_utils_file_exists ,
+.Nm atf_utils_fork ,
+.Nm atf_utils_free_charpp ,
+.Nm atf_utils_grep_file ,
+.Nm atf_utils_grep_string ,
+.Nm atf_utils_readline ,
+.Nm atf_utils_redirect ,
+.Nm atf_utils_wait
+.Nd C API to write ATF-based test programs
+.Sh SYNOPSIS
+.In atf-c.h
+.\" NO_CHECK_STYLE_BEGIN
+.Fn ATF_CHECK "expression"
+.Fn ATF_CHECK_MSG "expression" "fail_msg_fmt" ...
+.Fn ATF_CHECK_EQ "expected_expression" "actual_expression"
+.Fn ATF_CHECK_EQ_MSG "expected_expression" "actual_expression" "fail_msg_fmt" ...
+.Fn ATF_CHECK_MATCH "regexp" "string"
+.Fn ATF_CHECK_MATCH_MSG "regexp" "string" "fail_msg_fmt" ...
+.Fn ATF_CHECK_STREQ "string_1" "string_2"
+.Fn ATF_CHECK_STREQ_MSG "string_1" "string_2" "fail_msg_fmt" ...
+.Fn ATF_CHECK_ERRNO "expected_errno" "bool_expression"
+.Fn ATF_REQUIRE "expression"
+.Fn ATF_REQUIRE_MSG "expression" "fail_msg_fmt" ...
+.Fn ATF_REQUIRE_EQ "expected_expression" "actual_expression"
+.Fn ATF_REQUIRE_EQ_MSG "expected_expression" "actual_expression" "fail_msg_fmt" ...
+.Fn ATF_REQUIRE_MATCH "regexp" "string"
+.Fn ATF_REQUIRE_MATCH_MSG "regexp" "string" "fail_msg_fmt" ...
+.Fn ATF_REQUIRE_STREQ "expected_string" "actual_string"
+.Fn ATF_REQUIRE_STREQ_MSG "expected_string" "actual_string" "fail_msg_fmt" ...
+.Fn ATF_REQUIRE_ERRNO "expected_errno" "bool_expression"
+.\" NO_CHECK_STYLE_END
+.Fn ATF_TC "name"
+.Fn ATF_TC_BODY "name" "tc"
+.Fn ATF_TC_BODY_NAME "name"
+.Fn ATF_TC_CLEANUP "name" "tc"
+.Fn ATF_TC_CLEANUP_NAME "name"
+.Fn ATF_TC_HEAD "name" "tc"
+.Fn ATF_TC_HEAD_NAME "name"
+.Fn ATF_TC_NAME "name"
+.Fn ATF_TC_WITH_CLEANUP "name"
+.Fn ATF_TC_WITHOUT_HEAD "name"
+.Fn ATF_TP_ADD_TC "tp_name" "tc_name"
+.Fn ATF_TP_ADD_TCS "tp_name"
+.Fn atf_tc_get_config_var "tc" "varname"
+.Fn atf_tc_get_config_var_wd "tc" "variable_name" "default_value"
+.Fn atf_tc_get_config_var_as_bool "tc" "variable_name"
+.Fn atf_tc_get_config_var_as_bool_wd "tc" "variable_name" "default_value"
+.Fn atf_tc_get_config_var_as_long "tc" "variable_name"
+.Fn atf_tc_get_config_var_as_long_wd "tc" "variable_name" "default_value"
+.Fn atf_no_error
+.Fn atf_tc_expect_death "reason" "..."
+.Fn atf_tc_expect_exit "exitcode" "reason" "..."
+.Fn atf_tc_expect_fail "reason" "..."
+.Fn atf_tc_expect_pass
+.Fn atf_tc_expect_signal "signo" "reason" "..."
+.Fn atf_tc_expect_timeout "reason" "..."
+.Fn atf_tc_fail "reason"
+.Fn atf_tc_fail_nonfatal "reason"
+.Fn atf_tc_pass
+.Fn atf_tc_skip "reason"
+.Ft void
+.Fo atf_utils_cat_file
+.Fa "const char *file"
+.Fa "const char *prefix"
+.Fc
+.Ft bool
+.Fo atf_utils_compare_file
+.Fa "const char *file"
+.Fa "const char *contents"
+.Fc
+.Ft void
+.Fo atf_utils_copy_file
+.Fa "const char *source"
+.Fa "const char *destination"
+.Fc
+.Ft void
+.Fo atf_utils_create_file
+.Fa "const char *file"
+.Fa "const char *contents"
+.Fa "..."
+.Fc
+.Ft void
+.Fo atf_utils_file_exists
+.Fa "const char *file"
+.Fc
+.Ft pid_t
+.Fo atf_utils_fork
+.Fa "void"
+.Fc
+.Ft void
+.Fo atf_utils_free_charpp
+.Fa "char **argv"
+.Fc
+.Ft bool
+.Fo atf_utils_grep_file
+.Fa "const char *regexp"
+.Fa "const char *file"
+.Fa "..."
+.Fc
+.Ft bool
+.Fo atf_utils_grep_string
+.Fa "const char *regexp"
+.Fa "const char *str"
+.Fa "..."
+.Fc
+.Ft char *
+.Fo atf_utils_readline
+.Fa "int fd"
+.Fc
+.Ft void
+.Fo atf_utils_redirect
+.Fa "const int fd"
+.Fa "const char *file"
+.Fc
+.Ft void
+.Fo atf_utils_wait
+.Fa "const pid_t pid"
+.Fa "const int expected_exit_status"
+.Fa "const char *expected_stdout"
+.Fa "const char *expected_stderr"
+.Fc
+.Sh DESCRIPTION
+ATF provides a C programming interface to implement test programs.
+C-based test programs follow this template:
+.Bd -literal -offset indent
+\&... C-specific includes go here ...
+
+#include <atf-c.h>
+
+ATF_TC(tc1);
+ATF_TC_HEAD(tc1, tc)
+{
+    ... first test case's header ...
+}
+ATF_TC_BODY(tc1, tc)
+{
+    ... first test case's body ...
+}
+
+ATF_TC_WITH_CLEANUP(tc2);
+ATF_TC_HEAD(tc2, tc)
+{
+    ... second test case's header ...
+}
+ATF_TC_BODY(tc2, tc)
+{
+    ... second test case's body ...
+}
+ATF_TC_CLEANUP(tc2, tc)
+{
+    ... second test case's cleanup ...
+}
+
+ATF_TC_WITHOUT_HEAD(tc3);
+ATF_TC_BODY(tc3, tc)
+{
+    ... third test case's body ...
+}
+
+\&... additional test cases ...
+
+ATF_TP_ADD_TCS(tp)
+{
+    ATF_TP_ADD_TC(tcs, tc1);
+    ATF_TP_ADD_TC(tcs, tc2);
+    ATF_TP_ADD_TC(tcs, tc3);
+    ... add additional test cases ...
+
+    return atf_no_error();
+}
+.Ed
+.Ss Definition of test cases
+Test cases have an identifier and are composed of three different parts:
+the header, the body and an optional cleanup routine, all of which are
+described in
+.Xr atf-test-case 4 .
+To define test cases, one can use the
+.Fn ATF_TC ,
+.Fn ATF_TC_WITH_CLEANUP
+or the
+.Fn ATF_TC_WITHOUT_HEAD
+macros, which take a single parameter specifying the test case's name.
+.Fn ATF_TC ,
+requires to define a head and a body for the test case,
+.Fn ATF_TC_WITH_CLEANUP
+requires to define a head, a body and a cleanup for the test case and
+.Fn ATF_TC_WITHOUT_HEAD
+requires only a body for the test case.
+It is important to note that these
+.Em do not
+set the test case up for execution when the program is run.
+In order to do so, a later registration is needed with the
+.Fn ATF_TP_ADD_TC
+macro detailed in
+.Sx Program initialization .
+.Pp
+Later on, one must define the three parts of the body by means of three
+functions.
+Their headers are given by the
+.Fn ATF_TC_HEAD ,
+.Fn ATF_TC_BODY
+and
+.Fn ATF_TC_CLEANUP
+macros, all of which take the test case name provided to the
+.Fn ATF_TC
+.Fn ATF_TC_WITH_CLEANUP ,
+or
+.Fn ATF_TC_WITHOUT_HEAD
+macros and the name of the variable that will hold a pointer to the
+test case data.
+Following each of these, a block of code is expected, surrounded by the
+opening and closing brackets.
+.Ss Program initialization
+The library provides a way to easily define the test program's
+.Fn main
+function.
+You should never define one on your own, but rely on the
+library to do it for you.
+This is done by using the
+.Fn ATF_TP_ADD_TCS
+macro, which is passed the name of the object that will hold the test
+cases, i.e., the test program instance.
+This name can be whatever you want as long as it is a valid variable
+identifier.
+.Pp
+After the macro, you are supposed to provide the body of a function, which
+should only use the
+.Fn ATF_TP_ADD_TC
+macro to register the test cases the test program will execute and return
+a success error code.
+The first parameter of this macro matches the name you provided in the
+former call.
+The success status can be returned using the
+.Fn atf_no_error
+function.
+.Ss Header definitions
+The test case's header can define the meta-data by using the
+.Fn atf_tc_set_md_var
+method, which takes three parameters: the first one points to the test
+case data, the second one specifies the meta-data variable to be set
+and the third one specifies its value.
+Both of them are strings.
+.Ss Configuration variables
+The test case has read-only access to the current configuration variables
+by means of the
+.Ft bool
+.Fn atf_tc_has_config_var ,
+.Ft const char *
+.Fn atf_tc_get_config_var ,
+.Ft const char *
+.Fn atf_tc_get_config_var_wd ,
+.Ft bool
+.Fn atf_tc_get_config_var_as_bool ,
+.Ft bool
+.Fn atf_tc_get_config_var_as_bool_wd ,
+.Ft long
+.Fn atf_tc_get_config_var_as_long ,
+and the
+.Ft long
+.Fn atf_tc_get_config_var_as_long_wd
+functions, which can be called in any of the three parts of a test case.
+.Pp
+The
+.Sq _wd
+variants take a default value for the variable which is returned if the
+variable is not defined.
+The other functions without the
+.Sq _wd
+suffix
+.Em require
+the variable to be defined.
+.Ss Access to the source directory
+It is possible to get the path to the test case's source directory from any
+of its three components by querying the
+.Sq srcdir
+configuration variable.
+.Ss Requiring programs
+Aside from the
+.Va require.progs
+meta-data variable available in the header only, one can also check for
+additional programs in the test case's body by using the
+.Fn atf_tc_require_prog
+function, which takes the base name or full path of a single binary.
+Relative paths are forbidden.
+If it is not found, the test case will be automatically skipped.
+.Ss Test case finalization
+The test case finalizes either when the body reaches its end, at which
+point the test is assumed to have
+.Em passed ,
+unless any non-fatal errors were raised using
+.Fn atf_tc_fail_nonfatal ,
+or at any explicit call to
+.Fn atf_tc_pass ,
+.Fn atf_tc_fail
+or
+.Fn atf_tc_skip .
+These three functions terminate the execution of the test case immediately.
+The cleanup routine will be processed afterwards in a completely automated
+way, regardless of the test case's termination reason.
+.Pp
+.Fn atf_tc_pass
+does not take any parameters.
+.Fn atf_tc_fail ,
+.Fn atf_tc_fail_nonfatal
+and
+.Fn atf_tc_skip
+take a format string and a variable list of parameters, which describe, in
+a user-friendly manner, why the test case failed or was skipped,
+respectively.
+It is very important to provide a clear error message in both cases so that
+the user can quickly know why the test did not pass.
+.Ss Expectations
+Everything explained in the previous section changes when the test case
+expectations are redefined by the programmer.
+.Pp
+Each test case has an internal state called
+.Sq expect
+that describes what the test case expectations are at any point in time.
+The value of this property can change during execution by any of:
+.Bl -tag -width indent
+.It Fn atf_tc_expect_death "reason" "..."
+Expects the test case to exit prematurely regardless of the nature of the
+exit.
+.It Fn atf_tc_expect_exit "exitcode" "reason" "..."
+Expects the test case to exit cleanly.
+If
+.Va exitcode
+is not
+.Sq -1 ,
+the runtime engine will validate that the exit code of the test case
+matches the one provided in this call.
+Otherwise, the exact value will be ignored.
+.It Fn atf_tc_expect_fail "reason" "..."
+Any failure (be it fatal or non-fatal) raised in this mode is recorded.
+However, such failures do not report the test case as failed; instead, the
+test case finalizes cleanly and is reported as
+.Sq expected failure ;
+this report includes the provided
+.Fa reason
+as part of it.
+If no error is raised while running in this mode, then the test case is
+reported as
+.Sq failed .
+.Pp
+This mode is useful to reproduce actual known bugs in tests.
+Whenever the developer fixes the bug later on, the test case will start
+reporting a failure, signaling the developer that the test case must be
+adjusted to the new conditions.
+In this situation, it is useful, for example, to set
+.Fa reason
+as the bug number for tracking purposes.
+.It Fn atf_tc_expect_pass
+This is the normal mode of execution.
+In this mode, any failure is reported as such to the user and the test case
+is marked as
+.Sq failed .
+.It Fn atf_tc_expect_signal "signo" "reason" "..."
+Expects the test case to terminate due to the reception of a signal.
+If
+.Va signo
+is not
+.Sq -1 ,
+the runtime engine will validate that the signal that terminated the test
+case matches the one provided in this call.
+Otherwise, the exact value will be ignored.
+.It Fn atf_tc_expect_timeout "reason" "..."
+Expects the test case to execute for longer than its timeout.
+.El
+.Ss Helper macros for common checks
+The library provides several macros that are very handy in multiple
+situations.
+These basically check some condition after executing a given statement or
+processing a given expression and, if the condition is not met, they
+report the test case as failed.
+.Pp
+The
+.Sq REQUIRE
+variant of the macros immediately abort the test case as soon as an error
+condition is detected by calling the
+.Fn atf_tc_fail
+function.
+Use this variant whenever it makes no sense to continue the execution of a
+test case when the checked condition is not met.
+The
+.Sq CHECK
+variant, on the other hand, reports a failure as soon as it is encountered
+using the
+.Fn atf_tc_fail_nonfatal
+function, but the execution of the test case continues as if nothing had
+happened.
+Use this variant whenever the checked condition is important as a result of
+the test case, but there are other conditions that can be subsequently
+checked on the same run without aborting.
+.Pp
+Additionally, the
+.Sq MSG
+variants take an extra set of parameters to explicitly specify the failure
+message.
+This failure message is formatted according to the
+.Xr printf 3
+formatters.
+.Pp
+.Fn ATF_CHECK ,
+.Fn ATF_CHECK_MSG ,
+.Fn ATF_REQUIRE
+and
+.Fn ATF_REQUIRE_MSG
+take an expression and fail if the expression evaluates to false.
+.Pp
+.Fn ATF_CHECK_EQ ,
+.Fn ATF_CHECK_EQ_MSG ,
+.Fn ATF_REQUIRE_EQ
+and
+.Fn ATF_REQUIRE_EQ_MSG
+take two expressions and fail if the two evaluated values are not equal.
+The common style is to put the expected value in the first parameter and the
+actual value in the second parameter.
+.Pp
+.Fn ATF_CHECK_MATCH ,
+.Fn ATF_CHECK_MATCH_MSG ,
+.Fn ATF_REQUIRE_MATCH
+and
+.Fn ATF_REQUIRE_MATCH_MSG
+take a regular expression and a string and fail if the regular expression does
+not match the given string.
+Note that the regular expression is not anchored, so it will match anywhere in
+the string.
+.Pp
+.Fn ATF_CHECK_STREQ ,
+.Fn ATF_CHECK_STREQ_MSG ,
+.Fn ATF_REQUIRE_STREQ
+and
+.Fn ATF_REQUIRE_STREQ_MSG
+take two strings and fail if the two are not equal character by character.
+The common style is to put the expected string in the first parameter and the
+actual string in the second parameter.
+.Pp
+.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
+.Va errno
+has to be checked against the first value.
+.Ss Utility functions
+The following functions are provided as part of the
+.Nm
+API to simplify the creation of a variety of tests.
+In particular, these are useful to write tests for command-line interfaces.
+.Pp
+.Ft void
+.Fo atf_utils_cat_file
+.Fa "const char *file"
+.Fa "const char *prefix"
+.Fc
+.Bd -ragged -offset indent
+Prints the contents of
+.Fa file
+to the standard output, prefixing every line with the string in
+.Fa prefix .
+.Ed
+.Pp
+.Ft bool
+.Fo atf_utils_compare_file
+.Fa "const char *file"
+.Fa "const char *contents"
+.Fc
+.Bd -ragged -offset indent
+Returns true if the given
+.Fa file
+matches exactly the expected inlined
+.Fa contents .
+.Ed
+.Pp
+.Ft void
+.Fo atf_utils_copy_file
+.Fa "const char *source"
+.Fa "const char *destination"
+.Fc
+.Bd -ragged -offset indent
+Copies the file
+.Fa source
+to
+.Fa destination .
+The permissions of the file are preserved during the code.
+.Ed
+.Pp
+.Ft void
+.Fo atf_utils_create_file
+.Fa "const char *file"
+.Fa "const char *contents"
+.Fa "..."
+.Fc
+.Bd -ragged -offset indent
+Creates
+.Fa file
+with the text given in
+.Fa contents ,
+which is a formatting string that uses the rest of the variable arguments.
+.Ed
+.Pp
+.Ft void
+.Fo atf_utils_file_exists
+.Fa "const char *file"
+.Fc
+.Bd -ragged -offset indent
+Checks if
+.Fa file
+exists.
+.Ed
+.Pp
+.Ft pid_t
+.Fo atf_utils_fork
+.Fa "void"
+.Fc
+.Bd -ragged -offset indent
+Forks a process and redirects the standard output and standard error of the
+child to files for later validation with
+.Fn atf_utils_wait .
+Fails the test case if the fork fails, so this does not return an error.
+.Ed
+.Pp
+.Ft void
+.Fo atf_utils_free_charpp
+.Fa "char **argv"
+.Fc
+.Bd -ragged -offset indent
+Frees a dynamically-allocated array of dynamically-allocated strings.
+.Ed
+.Pp
+.Ft bool
+.Fo atf_utils_grep_file
+.Fa "const char *regexp"
+.Fa "const char *file"
+.Fa "..."
+.Fc
+.Bd -ragged -offset indent
+Searches for the
+.Fa regexp ,
+which is a formatting string representing the regular expression,
+in the
+.Fa file .
+The variable arguments are used to construct the regular expression.
+.Ed
+.Pp
+.Ft bool
+.Fo atf_utils_grep_string
+.Fa "const char *regexp"
+.Fa "const char *str"
+.Fa "..."
+.Fc
+.Bd -ragged -offset indent
+Searches for the
+.Fa regexp ,
+which is a formatting string representing the regular expression,
+in the literal string
+.Fa str .
+The variable arguments are used to construct the regular expression.
+.Ed
+.Pp
+.Ft char *
+.Fo atf_utils_readline
+.Fa "int fd"
+.Fc
+.Bd -ragged -offset indent
+Reads a line from the file descriptor
+.Fa fd .
+The line, if any, is returned as a dynamically-allocated buffer that must be
+released with
+.Xr free 3 .
+If there was nothing to read, returns
+.Sq NULL .
+.Ed
+.Pp
+.Ft void
+.Fo atf_utils_redirect
+.Fa "const int fd"
+.Fa "const char *file"
+.Fc
+.Bd -ragged -offset indent
+Redirects the given file descriptor
+.Fa fd
+to
+.Fa file .
+This function exits the process in case of an error and does not properly mark
+the test case as failed.
+As a result, it should only be used in subprocesses of the test case; specially
+those spawned by
+.Fn atf_utils_fork .
+.Ed
+.Pp
+.Ft void
+.Fo atf_utils_wait
+.Fa "const pid_t pid"
+.Fa "const int expected_exit_status"
+.Fa "const char *expected_stdout"
+.Fa "const char *expected_stderr"
+.Fc
+.Bd -ragged -offset indent
+Waits and validates the result of a subprocess spawned with
+.Fn atf_utils_fork .
+The validation involves checking that the subprocess exited cleanly and returned
+the code specified in
+.Fa expected_exit_status
+and that its standard output and standard error match the strings given in
+.Fa expected_stdout
+and
+.Fa expected_stderr .
+.Pp
+If any of the
+.Fa expected_stdout
+or
+.Fa expected_stderr
+strings are prefixed with
+.Sq save: ,
+then they specify the name of the file into which to store the stdout or stderr
+of the subprocess, and no comparison is performed.
+.Ed
+.Sh ENVIRONMENT
+The following variables are recognized by
+.Nm
+but should not be overridden other than for testing purposes:
+.Pp
+.Bl -tag -width ATFXBUILDXCXXFLAGSXX -compact
+.It Va ATF_BUILD_CC
+Path to the C compiler.
+.It Va ATF_BUILD_CFLAGS
+C compiler flags.
+.It Va ATF_BUILD_CPP
+Path to the C/C++ preprocessor.
+.It Va ATF_BUILD_CPPFLAGS
+C/C++ preprocessor flags.
+.It Va ATF_BUILD_CXX
+Path to the C++ compiler.
+.It Va ATF_BUILD_CXXFLAGS
+C++ compiler flags.
+.El
+.Sh EXAMPLES
+The following shows a complete test program with a single test case that
+validates the addition operator:
+.Bd -literal -offset indent
+#include <atf-c.h>
+
+ATF_TC(addition);
+ATF_TC_HEAD(addition, tc)
+{
+    atf_tc_set_md_var(tc, "descr",
+                      "Sample tests for the addition operator");
+}
+ATF_TC_BODY(addition, tc)
+{
+    ATF_CHECK_EQ(0, 0 + 0);
+    ATF_CHECK_EQ(1, 0 + 1);
+    ATF_CHECK_EQ(1, 1 + 0);
+
+    ATF_CHECK_EQ(2, 1 + 1);
+
+    ATF_CHECK_EQ(300, 100 + 200);
+}
+
+ATF_TC(string_formatting);
+ATF_TC_HEAD(string_formatting, tc)
+{
+    atf_tc_set_md_var(tc, "descr",
+                      "Sample tests for the snprintf");
+}
+ATF_TC_BODY(string_formatting, tc)
+{
+    char buf[1024];
+    snprintf(buf, sizeof(buf), "a %s", "string");
+    ATF_CHECK_STREQ_MSG("a string", buf, "%s is not working");
+}
+
+ATF_TC(open_failure);
+ATF_TC_HEAD(open_failure, tc)
+{
+    atf_tc_set_md_var(tc, "descr",
+                      "Sample tests for the open function");
+}
+ATF_TC_BODY(open_failure, tc)
+{
+    ATF_CHECK_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
+}
+
+ATF_TC(known_bug);
+ATF_TC_HEAD(known_bug, tc)
+{
+    atf_tc_set_md_var(tc, "descr",
+                      "Reproduces a known bug");
+}
+ATF_TC_BODY(known_bug, tc)
+{
+    atf_tc_expect_fail("See bug number foo/bar");
+    ATF_CHECK_EQ(3, 1 + 1);
+    atf_tc_expect_pass();
+    ATF_CHECK_EQ(3, 1 + 2);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+    ATF_TP_ADD_TC(tp, addition);
+    ATF_TP_ADD_TC(tp, string_formatting);
+    ATF_TP_ADD_TC(tp, open_failure);
+    ATF_TP_ADD_TC(tp, known_bug);
+
+    return atf_no_error();
+}
+.Ed
+.Sh SEE ALSO
+.Xr atf-test-program 1 ,
+.Xr atf-test-case 4

Added: vendor/atf/dist/atf-c/atf_c_test.c
===================================================================
--- vendor/atf/dist/atf-c/atf_c_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/atf_c_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,46 @@
+/* Copyright (c) 2008 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.h>
+
+#include "atf-c/detail/test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+HEADER_TC(include, "atf-c.h");
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    /* Add the test cases for the header file. */
+    ATF_TP_ADD_TC(tp, include);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/build.c
===================================================================
--- vendor/atf/dist/atf-c/build.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/build.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,282 @@
+/* Copyright (c) 2009 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/build.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "atf-c/detail/env.h"
+#include "atf-c/detail/sanity.h"
+#include "atf-c/detail/text.h"
+#include "atf-c/error.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+atf_error_t
+append_config_var(const char *var, const char *default_value, atf_list_t *argv)
+{
+    atf_error_t err;
+    atf_list_t words;
+
+    err = atf_text_split(atf_env_get_with_default(var, default_value),
+                         " ", &words);
+    if (atf_is_error(err))
+        goto out;
+
+    atf_list_append_list(argv, &words);
+
+out:
+    return err;
+}
+
+static
+atf_error_t
+append_arg1(const char *arg, atf_list_t *argv)
+{
+    return atf_list_append(argv, strdup(arg), true);
+}
+
+static
+atf_error_t
+append_arg2(const char *flag, const char *arg, atf_list_t *argv)
+{
+    atf_error_t err;
+
+    err = append_arg1(flag, argv);
+    if (!atf_is_error(err))
+        err = append_arg1(arg, argv);
+
+    return err;
+}
+
+static
+atf_error_t
+append_optargs(const char *const optargs[], atf_list_t *argv)
+{
+    atf_error_t err;
+
+    err = atf_no_error();
+    while (*optargs != NULL && !atf_is_error(err)) {
+        err = append_arg1(strdup(*optargs), argv);
+        optargs++;
+    }
+
+    return err;
+}
+
+static
+atf_error_t
+append_src_out(const char *src, const char *obj, atf_list_t *argv)
+{
+    atf_error_t err;
+
+    err = append_arg2("-o", obj, argv);
+    if (atf_is_error(err))
+        goto out;
+
+    err = append_arg1("-c", argv);
+    if (atf_is_error(err))
+        goto out;
+
+    err = append_arg1(src, argv);
+
+out:
+    return err;
+}
+
+static
+atf_error_t
+list_to_array(const atf_list_t *l, char ***ap)
+{
+    atf_error_t err;
+    char **a;
+
+    a = (char **)malloc((atf_list_size(l) + 1) * sizeof(char *));
+    if (a == NULL)
+        err = atf_no_memory_error();
+    else {
+        char **aiter;
+        atf_list_citer_t liter;
+
+        aiter = a;
+        atf_list_for_each_c(liter, l) {
+            *aiter = strdup((const char *)atf_list_citer_data(liter));
+            aiter++;
+        }
+        *aiter = NULL;
+
+        err = atf_no_error();
+    }
+    *ap = a; /* Shut up warnings in the caller about uninitialized *ap. */
+
+    return err;
+}
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+atf_error_t
+atf_build_c_o(const char *sfile,
+              const char *ofile,
+              const char *const optargs[],
+              char ***argv)
+{
+    atf_error_t err;
+    atf_list_t argv_list;
+
+    err = atf_list_init(&argv_list);
+    if (atf_is_error(err))
+        goto out;
+
+    err = append_config_var("ATF_BUILD_CC", ATF_BUILD_CC, &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    err = append_config_var("ATF_BUILD_CPPFLAGS", ATF_BUILD_CPPFLAGS,
+                            &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    err = append_config_var("ATF_BUILD_CFLAGS", ATF_BUILD_CFLAGS, &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    if (optargs != NULL) {
+        err = append_optargs(optargs, &argv_list);
+        if (atf_is_error(err))
+            goto out_list;
+    }
+
+    err = append_src_out(sfile, ofile, &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    err = list_to_array(&argv_list, argv);
+    if (atf_is_error(err))
+        goto out_list;
+
+out_list:
+    atf_list_fini(&argv_list);
+out:
+    return err;
+}
+
+atf_error_t
+atf_build_cpp(const char *sfile,
+              const char *ofile,
+              const char *const optargs[],
+              char ***argv)
+{
+    atf_error_t err;
+    atf_list_t argv_list;
+
+    err = atf_list_init(&argv_list);
+    if (atf_is_error(err))
+        goto out;
+
+    err = append_config_var("ATF_BUILD_CPP", ATF_BUILD_CPP, &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    err = append_config_var("ATF_BUILD_CPPFLAGS", ATF_BUILD_CPPFLAGS,
+                            &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    if (optargs != NULL) {
+        err = append_optargs(optargs, &argv_list);
+        if (atf_is_error(err))
+            goto out_list;
+    }
+
+    err = append_arg2("-o", ofile, &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    err = append_arg1(sfile, &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    err = list_to_array(&argv_list, argv);
+    if (atf_is_error(err))
+        goto out_list;
+
+out_list:
+    atf_list_fini(&argv_list);
+out:
+    return err;
+}
+
+atf_error_t
+atf_build_cxx_o(const char *sfile,
+                const char *ofile,
+                const char *const optargs[],
+                char ***argv)
+{
+    atf_error_t err;
+    atf_list_t argv_list;
+
+    err = atf_list_init(&argv_list);
+    if (atf_is_error(err))
+        goto out;
+
+    err = append_config_var("ATF_BUILD_CXX", ATF_BUILD_CXX, &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    err = append_config_var("ATF_BUILD_CPPFLAGS", ATF_BUILD_CPPFLAGS,
+                            &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    err = append_config_var("ATF_BUILD_CXXFLAGS", ATF_BUILD_CXXFLAGS,
+                            &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    if (optargs != NULL) {
+        err = append_optargs(optargs, &argv_list);
+        if (atf_is_error(err))
+            goto out_list;
+    }
+
+    err = append_src_out(sfile, ofile, &argv_list);
+    if (atf_is_error(err))
+        goto out_list;
+
+    err = list_to_array(&argv_list, argv);
+    if (atf_is_error(err))
+        goto out_list;
+
+out_list:
+    atf_list_fini(&argv_list);
+out:
+    return err;
+}

Added: vendor/atf/dist/atf-c/build.h
===================================================================
--- vendor/atf/dist/atf-c/build.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/build.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,38 @@
+/* Copyright (c) 2009 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_C_BUILD_H)
+#define ATF_C_BUILD_H
+
+#include <atf-c/error_fwd.h>
+
+atf_error_t atf_build_c_o(const char *, const char *, const char *const [],
+                          char ***);
+atf_error_t atf_build_cpp(const char *, const char *, const char *const [],
+                          char ***);
+atf_error_t atf_build_cxx_o(const char *, const char *, const char *const [],
+                            char ***);
+
+#endif /* !defined(ATF_C_BUILD_H) */

Added: vendor/atf/dist/atf-c/build_test.c
===================================================================
--- vendor/atf/dist/atf-c/build_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/build_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,249 @@
+/* Copyright (c) 2009 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/build.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/env.h"
+#include "atf-c/detail/test_helpers.h"
+#include "atf-c/h_build.h"
+#include "atf-c/utils.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+bool
+equal_arrays(const char *const *exp_array, char **actual_array)
+{
+    bool equal;
+
+    if (*exp_array == NULL && *actual_array == NULL)
+        equal = true;
+    else if (*exp_array == NULL || *actual_array == NULL)
+        equal = false;
+    else {
+        equal = true;
+        while (*actual_array != NULL) {
+            if (*exp_array == NULL || strcmp(*exp_array, *actual_array) != 0) {
+                equal = false;
+                break;
+            }
+            exp_array++;
+            actual_array++;
+        }
+    }
+
+    return equal;
+}
+
+static
+void
+check_equal_array(const char *const *exp_array, char **actual_array)
+{
+    {
+        const char *const *exp_ptr;
+        printf("Expected arguments:");
+        for (exp_ptr = exp_array; *exp_ptr != NULL; exp_ptr++)
+            printf(" '%s'", *exp_ptr);
+        printf("\n");
+    }
+
+    {
+        char **actual_ptr;
+        printf("Returned arguments:");
+        for (actual_ptr = actual_array; *actual_ptr != NULL; actual_ptr++)
+            printf(" '%s'", *actual_ptr);
+        printf("\n");
+    }
+
+    if (!equal_arrays(exp_array, actual_array))
+        atf_tc_fail_nonfatal("The constructed argv differs from the "
+                             "expected values");
+}
+
+static
+void
+verbose_set_env(const char *var, const char *val)
+{
+    printf("Setting %s to '%s'\n", var, val);
+    RE(atf_env_set(var, val));
+}
+
+/* ---------------------------------------------------------------------
+ * Internal test cases.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(equal_arrays);
+ATF_TC_HEAD(equal_arrays, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the test case internal "
+                      "equal_arrays function");
+}
+ATF_TC_BODY(equal_arrays, tc)
+{
+    {
+        const char *const exp[] = { NULL };
+        char *actual[] = { NULL };
+
+        ATF_CHECK(equal_arrays(exp, actual));
+    }
+
+    {
+        const char *const exp[] = { NULL };
+        char *actual[2] = { strdup("foo"), NULL };
+
+        ATF_CHECK(!equal_arrays(exp, actual));
+        free(actual[0]);
+    }
+
+    {
+        const char *const exp[] = { "foo", NULL };
+        char *actual[] = { NULL };
+
+        ATF_CHECK(!equal_arrays(exp, actual));
+    }
+
+    {
+        const char *const exp[] = { "foo", NULL };
+        char *actual[2] = { strdup("foo"), NULL };
+
+        ATF_CHECK(equal_arrays(exp, actual));
+        free(actual[0]);
+    }
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(c_o);
+ATF_TC_HEAD(c_o, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_build_c_o function");
+}
+ATF_TC_BODY(c_o, tc)
+{
+    struct c_o_test *test;
+
+    for (test = c_o_tests; test->expargv[0] != NULL; test++) {
+        printf("> Test: %s\n", test->msg);
+
+        verbose_set_env("ATF_BUILD_CC", test->cc);
+        verbose_set_env("ATF_BUILD_CFLAGS", test->cflags);
+        verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+
+        {
+            char **argv;
+            if (test->hasoptargs)
+                RE(atf_build_c_o(test->sfile, test->ofile, test->optargs,
+                                 &argv));
+            else
+                RE(atf_build_c_o(test->sfile, test->ofile, NULL, &argv));
+            check_equal_array(test->expargv, argv);
+            atf_utils_free_charpp(argv);
+        }
+    }
+}
+
+ATF_TC(cpp);
+ATF_TC_HEAD(cpp, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_build_cpp function");
+}
+ATF_TC_BODY(cpp, tc)
+{
+    struct cpp_test *test;
+
+    for (test = cpp_tests; test->expargv[0] != NULL; test++) {
+        printf("> Test: %s\n", test->msg);
+
+        verbose_set_env("ATF_BUILD_CPP", test->cpp);
+        verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+
+        {
+            char **argv;
+            if (test->hasoptargs)
+                RE(atf_build_cpp(test->sfile, test->ofile, test->optargs,
+                                 &argv));
+            else
+                RE(atf_build_cpp(test->sfile, test->ofile, NULL, &argv));
+            check_equal_array(test->expargv, argv);
+            atf_utils_free_charpp(argv);
+        }
+    }
+}
+
+ATF_TC(cxx_o);
+ATF_TC_HEAD(cxx_o, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_build_cxx_o function");
+}
+ATF_TC_BODY(cxx_o, tc)
+{
+    struct cxx_o_test *test;
+
+    for (test = cxx_o_tests; test->expargv[0] != NULL; test++) {
+        printf("> Test: %s\n", test->msg);
+
+        verbose_set_env("ATF_BUILD_CXX", test->cxx);
+        verbose_set_env("ATF_BUILD_CXXFLAGS", test->cxxflags);
+        verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+
+        {
+            char **argv;
+            if (test->hasoptargs)
+                RE(atf_build_cxx_o(test->sfile, test->ofile, test->optargs,
+                                   &argv));
+            else
+                RE(atf_build_cxx_o(test->sfile, test->ofile, NULL, &argv));
+            check_equal_array(test->expargv, argv);
+            atf_utils_free_charpp(argv);
+        }
+    }
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    /* Add the internal test cases. */
+    ATF_TP_ADD_TC(tp, equal_arrays);
+
+    /* Add the test cases for the free functions. */
+    ATF_TP_ADD_TC(tp, c_o);
+    ATF_TP_ADD_TC(tp, cpp);
+    ATF_TP_ADD_TC(tp, cxx_o);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/check.c
===================================================================
--- vendor/atf/dist/atf-c/check.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/check.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,484 @@
+/* Copyright (c) 2008 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/check.h"
+
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "atf-c/build.h"
+#include "atf-c/defs.h"
+#include "atf-c/detail/dynstr.h"
+#include "atf-c/detail/env.h"
+#include "atf-c/detail/fs.h"
+#include "atf-c/detail/list.h"
+#include "atf-c/detail/process.h"
+#include "atf-c/detail/sanity.h"
+#include "atf-c/error.h"
+#include "atf-c/utils.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+atf_error_t
+create_tmpdir(atf_fs_path_t *dir)
+{
+    atf_error_t err;
+
+    err = atf_fs_path_init_fmt(dir, "%s/check.XXXXXX",
+                               atf_env_get_with_default("TMPDIR", "/tmp"));
+    if (atf_is_error(err))
+        goto out;
+
+    err = atf_fs_mkdtemp(dir);
+    if (atf_is_error(err)) {
+        atf_fs_path_fini(dir);
+        goto out;
+    }
+
+    INV(!atf_is_error(err));
+out:
+    return err;
+}
+
+static
+void
+cleanup_tmpdir(const atf_fs_path_t *dir, const atf_fs_path_t *outfile,
+               const atf_fs_path_t *errfile)
+{
+    {
+        atf_error_t err = atf_fs_unlink(outfile);
+        if (atf_is_error(err)) {
+            INV(atf_error_is(err, "libc") &&
+                atf_libc_error_code(err) == ENOENT);
+            atf_error_free(err);
+        } else
+            INV(!atf_is_error(err));
+    }
+
+    {
+        atf_error_t err = atf_fs_unlink(errfile);
+        if (atf_is_error(err)) {
+            INV(atf_error_is(err, "libc") &&
+                atf_libc_error_code(err) == ENOENT);
+            atf_error_free(err);
+        } else
+            INV(!atf_is_error(err));
+    }
+
+    {
+        atf_error_t err = atf_fs_rmdir(dir);
+        INV(!atf_is_error(err));
+    }
+}
+
+static
+int
+const_execvp(const char *file, const char *const *argv)
+{
+#define UNCONST(a) ((void *)(unsigned long)(const void *)(a))
+    return execvp(file, UNCONST(argv));
+#undef UNCONST
+}
+
+static
+atf_error_t
+init_sb(const atf_fs_path_t *path, atf_process_stream_t *sb)
+{
+    atf_error_t err;
+
+    if (path == NULL)
+        err = atf_process_stream_init_inherit(sb);
+    else
+        err = atf_process_stream_init_redirect_path(sb, path);
+
+    return err;
+}
+
+static
+atf_error_t
+init_sbs(const atf_fs_path_t *outfile, atf_process_stream_t *outsb,
+         const atf_fs_path_t *errfile, atf_process_stream_t *errsb)
+{
+    atf_error_t err;
+
+    err = init_sb(outfile, outsb);
+    if (atf_is_error(err))
+        goto out;
+
+    err = init_sb(errfile, errsb);
+    if (atf_is_error(err)) {
+        atf_process_stream_fini(outsb);
+        goto out;
+    }
+
+out:
+    return err;
+}
+
+struct exec_data {
+    const char *const *m_argv;
+};
+
+static void exec_child(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
+
+static
+void
+exec_child(void *v)
+{
+    struct exec_data *ea = v;
+
+    const_execvp(ea->m_argv[0], ea->m_argv);
+    fprintf(stderr, "execvp(%s) failed: %s\n", ea->m_argv[0], strerror(errno));
+    exit(127);
+}
+
+static
+atf_error_t
+fork_and_wait(const char *const *argv, const atf_fs_path_t *outfile,
+              const atf_fs_path_t *errfile, atf_process_status_t *status)
+{
+    atf_error_t err;
+    atf_process_child_t child;
+    atf_process_stream_t outsb, errsb;
+    struct exec_data ea = { argv };
+
+    err = init_sbs(outfile, &outsb, errfile, &errsb);
+    if (atf_is_error(err))
+        goto out;
+
+    err = atf_process_fork(&child, exec_child, &outsb, &errsb, &ea);
+    if (atf_is_error(err))
+        goto out_sbs;
+
+    err = atf_process_child_wait(&child, status);
+
+out_sbs:
+    atf_process_stream_fini(&errsb);
+    atf_process_stream_fini(&outsb);
+out:
+    return err;
+}
+
+static
+void
+update_success_from_status(const char *progname,
+                           const atf_process_status_t *status, bool *success)
+{
+    bool s = atf_process_status_exited(status) &&
+             atf_process_status_exitstatus(status) == EXIT_SUCCESS;
+
+    if (atf_process_status_exited(status)) {
+        if (atf_process_status_exitstatus(status) == EXIT_SUCCESS)
+            INV(s);
+        else {
+            INV(!s);
+            fprintf(stderr, "%s failed with exit code %d\n", progname,
+                    atf_process_status_exitstatus(status));
+        }
+    } else if (atf_process_status_signaled(status)) {
+        INV(!s);
+        fprintf(stderr, "%s failed due to signal %d%s\n", progname,
+                atf_process_status_termsig(status),
+                atf_process_status_coredump(status) ? " (core dumped)" : "");
+    } else {
+        INV(!s);
+        fprintf(stderr, "%s failed due to unknown reason\n", progname);
+    }
+
+    *success = s;
+}
+
+static
+atf_error_t
+array_to_list(const char *const *a, atf_list_t *l)
+{
+    atf_error_t err;
+
+    err = atf_list_init(l);
+    if (atf_is_error(err))
+        goto out;
+
+    while (*a != NULL) {
+        char *item = strdup(*a);
+        if (item == NULL) {
+            err = atf_no_memory_error();
+            goto out;
+        }
+
+        err = atf_list_append(l, item, true);
+        if (atf_is_error(err))
+            goto out;
+
+        a++;
+    }
+
+out:
+    return err;
+}
+
+static void
+print_array(const char *const *array, const char *pfx)
+{
+    const char *const *ptr;
+
+    printf("%s", pfx);
+    for (ptr = array; *ptr != NULL; ptr++)
+        printf(" %s", *ptr);
+    printf("\n");
+}
+
+static
+atf_error_t
+check_build_run(const char *const *argv, bool *success)
+{
+    atf_error_t err;
+    atf_process_status_t status;
+
+    print_array(argv, ">");
+
+    err = fork_and_wait(argv, NULL, NULL, &status);
+    if (atf_is_error(err))
+        goto out;
+
+    update_success_from_status(argv[0], &status, success);
+    atf_process_status_fini(&status);
+
+    INV(!atf_is_error(err));
+out:
+    return err;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_check_result" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_check_result_impl {
+    atf_list_t m_argv;
+    atf_fs_path_t m_dir;
+    atf_fs_path_t m_stdout;
+    atf_fs_path_t m_stderr;
+    atf_process_status_t m_status;
+};
+
+static
+atf_error_t
+atf_check_result_init(atf_check_result_t *r, const char *const *argv,
+                      const atf_fs_path_t *dir)
+{
+    atf_error_t err;
+
+    r->pimpl = malloc(sizeof(struct atf_check_result_impl));
+    if (r->pimpl == NULL)
+        return atf_no_memory_error();
+
+    err = array_to_list(argv, &r->pimpl->m_argv);
+    if (atf_is_error(err))
+        goto out;
+
+    err = atf_fs_path_copy(&r->pimpl->m_dir, dir);
+    if (atf_is_error(err))
+        goto err_argv;
+
+    err = atf_fs_path_init_fmt(&r->pimpl->m_stdout, "%s/stdout",
+                               atf_fs_path_cstring(dir));
+    if (atf_is_error(err))
+        goto err_dir;
+
+    err = atf_fs_path_init_fmt(&r->pimpl->m_stderr, "%s/stderr",
+                               atf_fs_path_cstring(dir));
+    if (atf_is_error(err))
+        goto err_stdout;
+
+    INV(!atf_is_error(err));
+    goto out;
+
+err_stdout:
+    atf_fs_path_fini(&r->pimpl->m_stdout);
+err_dir:
+    atf_fs_path_fini(&r->pimpl->m_dir);
+err_argv:
+    atf_list_fini(&r->pimpl->m_argv);
+out:
+    return err;
+}
+
+void
+atf_check_result_fini(atf_check_result_t *r)
+{
+    atf_process_status_fini(&r->pimpl->m_status);
+
+    cleanup_tmpdir(&r->pimpl->m_dir, &r->pimpl->m_stdout,
+                   &r->pimpl->m_stderr);
+    atf_fs_path_fini(&r->pimpl->m_stdout);
+    atf_fs_path_fini(&r->pimpl->m_stderr);
+    atf_fs_path_fini(&r->pimpl->m_dir);
+
+    atf_list_fini(&r->pimpl->m_argv);
+
+    free(r->pimpl);
+}
+
+const char *
+atf_check_result_stdout(const atf_check_result_t *r)
+{
+    return atf_fs_path_cstring(&r->pimpl->m_stdout);
+}
+
+const char *
+atf_check_result_stderr(const atf_check_result_t *r)
+{
+    return atf_fs_path_cstring(&r->pimpl->m_stderr);
+}
+
+bool
+atf_check_result_exited(const atf_check_result_t *r)
+{
+    return atf_process_status_exited(&r->pimpl->m_status);
+}
+
+int
+atf_check_result_exitcode(const atf_check_result_t *r)
+{
+    return atf_process_status_exitstatus(&r->pimpl->m_status);
+}
+
+bool
+atf_check_result_signaled(const atf_check_result_t *r)
+{
+    return atf_process_status_signaled(&r->pimpl->m_status);
+}
+
+int
+atf_check_result_termsig(const atf_check_result_t *r)
+{
+    return atf_process_status_termsig(&r->pimpl->m_status);
+}
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+/* XXX: This function shouldn't be in this module.  It messes with stdout
+ * and stderr, and it provides a very high-end interface.  This belongs,
+ * probably, somewhere related to test cases (such as in the tc module). */
+atf_error_t
+atf_check_build_c_o(const char *sfile,
+                    const char *ofile,
+                    const char *const optargs[],
+                    bool *success)
+{
+    atf_error_t err;
+    char **argv;
+
+    err = atf_build_c_o(sfile, ofile, optargs, &argv);
+    if (atf_is_error(err))
+        goto out;
+
+    err = check_build_run((const char *const *)argv, success);
+
+    atf_utils_free_charpp(argv);
+out:
+    return err;
+}
+
+atf_error_t
+atf_check_build_cpp(const char *sfile,
+                    const char *ofile,
+                    const char *const optargs[],
+                    bool *success)
+{
+    atf_error_t err;
+    char **argv;
+
+    err = atf_build_cpp(sfile, ofile, optargs, &argv);
+    if (atf_is_error(err))
+        goto out;
+
+    err = check_build_run((const char *const *)argv, success);
+
+    atf_utils_free_charpp(argv);
+out:
+    return err;
+}
+
+atf_error_t
+atf_check_build_cxx_o(const char *sfile,
+                      const char *ofile,
+                      const char *const optargs[],
+                      bool *success)
+{
+    atf_error_t err;
+    char **argv;
+
+    err = atf_build_cxx_o(sfile, ofile, optargs, &argv);
+    if (atf_is_error(err))
+        goto out;
+
+    err = check_build_run((const char *const *)argv, success);
+
+    atf_utils_free_charpp(argv);
+out:
+    return err;
+}
+
+atf_error_t
+atf_check_exec_array(const char *const *argv, atf_check_result_t *r)
+{
+    atf_error_t err;
+    atf_fs_path_t dir;
+
+    err = create_tmpdir(&dir);
+    if (atf_is_error(err))
+        goto out;
+
+    err = atf_check_result_init(r, argv, &dir);
+    if (atf_is_error(err)) {
+        atf_error_t err2 = atf_fs_rmdir(&dir);
+        INV(!atf_is_error(err2));
+        goto out;
+    }
+
+    err = fork_and_wait(argv, &r->pimpl->m_stdout, &r->pimpl->m_stderr,
+                        &r->pimpl->m_status);
+    if (atf_is_error(err)) {
+        atf_check_result_fini(r);
+        goto out;
+    }
+
+    INV(!atf_is_error(err));
+
+    atf_fs_path_fini(&dir);
+out:
+    return err;
+}

Added: vendor/atf/dist/atf-c/check.h
===================================================================
--- vendor/atf/dist/atf-c/check.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/check.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,69 @@
+/* Copyright (c) 2008 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_C_CHECK_H)
+#define ATF_C_CHECK_H
+
+#include <stdbool.h>
+
+#include <atf-c/error_fwd.h>
+
+/* ---------------------------------------------------------------------
+ * The "atf_check_result" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_check_result_impl;
+struct atf_check_result {
+    struct atf_check_result_impl *pimpl;
+};
+typedef struct atf_check_result atf_check_result_t;
+
+/* Construtors and destructors */
+void atf_check_result_fini(atf_check_result_t *);
+
+/* Getters */
+const char *atf_check_result_stdout(const atf_check_result_t *);
+const char *atf_check_result_stderr(const atf_check_result_t *);
+bool atf_check_result_exited(const atf_check_result_t *);
+int atf_check_result_exitcode(const atf_check_result_t *);
+bool atf_check_result_signaled(const atf_check_result_t *);
+int atf_check_result_termsig(const atf_check_result_t *);
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+atf_error_t atf_check_build_c_o(const char *, const char *,
+                                const char *const [],
+                                bool *);
+atf_error_t atf_check_build_cpp(const char *, const char *,
+                                const char *const [],
+                                bool *);
+atf_error_t atf_check_build_cxx_o(const char *, const char *,
+                                  const char *const [],
+                                  bool *);
+atf_error_t atf_check_exec_array(const char *const *, atf_check_result_t *);
+
+#endif /* !defined(ATF_C_CHECK_H) */

Added: vendor/atf/dist/atf-c/check_test.c
===================================================================
--- vendor/atf/dist/atf-c/check_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/check_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,521 @@
+/* Copyright (c) 2008 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/check.h"
+
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/fs.h"
+#include "atf-c/detail/map.h"
+#include "atf-c/detail/process.h"
+#include "atf-c/detail/test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+do_exec(const atf_tc_t *tc, const char *helper_name, atf_check_result_t *r)
+{
+    atf_fs_path_t process_helpers;
+    const char *argv[3];
+
+    get_process_helpers_path(tc, false, &process_helpers);
+
+    argv[0] = atf_fs_path_cstring(&process_helpers);
+    argv[1] = helper_name;
+    argv[2] = NULL;
+    printf("Executing %s %s\n", argv[0], argv[1]);
+    RE(atf_check_exec_array(argv, r));
+
+    atf_fs_path_fini(&process_helpers);
+}
+
+static
+void
+do_exec_with_arg(const atf_tc_t *tc, const char *helper_name, const char *arg,
+                 atf_check_result_t *r)
+{
+    atf_fs_path_t process_helpers;
+    const char *argv[4];
+
+    get_process_helpers_path(tc, false, &process_helpers);
+
+    argv[0] = atf_fs_path_cstring(&process_helpers);
+    argv[1] = helper_name;
+    argv[2] = arg;
+    argv[3] = NULL;
+    printf("Executing %s %s %s\n", argv[0], argv[1], argv[2]);
+    RE(atf_check_exec_array(argv, r));
+
+    atf_fs_path_fini(&process_helpers);
+}
+
+static
+void
+check_line(int fd, const char *exp)
+{
+    char *line = atf_utils_readline(fd);
+    ATF_CHECK(line != NULL);
+    ATF_CHECK_STREQ_MSG(exp, line, "read: '%s', expected: '%s'", line, exp);
+    free(line);
+}
+
+/* ---------------------------------------------------------------------
+ * Helper test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(h_build_c_o_ok);
+ATF_TC_HEAD(h_build_c_o_ok, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
+}
+ATF_TC_BODY(h_build_c_o_ok, tc)
+{
+    FILE *sfile;
+    bool success;
+
+    ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
+    fprintf(sfile, "#include <stdio.h>\n");
+    fclose(sfile);
+
+    RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
+    ATF_REQUIRE(success);
+}
+
+ATF_TC(h_build_c_o_fail);
+ATF_TC_HEAD(h_build_c_o_fail, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for build_c_o");
+}
+ATF_TC_BODY(h_build_c_o_fail, tc)
+{
+    FILE *sfile;
+    bool success;
+
+    ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
+    fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
+    fclose(sfile);
+
+    RE(atf_check_build_c_o("test.c", "test.o", NULL, &success));
+    ATF_REQUIRE(!success);
+}
+
+ATF_TC(h_build_cpp_ok);
+ATF_TC_HEAD(h_build_cpp_ok, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
+}
+ATF_TC_BODY(h_build_cpp_ok, tc)
+{
+    FILE *sfile;
+    bool success;
+    atf_fs_path_t test_p;
+
+    RE(atf_fs_path_init_fmt(&test_p, "test.p"));
+
+    ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
+    fprintf(sfile, "#define A foo\n");
+    fprintf(sfile, "#define B bar\n");
+    fprintf(sfile, "A B\n");
+    fclose(sfile);
+
+    RE(atf_check_build_cpp("test.c", atf_fs_path_cstring(&test_p), NULL,
+                           &success));
+    ATF_REQUIRE(success);
+
+    atf_fs_path_fini(&test_p);
+}
+
+ATF_TC(h_build_cpp_fail);
+ATF_TC_HEAD(h_build_cpp_fail, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for build_cpp");
+}
+ATF_TC_BODY(h_build_cpp_fail, tc)
+{
+    FILE *sfile;
+    bool success;
+
+    ATF_REQUIRE((sfile = fopen("test.c", "w")) != NULL);
+    fprintf(sfile, "#include \"./non-existent.h\"\n");
+    fclose(sfile);
+
+    RE(atf_check_build_cpp("test.c", "test.p", NULL, &success));
+    ATF_REQUIRE(!success);
+}
+
+ATF_TC(h_build_cxx_o_ok);
+ATF_TC_HEAD(h_build_cxx_o_ok, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
+}
+ATF_TC_BODY(h_build_cxx_o_ok, tc)
+{
+    FILE *sfile;
+    bool success;
+
+    ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
+    fprintf(sfile, "#include <iostream>\n");
+    fclose(sfile);
+
+    RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
+    ATF_REQUIRE(success);
+}
+
+ATF_TC(h_build_cxx_o_fail);
+ATF_TC_HEAD(h_build_cxx_o_fail, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for build_cxx_o");
+}
+ATF_TC_BODY(h_build_cxx_o_fail, tc)
+{
+    FILE *sfile;
+    bool success;
+
+    ATF_REQUIRE((sfile = fopen("test.cpp", "w")) != NULL);
+    fprintf(sfile, "void foo(void) { int a = UNDEFINED_SYMBOL; }\n");
+    fclose(sfile);
+
+    RE(atf_check_build_cxx_o("test.cpp", "test.o", NULL, &success));
+    ATF_REQUIRE(!success);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+init_and_run_h_tc(atf_tc_t *tc, const atf_tc_pack_t *tcpack,
+                  const char *outname, const char *errname)
+{
+    const char *const config[] = { NULL };
+
+    RE(atf_tc_init_pack(tc, tcpack, config));
+    run_h_tc(tc, outname, errname, "result");
+    atf_tc_fini(tc);
+}
+
+ATF_TC(build_c_o);
+ATF_TC_HEAD(build_c_o, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_c_o "
+                      "function");
+}
+ATF_TC_BODY(build_c_o, tc)
+{
+    init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_ok),
+             &ATF_TC_PACK_NAME(h_build_c_o_ok), "stdout", "stderr");
+    ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
+    ATF_CHECK(atf_utils_grep_file("-c test.c", "stdout"));
+
+    init_and_run_h_tc(&ATF_TC_NAME(h_build_c_o_fail),
+             &ATF_TC_PACK_NAME(h_build_c_o_fail), "stdout", "stderr");
+    ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
+    ATF_CHECK(atf_utils_grep_file("-c test.c", "stdout"));
+    ATF_CHECK(atf_utils_grep_file("test.c", "stderr"));
+    ATF_CHECK(atf_utils_grep_file("UNDEFINED_SYMBOL", "stderr"));
+}
+
+ATF_TC(build_cpp);
+ATF_TC_HEAD(build_cpp, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cpp "
+                      "function");
+}
+ATF_TC_BODY(build_cpp, tc)
+{
+    init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_ok),
+             &ATF_TC_PACK_NAME(h_build_cpp_ok), "stdout", "stderr");
+    ATF_CHECK(atf_utils_grep_file("-o.*test.p", "stdout"));
+    ATF_CHECK(atf_utils_grep_file("test.c", "stdout"));
+    ATF_CHECK(atf_utils_grep_file("foo bar", "test.p"));
+
+    init_and_run_h_tc(&ATF_TC_NAME(h_build_cpp_fail),
+             &ATF_TC_PACK_NAME(h_build_cpp_fail), "stdout", "stderr");
+    ATF_CHECK(atf_utils_grep_file("-o test.p", "stdout"));
+    ATF_CHECK(atf_utils_grep_file("test.c", "stdout"));
+    ATF_CHECK(atf_utils_grep_file("test.c", "stderr"));
+    ATF_CHECK(atf_utils_grep_file("non-existent.h", "stderr"));
+}
+
+ATF_TC(build_cxx_o);
+ATF_TC_HEAD(build_cxx_o, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_check_build_cxx_o "
+                      "function");
+}
+ATF_TC_BODY(build_cxx_o, tc)
+{
+    init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_ok),
+             &ATF_TC_PACK_NAME(h_build_cxx_o_ok), "stdout", "stderr");
+    ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
+    ATF_CHECK(atf_utils_grep_file("-c test.cpp", "stdout"));
+
+    init_and_run_h_tc(&ATF_TC_NAME(h_build_cxx_o_fail),
+             &ATF_TC_PACK_NAME(h_build_cxx_o_fail), "stdout", "stderr");
+    ATF_CHECK(atf_utils_grep_file("-o test.o", "stdout"));
+    ATF_CHECK(atf_utils_grep_file("-c test.cpp", "stdout"));
+    ATF_CHECK(atf_utils_grep_file("test.cpp", "stderr"));
+    ATF_CHECK(atf_utils_grep_file("UNDEFINED_SYMBOL", "stderr"));
+}
+
+ATF_TC(exec_array);
+ATF_TC_HEAD(exec_array, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
+                      "works properly");
+}
+ATF_TC_BODY(exec_array, tc)
+{
+    atf_fs_path_t process_helpers;
+    atf_check_result_t result;
+
+    get_process_helpers_path(tc, false, &process_helpers);
+
+    const char *argv[4];
+    argv[0] = atf_fs_path_cstring(&process_helpers);
+    argv[1] = "echo";
+    argv[2] = "test-message";
+    argv[3] = NULL;
+
+    RE(atf_check_exec_array(argv, &result));
+
+    ATF_CHECK(atf_check_result_exited(&result));
+    ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
+
+    {
+        const char *path = atf_check_result_stdout(&result);
+        int fd = open(path, O_RDONLY);
+        ATF_CHECK(fd != -1);
+        check_line(fd, "test-message");
+        close(fd);
+    }
+
+    atf_check_result_fini(&result);
+    atf_fs_path_fini(&process_helpers);
+}
+
+ATF_TC(exec_cleanup);
+ATF_TC_HEAD(exec_cleanup, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
+                      "properly cleans up the temporary files it creates");
+}
+ATF_TC_BODY(exec_cleanup, tc)
+{
+    atf_fs_path_t out, err;
+    atf_check_result_t result;
+    bool exists;
+
+    do_exec(tc, "exit-success", &result);
+    RE(atf_fs_path_init_fmt(&out, "%s", atf_check_result_stdout(&result)));
+    RE(atf_fs_path_init_fmt(&err, "%s", atf_check_result_stderr(&result)));
+
+    RE(atf_fs_exists(&out, &exists)); ATF_CHECK(exists);
+    RE(atf_fs_exists(&err, &exists)); ATF_CHECK(exists);
+    atf_check_result_fini(&result);
+    RE(atf_fs_exists(&out, &exists)); ATF_CHECK(!exists);
+    RE(atf_fs_exists(&err, &exists)); ATF_CHECK(!exists);
+
+    atf_fs_path_fini(&err);
+    atf_fs_path_fini(&out);
+}
+
+ATF_TC(exec_exitstatus);
+ATF_TC_HEAD(exec_exitstatus, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
+                      "properly captures the exit status of the executed "
+                      "command");
+}
+ATF_TC_BODY(exec_exitstatus, tc)
+{
+    {
+        atf_check_result_t result;
+        do_exec(tc, "exit-success", &result);
+        ATF_CHECK(atf_check_result_exited(&result));
+        ATF_CHECK(!atf_check_result_signaled(&result));
+        ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_SUCCESS);
+        atf_check_result_fini(&result);
+    }
+
+    {
+        atf_check_result_t result;
+        do_exec(tc, "exit-failure", &result);
+        ATF_CHECK(atf_check_result_exited(&result));
+        ATF_CHECK(!atf_check_result_signaled(&result));
+        ATF_CHECK(atf_check_result_exitcode(&result) == EXIT_FAILURE);
+        atf_check_result_fini(&result);
+    }
+
+    {
+        atf_check_result_t result;
+        do_exec(tc, "exit-signal", &result);
+        ATF_CHECK(!atf_check_result_exited(&result));
+        ATF_CHECK(atf_check_result_signaled(&result));
+        ATF_CHECK(atf_check_result_termsig(&result) == SIGKILL);
+        atf_check_result_fini(&result);
+    }
+}
+
+ATF_TC(exec_stdout_stderr);
+ATF_TC_HEAD(exec_stdout_stderr, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
+                      "properly captures the stdout and stderr streams "
+                      "of the child process");
+}
+ATF_TC_BODY(exec_stdout_stderr, tc)
+{
+    atf_check_result_t result1, result2;
+    const char *out1, *out2;
+    const char *err1, *err2;
+
+    do_exec_with_arg(tc, "stdout-stderr", "result1", &result1);
+    ATF_CHECK(atf_check_result_exited(&result1));
+    ATF_CHECK(atf_check_result_exitcode(&result1) == EXIT_SUCCESS);
+
+    do_exec_with_arg(tc, "stdout-stderr", "result2", &result2);
+    ATF_CHECK(atf_check_result_exited(&result2));
+    ATF_CHECK(atf_check_result_exitcode(&result2) == EXIT_SUCCESS);
+
+    out1 = atf_check_result_stdout(&result1);
+    out2 = atf_check_result_stdout(&result2);
+    err1 = atf_check_result_stderr(&result1);
+    err2 = atf_check_result_stderr(&result2);
+
+    ATF_CHECK(strstr(out1, "check.XXXXXX") == NULL);
+    ATF_CHECK(strstr(out2, "check.XXXXXX") == NULL);
+    ATF_CHECK(strstr(err1, "check.XXXXXX") == NULL);
+    ATF_CHECK(strstr(err2, "check.XXXXXX") == NULL);
+
+    ATF_CHECK(strstr(out1, "/check") != NULL);
+    ATF_CHECK(strstr(out2, "/check") != NULL);
+    ATF_CHECK(strstr(err1, "/check") != NULL);
+    ATF_CHECK(strstr(err2, "/check") != NULL);
+
+    ATF_CHECK(strstr(out1, "/stdout") != NULL);
+    ATF_CHECK(strstr(out2, "/stdout") != NULL);
+    ATF_CHECK(strstr(err1, "/stderr") != NULL);
+    ATF_CHECK(strstr(err2, "/stderr") != NULL);
+
+    ATF_CHECK(strcmp(out1, out2) != 0);
+    ATF_CHECK(strcmp(err1, err2) != 0);
+
+#define CHECK_LINES(path, outname, resname) \
+    do { \
+        int fd = open(path, O_RDONLY); \
+        ATF_CHECK(fd != -1); \
+        check_line(fd, "Line 1 to " outname " for " resname); \
+        check_line(fd, "Line 2 to " outname " for " resname); \
+        close(fd); \
+    } while (false)
+
+    CHECK_LINES(out1, "stdout", "result1");
+    CHECK_LINES(out2, "stdout", "result2");
+    CHECK_LINES(err1, "stderr", "result1");
+    CHECK_LINES(err2, "stderr", "result2");
+
+#undef CHECK_LINES
+
+    atf_check_result_fini(&result2);
+    atf_check_result_fini(&result1);
+}
+
+ATF_TC(exec_umask);
+ATF_TC_HEAD(exec_umask, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that atf_check_exec_array "
+                      "correctly reports an error if the umask is too "
+                      "restrictive to create temporary files");
+}
+ATF_TC_BODY(exec_umask, tc)
+{
+    atf_check_result_t result;
+    atf_fs_path_t process_helpers;
+    const char *argv[3];
+
+    get_process_helpers_path(tc, false, &process_helpers);
+    argv[0] = atf_fs_path_cstring(&process_helpers);
+    argv[1] = "exit-success";
+    argv[2] = NULL;
+
+    umask(0222);
+    atf_error_t err = atf_check_exec_array(argv, &result);
+    ATF_CHECK(atf_is_error(err));
+    ATF_CHECK(atf_error_is(err, "invalid_umask"));
+    atf_error_free(err);
+
+    atf_fs_path_fini(&process_helpers);
+}
+
+ATF_TC(exec_unknown);
+ATF_TC_HEAD(exec_unknown, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that running a non-existing "
+                      "binary is handled correctly");
+}
+ATF_TC_BODY(exec_unknown, tc)
+{
+    const char *argv[2];
+    argv[0] = "/foo/bar/non-existent";
+    argv[1] = NULL;
+
+    atf_check_result_t result;
+    RE(atf_check_exec_array(argv, &result));
+    ATF_CHECK(atf_check_result_exited(&result));
+    ATF_CHECK(atf_check_result_exitcode(&result) == 127);
+    atf_check_result_fini(&result);
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    /* Add the test cases for the free functions. */
+    ATF_TP_ADD_TC(tp, build_c_o);
+    ATF_TP_ADD_TC(tp, build_cpp);
+    ATF_TP_ADD_TC(tp, build_cxx_o);
+    ATF_TP_ADD_TC(tp, exec_array);
+    ATF_TP_ADD_TC(tp, exec_cleanup);
+    ATF_TP_ADD_TC(tp, exec_exitstatus);
+    ATF_TP_ADD_TC(tp, exec_stdout_stderr);
+    ATF_TP_ADD_TC(tp, exec_umask);
+    ATF_TP_ADD_TC(tp, exec_unknown);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/defs.h
===================================================================
--- vendor/atf/dist/atf-c/defs.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/defs.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,37 @@
+/*
+ * Automated Testing Framework (atf)
+ *
+ * Copyright (c) 2008 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_C_DEFS_H)
+#define ATF_C_DEFS_H
+
+#define ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(a, b) __attribute__((__format__(__printf__, a, b)))
+#define ATF_DEFS_ATTRIBUTE_NORETURN __attribute__((__noreturn__))
+#define ATF_DEFS_ATTRIBUTE_UNUSED __attribute__((__unused__))
+
+#endif /* !defined(ATF_C_DEFS_H) */

Added: vendor/atf/dist/atf-c/defs.h.in
===================================================================
--- vendor/atf/dist/atf-c/defs.h.in	                        (rev 0)
+++ vendor/atf/dist/atf-c/defs.h.in	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,33 @@
+/* Copyright (c) 2008 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_C_DEFS_H)
+#define ATF_C_DEFS_H
+
+#define ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(a, b) @ATTRIBUTE_FORMAT_PRINTF@
+#define ATF_DEFS_ATTRIBUTE_NORETURN @ATTRIBUTE_NORETURN@
+#define ATF_DEFS_ATTRIBUTE_UNUSED @ATTRIBUTE_UNUSED@
+
+#endif /* !defined(ATF_C_DEFS_H) */

Added: vendor/atf/dist/atf-c/detail/Kyuafile
===================================================================
--- vendor/atf/dist/atf-c/detail/Kyuafile	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/Kyuafile	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,13 @@
+syntax("kyuafile", 1)
+
+test_suite("atf")
+
+atf_test_program{name="dynstr_test"}
+atf_test_program{name="env_test"}
+atf_test_program{name="fs_test"}
+atf_test_program{name="list_test"}
+atf_test_program{name="map_test"}
+atf_test_program{name="process_test"}
+atf_test_program{name="sanity_test"}
+atf_test_program{name="text_test"}
+atf_test_program{name="user_test"}

Added: vendor/atf/dist/atf-c/detail/dynstr.c
===================================================================
--- vendor/atf/dist/atf-c/detail/dynstr.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/dynstr.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,394 @@
+/* Copyright (c) 2008 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/dynstr.h"
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "atf-c/detail/sanity.h"
+#include "atf-c/detail/text.h"
+#include "atf-c/error.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+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();
+    }
+
+    return err;
+}
+
+static
+atf_error_t
+prepend_or_append(atf_dynstr_t *ad, const char *fmt, va_list ap,
+                  bool prepend)
+{
+    char *aux;
+    atf_error_t err;
+    size_t newlen;
+    va_list ap2;
+
+    va_copy(ap2, ap);
+    err = atf_text_format_ap(&aux, fmt, ap2);
+    va_end(ap2);
+    if (atf_is_error(err))
+        goto out;
+    newlen = ad->m_length + strlen(aux);
+
+    if (newlen + sizeof(char) > ad->m_datasize) {
+        err = resize(ad, newlen + sizeof(char));
+        if (atf_is_error(err))
+            goto out_free;
+    }
+
+    if (prepend) {
+        memmove(ad->m_data + strlen(aux), ad->m_data, ad->m_length + 1);
+        memcpy(ad->m_data, aux, strlen(aux));
+    } else
+        strcpy(ad->m_data + ad->m_length, aux);
+    ad->m_length = newlen;
+    err = atf_no_error();
+
+out_free:
+    free(aux);
+out:
+    return err;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_dynstr" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constants.
+ */
+
+const size_t atf_dynstr_npos = SIZE_MAX;
+
+/*
+ * Constructors and destructors.
+ */
+
+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[0] = '\0';
+    ad->m_datasize = 1;
+    ad->m_length = 0;
+    err = atf_no_error();
+
+out:
+    return err;
+}
+
+atf_error_t
+atf_dynstr_init_ap(atf_dynstr_t *ad, const char *fmt, va_list ap)
+{
+    atf_error_t err;
+
+    ad->m_datasize = strlen(fmt) + 1;
+    ad->m_length = 0;
+
+    do {
+        va_list ap2;
+        int ret;
+
+        ad->m_datasize *= 2;
+        ad->m_data = (char *)malloc(ad->m_datasize);
+        if (ad->m_data == NULL) {
+            err = atf_no_memory_error();
+            goto out;
+        }
+
+        va_copy(ap2, ap);
+        ret = vsnprintf(ad->m_data, ad->m_datasize, fmt, ap2);
+        va_end(ap2);
+        if (ret < 0) {
+            free(ad->m_data);
+            err = atf_libc_error(errno, "Cannot format string");
+            goto out;
+        }
+
+        INV(ret >= 0);
+        if ((size_t)ret >= ad->m_datasize) {
+            free(ad->m_data);
+            ad->m_data = NULL;
+        }
+        ad->m_length = ret;
+    } while (ad->m_length >= ad->m_datasize);
+
+    err = atf_no_error();
+out:
+    POST(atf_is_error(err) || ad->m_data != NULL);
+    return err;
+}
+
+atf_error_t
+atf_dynstr_init_fmt(atf_dynstr_t *ad, const char *fmt, ...)
+{
+    va_list ap;
+    atf_error_t err;
+
+    va_start(ap, fmt);
+    err = atf_dynstr_init_ap(ad, fmt, ap);
+    va_end(ap);
+
+    return err;
+}
+
+atf_error_t
+atf_dynstr_init_raw(atf_dynstr_t *ad, const void *mem, size_t memlen)
+{
+    atf_error_t err;
+
+    if (memlen >= SIZE_MAX - 1) {
+        err = atf_no_memory_error();
+        goto out;
+    }
+
+    ad->m_data = (char *)malloc(memlen + 1);
+    if (ad->m_data == NULL) {
+        err = atf_no_memory_error();
+        goto out;
+    }
+
+    ad->m_datasize = memlen + 1;
+    memcpy(ad->m_data, mem, memlen);
+    ad->m_data[memlen] = '\0';
+    ad->m_length = strlen(ad->m_data);
+    INV(ad->m_length <= memlen);
+    err = atf_no_error();
+
+out:
+    return err;
+}
+
+atf_error_t
+atf_dynstr_init_rep(atf_dynstr_t *ad, size_t len, char ch)
+{
+    atf_error_t err;
+
+    if (len == SIZE_MAX) {
+        err = atf_no_memory_error();
+        goto out;
+    }
+
+    ad->m_datasize = (len + 1) * sizeof(char);
+    ad->m_data = (char *)malloc(ad->m_datasize);
+    if (ad->m_data == NULL) {
+        err = atf_no_memory_error();
+        goto out;
+    }
+
+    memset(ad->m_data, ch, len);
+    ad->m_data[len] = '\0';
+    ad->m_length = len;
+    err = atf_no_error();
+
+out:
+    return err;
+}
+
+atf_error_t
+atf_dynstr_init_substr(atf_dynstr_t *ad, const atf_dynstr_t *src,
+                       size_t beg, size_t end)
+{
+    if (beg > src->m_length)
+        beg = src->m_length;
+
+    if (end == atf_dynstr_npos || end > src->m_length)
+        end = src->m_length;
+
+    return atf_dynstr_init_raw(ad, src->m_data + beg, end - beg);
+}
+
+atf_error_t
+atf_dynstr_copy(atf_dynstr_t *dest, const atf_dynstr_t *src)
+{
+    atf_error_t err;
+
+    dest->m_data = (char *)malloc(src->m_datasize);
+    if (dest->m_data == NULL)
+        err = atf_no_memory_error();
+    else {
+        memcpy(dest->m_data, src->m_data, src->m_datasize);
+        dest->m_datasize = src->m_datasize;
+        dest->m_length = src->m_length;
+        err = atf_no_error();
+    }
+
+    return err;
+}
+
+void
+atf_dynstr_fini(atf_dynstr_t *ad)
+{
+    INV(ad->m_data != NULL);
+    free(ad->m_data);
+}
+
+char *
+atf_dynstr_fini_disown(atf_dynstr_t *ad)
+{
+    INV(ad->m_data != NULL);
+    return ad->m_data;
+}
+
+/*
+ * Getters.
+ */
+
+const char *
+atf_dynstr_cstring(const atf_dynstr_t *ad)
+{
+    return ad->m_data;
+}
+
+size_t
+atf_dynstr_length(const atf_dynstr_t *ad)
+{
+    return ad->m_length;
+}
+
+size_t
+atf_dynstr_rfind_ch(const atf_dynstr_t *ad, char ch)
+{
+    size_t pos;
+
+    for (pos = ad->m_length; pos > 0 && ad->m_data[pos - 1] != ch; pos--)
+        ;
+
+    return pos == 0 ? atf_dynstr_npos : pos - 1;
+}
+
+/*
+ * Modifiers.
+ */
+
+atf_error_t
+atf_dynstr_append_ap(atf_dynstr_t *ad, const char *fmt, va_list ap)
+{
+    atf_error_t err;
+    va_list ap2;
+
+    va_copy(ap2, ap);
+    err = prepend_or_append(ad, fmt, ap2, false);
+    va_end(ap2);
+
+    return err;
+}
+
+atf_error_t
+atf_dynstr_append_fmt(atf_dynstr_t *ad, const char *fmt, ...)
+{
+    va_list ap;
+    atf_error_t err;
+
+    va_start(ap, fmt);
+    err = prepend_or_append(ad, fmt, ap, false);
+    va_end(ap);
+
+    return err;
+}
+
+void
+atf_dynstr_clear(atf_dynstr_t *ad)
+{
+    ad->m_data[0] = '\0';
+    ad->m_length = 0;
+}
+
+atf_error_t
+atf_dynstr_prepend_ap(atf_dynstr_t *ad, const char *fmt, va_list ap)
+{
+    atf_error_t err;
+    va_list ap2;
+
+    va_copy(ap2, ap);
+    err = prepend_or_append(ad, fmt, ap2, true);
+    va_end(ap2);
+
+    return err;
+}
+
+atf_error_t
+atf_dynstr_prepend_fmt(atf_dynstr_t *ad, const char *fmt, ...)
+{
+    va_list ap;
+    atf_error_t err;
+
+    va_start(ap, fmt);
+    err = prepend_or_append(ad, fmt, ap, true);
+    va_end(ap);
+
+    return err;
+}
+
+/*
+ * Operators.
+ */
+
+bool
+atf_equal_dynstr_cstring(const atf_dynstr_t *ad, const char *str)
+{
+    return strcmp(ad->m_data, str) == 0;
+}
+
+bool
+atf_equal_dynstr_dynstr(const atf_dynstr_t *s1, const atf_dynstr_t *s2)
+{
+    return strcmp(s1->m_data, s2->m_data) == 0;
+}

Added: vendor/atf/dist/atf-c/detail/dynstr.h
===================================================================
--- vendor/atf/dist/atf-c/detail/dynstr.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/dynstr.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,77 @@
+/* Copyright (c) 2008 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_C_DETAIL_DYNSTR_H)
+#define ATF_C_DETAIL_DYNSTR_H
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#include <atf-c/error_fwd.h>
+
+/* ---------------------------------------------------------------------
+ * The "atf_dynstr" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_dynstr {
+    char *m_data;
+    size_t m_datasize;
+    size_t m_length;
+};
+typedef struct atf_dynstr atf_dynstr_t;
+
+/* Constants */
+extern const size_t atf_dynstr_npos;
+
+/* Constructors and destructors */
+atf_error_t atf_dynstr_init(atf_dynstr_t *);
+atf_error_t atf_dynstr_init_ap(atf_dynstr_t *, const char *, va_list);
+atf_error_t atf_dynstr_init_fmt(atf_dynstr_t *, const char *, ...);
+atf_error_t atf_dynstr_init_raw(atf_dynstr_t *, const void *, size_t);
+atf_error_t atf_dynstr_init_rep(atf_dynstr_t *, size_t, char);
+atf_error_t atf_dynstr_init_substr(atf_dynstr_t *, const atf_dynstr_t *,
+                                   size_t, size_t);
+atf_error_t atf_dynstr_copy(atf_dynstr_t *, const atf_dynstr_t *);
+void atf_dynstr_fini(atf_dynstr_t *);
+char *atf_dynstr_fini_disown(atf_dynstr_t *);
+
+/* Getters */
+const char *atf_dynstr_cstring(const atf_dynstr_t *);
+size_t atf_dynstr_length(const atf_dynstr_t *);
+size_t atf_dynstr_rfind_ch(const atf_dynstr_t *, char);
+
+/* Modifiers */
+atf_error_t atf_dynstr_append_ap(atf_dynstr_t *, const char *, va_list);
+atf_error_t atf_dynstr_append_fmt(atf_dynstr_t *, const char *, ...);
+void atf_dynstr_clear(atf_dynstr_t *);
+atf_error_t atf_dynstr_prepend_ap(atf_dynstr_t *, const char *, va_list);
+atf_error_t atf_dynstr_prepend_fmt(atf_dynstr_t *, const char *, ...);
+
+/* Operators */
+bool atf_equal_dynstr_cstring(const atf_dynstr_t *, const char *);
+bool atf_equal_dynstr_dynstr(const atf_dynstr_t *, const atf_dynstr_t *);
+
+#endif /* !defined(ATF_C_DETAIL_DYNSTR_H) */

Added: vendor/atf/dist/atf-c/detail/dynstr_test.c
===================================================================
--- vendor/atf/dist/atf-c/detail/dynstr_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/dynstr_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,634 @@
+/* Copyright (c) 2008 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/dynstr.h"
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Tests for the "atf_dynstr" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constructors and destructors.
+ */
+
+ATF_TC(init);
+ATF_TC_HEAD(init, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the empty constructor");
+}
+ATF_TC_BODY(init, tc)
+{
+    atf_dynstr_t str;
+
+    RE(atf_dynstr_init(&str));
+    ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0);
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+    atf_dynstr_fini(&str);
+}
+
+static
+void
+init_fmt(atf_dynstr_t *str, const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    RE(atf_dynstr_init_ap(str, fmt, ap));
+    va_end(ap);
+}
+
+ATF_TC(init_ap);
+ATF_TC_HEAD(init_ap, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the formatted constructor using "
+                      "a va_list argument");
+}
+ATF_TC_BODY(init_ap, tc)
+{
+    atf_dynstr_t str;
+
+    init_fmt(&str, "String 1");
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0);
+    atf_dynstr_fini(&str);
+
+    init_fmt(&str, "String %d", 2);
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0);
+    atf_dynstr_fini(&str);
+
+    init_fmt(&str, "%s %d", "String", 3);
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 3") == 0);
+    atf_dynstr_fini(&str);
+
+    init_fmt(&str, "%s%s%s%s%s%s%s", "This ", "should ", "be ", "a ",
+             "large ", "string ", "aaaabbbbccccdddd");
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str),
+                     "This should be a large string "
+                     "aaaabbbbccccdddd") == 0);
+    atf_dynstr_fini(&str);
+}
+
+ATF_TC(init_fmt);
+ATF_TC_HEAD(init_fmt, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the formatted constructor using "
+                      "a variable list of parameters");
+}
+ATF_TC_BODY(init_fmt, tc)
+{
+    atf_dynstr_t str;
+
+    RE(atf_dynstr_init_fmt(&str, "String 1"));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_fmt(&str, "String %d", 2));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_fmt(&str, "%s %d", "String", 3));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 3") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_fmt(&str, "%s%s%s%s%s%s%s", "This ", "should ",
+                           "be ", "a ", "large ", "string ",
+                           "aaaabbbbccccdddd"));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str),
+                     "This should be a large string "
+                     "aaaabbbbccccdddd") == 0);
+    atf_dynstr_fini(&str);
+}
+
+ATF_TC(init_raw);
+ATF_TC_HEAD(init_raw, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the construction of a string "
+                      "using a raw memory pointer");
+}
+ATF_TC_BODY(init_raw, tc)
+{
+    const char *src = "String 1, String 2";
+    atf_dynstr_t str;
+
+    RE(atf_dynstr_init_raw(&str, src, 0));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_raw(&str, src, 8));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_raw(&str, src + 10, 8));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_raw(&str, "String\0Lost", 11));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String") == 0);
+    atf_dynstr_fini(&str);
+
+    {
+        atf_error_t err = atf_dynstr_init_raw(&str, "NULL", SIZE_MAX - 1);
+        ATF_REQUIRE(atf_is_error(err));
+        ATF_REQUIRE(atf_error_is(err, "no_memory"));
+        atf_error_free(err);
+    }
+}
+
+ATF_TC(init_rep);
+ATF_TC_HEAD(init_rep, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the construction of a string by "
+                      "repeating characters");
+}
+ATF_TC_BODY(init_rep, tc)
+{
+    const size_t maxlen = 8192;
+    char buf[maxlen + 1];
+    size_t i;
+
+    buf[0] = '\0';
+
+    for (i = 0; i < maxlen; i++) {
+        atf_dynstr_t str;
+
+        RE(atf_dynstr_init_rep(&str, i, 'a'));
+
+        if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {
+            fprintf(stderr, "Failed at iteration %zd\n", i);
+            atf_tc_fail("Failed to construct dynstr by repeating %zd "
+                        "times the '%c' character", i, 'a');
+        }
+
+        atf_dynstr_fini(&str);
+
+        strcat(buf, "a");
+    }
+
+    {
+        atf_dynstr_t str;
+        atf_error_t err;
+
+        err = atf_dynstr_init_rep(&str, SIZE_MAX, 'a');
+        ATF_REQUIRE(atf_is_error(err));
+        ATF_REQUIRE(atf_error_is(err, "no_memory"));
+        atf_error_free(err);
+
+        err = atf_dynstr_init_rep(&str, SIZE_MAX - 1, 'a');
+        ATF_REQUIRE(atf_is_error(err));
+        ATF_REQUIRE(atf_error_is(err, "no_memory"));
+        atf_error_free(err);
+    }
+}
+
+ATF_TC(init_substr);
+ATF_TC_HEAD(init_substr, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the construction of a string "
+                      "using a substring of another one");
+}
+ATF_TC_BODY(init_substr, tc)
+{
+    atf_dynstr_t src;
+    atf_dynstr_t str;
+
+    RE(atf_dynstr_init_fmt(&src, "Str 1, Str 2"));
+
+    RE(atf_dynstr_init_substr(&str, &src, 0, 0));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_substr(&str, &src, 0, atf_dynstr_npos));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_substr(&str, &src, 0, 100));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_substr(&str, &src, 0, 5));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_substr(&str, &src, 100, atf_dynstr_npos));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_substr(&str, &src, 7, atf_dynstr_npos));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 2") == 0);
+    atf_dynstr_fini(&str);
+
+    atf_dynstr_fini(&src);
+}
+
+ATF_TC(copy);
+ATF_TC_HEAD(copy, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_dynstr_copy constructor");
+}
+ATF_TC_BODY(copy, tc)
+{
+    atf_dynstr_t str, str2;
+
+    RE(atf_dynstr_init_fmt(&str, "Test string"));
+    RE(atf_dynstr_copy(&str2, &str));
+
+    ATF_REQUIRE(atf_equal_dynstr_dynstr(&str, &str2));
+
+    RE(atf_dynstr_append_fmt(&str2, " non-shared text"));
+
+    ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2));
+
+    atf_dynstr_fini(&str2);
+    atf_dynstr_fini(&str);
+}
+
+ATF_TC(fini_disown);
+ATF_TC_HEAD(fini_disown, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks grabbing ownership of the "
+                      "internal plain C string");
+}
+ATF_TC_BODY(fini_disown, tc)
+{
+    const char *cstr;
+    char *cstr2;
+    atf_dynstr_t str;
+
+    RE(atf_dynstr_init_fmt(&str, "Test string 1"));
+    cstr = atf_dynstr_cstring(&str);
+    cstr2 = atf_dynstr_fini_disown(&str);
+
+    ATF_REQUIRE_EQ(cstr, cstr2);
+    free(cstr2);
+}
+
+/*
+ * Getters.
+ */
+
+ATF_TC(cstring);
+ATF_TC_HEAD(cstring, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the method to obtain a plain C "
+                      "string");
+}
+ATF_TC_BODY(cstring, tc)
+{
+    const char *cstr;
+    atf_dynstr_t str;
+
+    RE(atf_dynstr_init_fmt(&str, "Test string 1"));
+    cstr = atf_dynstr_cstring(&str);
+    ATF_REQUIRE(cstr != NULL);
+    ATF_REQUIRE(strcmp(cstr, "Test string 1") == 0);
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_fmt(&str, "Test string 2"));
+    cstr = atf_dynstr_cstring(&str);
+    ATF_REQUIRE(cstr != NULL);
+    ATF_REQUIRE(strcmp(cstr, "Test string 2") == 0);
+    atf_dynstr_fini(&str);
+}
+
+ATF_TC(length);
+ATF_TC_HEAD(length, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the method to obtain the length");
+}
+ATF_TC_BODY(length, tc)
+{
+    size_t i;
+
+    for (i = 0; i < 8192; i++) {
+        atf_dynstr_t str;
+        RE(atf_dynstr_init_rep(&str, i, 'a'));
+        ATF_REQUIRE_EQ(atf_dynstr_length(&str), i);
+        atf_dynstr_fini(&str);
+    }
+}
+
+ATF_TC(rfind_ch);
+ATF_TC_HEAD(rfind_ch, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the method to locate the first "
+                      "occurrence of a character starting from the end");
+}
+ATF_TC_BODY(rfind_ch, tc)
+{
+    atf_dynstr_t str;
+
+    RE(atf_dynstr_init_fmt(&str, "Foo1/Bar2/,.Baz"));
+
+    ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '\0'), atf_dynstr_npos);
+
+    ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '0'), atf_dynstr_npos);
+    ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'b'), atf_dynstr_npos);
+
+    ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'F'), 0);
+    ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '/'), 9);
+    ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'a'), 13);
+    ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'z'), 14);
+
+    atf_dynstr_fini(&str);
+}
+
+/*
+ * Modifiers.
+ */
+
+static
+void
+check_append(atf_error_t (*append)(atf_dynstr_t *, const char *, ...))
+{
+    const size_t maxlen = 8192;
+    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++) {
+        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);
+        }
+
+        RE(append(&str, "a"));
+        strcat(buf, "a");
+    }
+    atf_dynstr_fini(&str);
+
+    printf("Appending with formatted string\n");
+    buf[0] = '\0';
+    RE(atf_dynstr_init(&str));
+    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);
+        }
+
+        RE(append(&str, "%s", "a"));
+        strcat(buf, "a");
+    }
+    atf_dynstr_fini(&str);
+}
+
+static
+atf_error_t
+append_ap_aux(atf_dynstr_t *str, const char *fmt, ...)
+{
+    va_list ap;
+    atf_error_t err;
+
+    va_start(ap, fmt);
+    err = atf_dynstr_append_ap(str, fmt, ap);
+    va_end(ap);
+
+    return err;
+}
+
+ATF_TC(append_ap);
+ATF_TC_HEAD(append_ap, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that appending a string to "
+                      "another one works");
+}
+ATF_TC_BODY(append_ap, tc)
+{
+    check_append(append_ap_aux);
+}
+
+ATF_TC(append_fmt);
+ATF_TC_HEAD(append_fmt, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that appending a string to "
+                      "another one works");
+}
+ATF_TC_BODY(append_fmt, tc)
+{
+    check_append(atf_dynstr_append_fmt);
+}
+
+ATF_TC(clear);
+ATF_TC_HEAD(clear, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks clearing a string");
+}
+ATF_TC_BODY(clear, tc)
+{
+    atf_dynstr_t str;
+
+    printf("Clear an empty string\n");
+    RE(atf_dynstr_init(&str));
+    atf_dynstr_clear(&str);
+    ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0);
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+    atf_dynstr_fini(&str);
+
+    printf("Clear a non-empty string\n");
+    RE(atf_dynstr_init_fmt(&str, "Not empty"));
+    ATF_REQUIRE_EQ(atf_dynstr_length(&str), strlen("Not empty"));
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Not empty") == 0);
+    atf_dynstr_clear(&str);
+    ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0);
+    ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);
+    atf_dynstr_fini(&str);
+}
+
+static
+void
+check_prepend(atf_error_t (*prepend)(atf_dynstr_t *, const char *, ...))
+{
+    const size_t maxlen = 8192;
+    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++) {
+        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);
+        }
+
+        memmove(buf + 1, buf, i + 1);
+        if (i % 2 == 0) {
+            RE(prepend(&str, "%s", "a"));
+            buf[0] = 'a';
+        } else {
+            RE(prepend(&str, "%s", "b"));
+            buf[0] = 'b';
+        }
+    }
+    atf_dynstr_fini(&str);
+
+    printf("Prepending with formatted string\n");
+    buf[0] = '\0';
+    RE(atf_dynstr_init(&str));
+    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);
+        }
+
+        memmove(buf + 1, buf, i + 1);
+        if (i % 2 == 0) {
+            RE(prepend(&str, "%s", "a"));
+            buf[0] = 'a';
+        } else {
+            RE(prepend(&str, "%s", "b"));
+            buf[0] = 'b';
+        }
+    }
+    atf_dynstr_fini(&str);
+}
+
+static
+atf_error_t
+prepend_ap_aux(atf_dynstr_t *str, const char *fmt, ...)
+{
+    va_list ap;
+    atf_error_t err;
+
+    va_start(ap, fmt);
+    err = atf_dynstr_prepend_ap(str, fmt, ap);
+    va_end(ap);
+
+    return err;
+}
+
+ATF_TC(prepend_ap);
+ATF_TC_HEAD(prepend_ap, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that prepending a string to "
+                      "another one works");
+}
+ATF_TC_BODY(prepend_ap, tc)
+{
+    check_prepend(prepend_ap_aux);
+}
+
+ATF_TC(prepend_fmt);
+ATF_TC_HEAD(prepend_fmt, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that prepending a string to "
+                      "another one works");
+}
+ATF_TC_BODY(prepend_fmt, tc)
+{
+    check_prepend(atf_dynstr_prepend_fmt);
+}
+
+/*
+ * Operators.
+ */
+
+ATF_TC(equal_cstring);
+ATF_TC_HEAD(equal_cstring, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_cstring "
+                      "function");
+}
+ATF_TC_BODY(equal_cstring, tc)
+{
+    atf_dynstr_t str;
+
+    RE(atf_dynstr_init(&str));
+    ATF_REQUIRE( atf_equal_dynstr_cstring(&str, ""));
+    ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test"));
+    atf_dynstr_fini(&str);
+
+    RE(atf_dynstr_init_fmt(&str, "Test"));
+    ATF_REQUIRE( atf_equal_dynstr_cstring(&str, "Test"));
+    ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, ""));
+    ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Tes"));
+    ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test "));
+    atf_dynstr_fini(&str);
+}
+
+ATF_TC(equal_dynstr);
+ATF_TC_HEAD(equal_dynstr, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_dynstr "
+                      "function");
+}
+ATF_TC_BODY(equal_dynstr, tc)
+{
+    atf_dynstr_t str, str2;
+
+    RE(atf_dynstr_init(&str));
+    RE(atf_dynstr_init_fmt(&str2, "Test"));
+    ATF_REQUIRE( atf_equal_dynstr_dynstr(&str, &str));
+    ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2));
+    atf_dynstr_fini(&str2);
+    atf_dynstr_fini(&str);
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    /* Constructors and destructors. */
+    ATF_TP_ADD_TC(tp, init);
+    ATF_TP_ADD_TC(tp, init_ap);
+    ATF_TP_ADD_TC(tp, init_fmt);
+    ATF_TP_ADD_TC(tp, init_raw);
+    ATF_TP_ADD_TC(tp, init_rep);
+    ATF_TP_ADD_TC(tp, init_substr);
+    ATF_TP_ADD_TC(tp, copy);
+    ATF_TP_ADD_TC(tp, fini_disown);
+
+    /* Getters. */
+    ATF_TP_ADD_TC(tp, cstring);
+    ATF_TP_ADD_TC(tp, length);
+    ATF_TP_ADD_TC(tp, rfind_ch);
+
+    /* Modifiers. */
+    ATF_TP_ADD_TC(tp, append_ap);
+    ATF_TP_ADD_TC(tp, append_fmt);
+    ATF_TP_ADD_TC(tp, clear);
+    ATF_TP_ADD_TC(tp, prepend_ap);
+    ATF_TP_ADD_TC(tp, prepend_fmt);
+
+    /* Operators. */
+    ATF_TP_ADD_TC(tp, equal_cstring);
+    ATF_TP_ADD_TC(tp, equal_dynstr);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/detail/env.c
===================================================================
--- vendor/atf/dist/atf-c/detail/env.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/env.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,114 @@
+/* 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/env.h"
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include "atf-c/detail/sanity.h"
+#include "atf-c/detail/text.h"
+#include "atf-c/error.h"
+
+const char *
+atf_env_get(const char *name)
+{
+    const char* val = getenv(name);
+    PRE(val != NULL);
+    return val;
+}
+
+const char *
+atf_env_get_with_default(const char *name, const char *default_value)
+{
+    const char* val = getenv(name);
+    if (val == NULL)
+        return default_value;
+    else
+        return val;
+}
+
+bool
+atf_env_has(const char *name)
+{
+    return getenv(name) != NULL;
+}
+
+atf_error_t
+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);
+    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;
+}
+
+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;
+}

Added: vendor/atf/dist/atf-c/detail/env.h
===================================================================
--- vendor/atf/dist/atf-c/detail/env.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/env.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,39 @@
+/* Copyright (c) 2008 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_C_DETAIL_ENV_H)
+#define ATF_C_DETAIL_ENV_H
+
+#include <stdbool.h>
+
+#include <atf-c/error_fwd.h>
+
+const char *atf_env_get(const char *);
+const char *atf_env_get_with_default(const char *, const char *);
+bool atf_env_has(const char *);
+atf_error_t atf_env_set(const char *, const char *);
+atf_error_t atf_env_unset(const char *);
+
+#endif /* !defined(ATF_C_DETAIL_ENV_H) */

Added: vendor/atf/dist/atf-c/detail/env_test.c
===================================================================
--- vendor/atf/dist/atf-c/detail/env_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/env_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,133 @@
+/* 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/env.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/test_helpers.h"
+#include "atf-c/detail/text.h"
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(has);
+ATF_TC_HEAD(has, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_env_has function");
+}
+ATF_TC_BODY(has, tc)
+{
+    ATF_REQUIRE(atf_env_has("PATH"));
+    ATF_REQUIRE(!atf_env_has("_UNDEFINED_VARIABLE_"));
+}
+
+ATF_TC(get);
+ATF_TC_HEAD(get, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_env_get function");
+}
+ATF_TC_BODY(get, tc)
+{
+    const char *val;
+
+    ATF_REQUIRE(atf_env_has("PATH"));
+
+    val = atf_env_get("PATH");
+    ATF_REQUIRE(strlen(val) > 0);
+    ATF_REQUIRE(strchr(val, ':') != NULL);
+}
+
+ATF_TC(get_with_default);
+ATF_TC_HEAD(get_with_default, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_env_get_with_default "
+                      "function");
+}
+ATF_TC_BODY(get_with_default, tc)
+{
+    const char *val;
+
+    ATF_REQUIRE(atf_env_has("PATH"));
+
+    val = atf_env_get_with_default("PATH", "unknown");
+    ATF_REQUIRE(strcmp(val, "unknown") != 0);
+
+    val = atf_env_get_with_default("_UNKNOWN_VARIABLE_", "foo bar");
+    ATF_REQUIRE(strcmp(val, "foo bar") == 0);
+}
+
+ATF_TC(set);
+ATF_TC_HEAD(set, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_env_set function");
+}
+ATF_TC_BODY(set, tc)
+{
+    char *oldval;
+
+    ATF_REQUIRE(atf_env_has("PATH"));
+    RE(atf_text_format(&oldval, "%s", atf_env_get("PATH")));
+    RE(atf_env_set("PATH", "foo-bar"));
+    ATF_REQUIRE(strcmp(atf_env_get("PATH"), oldval) != 0);
+    ATF_REQUIRE(strcmp(atf_env_get("PATH"), "foo-bar") == 0);
+    free(oldval);
+
+    ATF_REQUIRE(!atf_env_has("_UNDEFINED_VARIABLE_"));
+    RE(atf_env_set("_UNDEFINED_VARIABLE_", "foo2-bar2"));
+    ATF_REQUIRE(strcmp(atf_env_get("_UNDEFINED_VARIABLE_"),
+                     "foo2-bar2") == 0);
+}
+
+ATF_TC(unset);
+ATF_TC_HEAD(unset, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_env_unset function");
+}
+ATF_TC_BODY(unset, tc)
+{
+    ATF_REQUIRE(atf_env_has("PATH"));
+    RE(atf_env_unset("PATH"));
+    ATF_REQUIRE(!atf_env_has("PATH"));
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    ATF_TP_ADD_TC(tp, has);
+    ATF_TP_ADD_TC(tp, get);
+    ATF_TP_ADD_TC(tp, get_with_default);
+    ATF_TP_ADD_TC(tp, set);
+    ATF_TP_ADD_TC(tp, unset);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/detail/fs.c
===================================================================
--- vendor/atf/dist/atf-c/detail/fs.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/fs.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,884 @@
+/* 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/fs.h"
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <libgen.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "atf-c/defs.h"
+#include "atf-c/detail/sanity.h"
+#include "atf-c/detail/text.h"
+#include "atf-c/detail/user.h"
+#include "atf-c/error.h"
+
+/* ---------------------------------------------------------------------
+ * Prototypes for auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static bool check_umask(const mode_t, const mode_t);
+static atf_error_t copy_contents(const atf_fs_path_t *, char **);
+static mode_t current_umask(void);
+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 "invalid_umask" error type.
+ * --------------------------------------------------------------------- */
+
+struct invalid_umask_error_data {
+    /* One of atf_fs_stat_*_type. */
+    int m_type;
+
+    /* The original path causing the error. */
+    /* XXX: Ideally this would be an atf_fs_path_t, but if we create it
+     * from the error constructor, we cannot delete the path later on.
+     * Can't remember why atf_error_new does not take a hook for
+     * deletion. */
+    char m_path[1024];
+
+    /* The umask that caused the error. */
+    mode_t m_umask;
+};
+typedef struct invalid_umask_error_data invalid_umask_error_data_t;
+
+static
+void
+invalid_umask_format(const atf_error_t err, char *buf, size_t buflen)
+{
+    const invalid_umask_error_data_t *data;
+
+    PRE(atf_error_is(err, "invalid_umask"));
+
+    data = atf_error_data(err);
+    snprintf(buf, buflen, "Could not create the temporary %s %s because "
+             "it will not have enough access rights due to the current "
+             "umask %05o", stat_type_to_string(data->m_type),
+             data->m_path, (unsigned int)data->m_umask);
+}
+
+static
+atf_error_t
+invalid_umask_error(const atf_fs_path_t *path, const int type,
+                    const mode_t failing_mask)
+{
+    atf_error_t err;
+    invalid_umask_error_data_t data;
+
+    data.m_type = type;
+
+    strncpy(data.m_path, atf_fs_path_cstring(path), sizeof(data.m_path));
+    data.m_path[sizeof(data.m_path) - 1] = '\0';
+
+    data.m_umask = failing_mask;
+
+    err = atf_error_new("invalid_umask", &data, sizeof(data),
+                        invalid_umask_format);
+
+    return err;
+}
+
+/* ---------------------------------------------------------------------
+ * The "unknown_file_type" error type.
+ * --------------------------------------------------------------------- */
+
+struct unknown_type_error_data {
+    const char *m_path;
+    int m_type;
+};
+typedef struct unknown_type_error_data unknown_type_error_data_t;
+
+static
+void
+unknown_type_format(const atf_error_t err, char *buf, size_t buflen)
+{
+    const unknown_type_error_data_t *data;
+
+    PRE(atf_error_is(err, "unknown_type"));
+
+    data = atf_error_data(err);
+    snprintf(buf, buflen, "Unknown file type %d of %s", data->m_type,
+             data->m_path);
+}
+
+static
+atf_error_t
+unknown_type_error(const char *path, int type)
+{
+    atf_error_t err;
+    unknown_type_error_data_t data;
+
+    data.m_path = path;
+    data.m_type = type;
+
+    err = atf_error_new("unknown_type", &data, sizeof(data),
+                        unknown_type_format);
+
+    return err;
+}
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+bool
+check_umask(const mode_t exp_mode, const mode_t min_mode)
+{
+    const mode_t actual_mode = (~current_umask() & exp_mode);
+    return (actual_mode & min_mode) == min_mode;
+}
+
+static
+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)
+        err = atf_no_memory_error();
+    else {
+        strcpy(str, atf_dynstr_cstring(&p->m_data));
+        *buf = str;
+        err = atf_no_error();
+    }
+
+    return err;
+}
+
+static
+mode_t
+current_umask(void)
+{
+    const mode_t current = umask(0);
+    (void)umask(current);
+    return current;
+}
+
+static
+atf_error_t
+do_mkdtemp(char *tmpl)
+{
+    atf_error_t err;
+
+    PRE(strstr(tmpl, "XXXXXX") != NULL);
+
+    if (mkdtemp(tmpl) == NULL)
+        err = atf_libc_error(errno, "Cannot create temporary directory "
+                             "with template '%s'", tmpl);
+    else
+        err = atf_no_error();
+
+    return err;
+}
+
+static
+atf_error_t
+do_mkstemp(char *tmpl, int *fdout)
+{
+    atf_error_t err;
+
+    PRE(strstr(tmpl, "XXXXXX") != NULL);
+
+    *fdout = mkstemp(tmpl);
+    if (*fdout == -1)
+        err = atf_libc_error(errno, "Cannot create temporary file "
+                             "with template '%s'", tmpl);
+
+    else
+        err = atf_no_error();
+
+    return err;
+}
+
+static
+atf_error_t
+normalize(atf_dynstr_t *d, char *p)
+{
+    const char *ptr;
+    char *last;
+    atf_error_t err;
+    bool first;
+
+    PRE(strlen(p) > 0);
+    PRE(atf_dynstr_length(d) == 0);
+
+    if (p[0] == '/')
+        err = atf_dynstr_append_fmt(d, "/");
+    else
+        err = atf_no_error();
+
+    first = true;
+    last = NULL; /* Silence GCC warning. */
+    ptr = strtok_r(p, "/", &last);
+    while (!atf_is_error(err) && ptr != NULL) {
+        if (strlen(ptr) > 0) {
+            err = atf_dynstr_append_fmt(d, "%s%s", first ? "" : "/", ptr);
+            first = false;
+        }
+
+        ptr = strtok_r(NULL, "/", &last);
+    }
+
+    return err;
+}
+
+static
+atf_error_t
+normalize_ap(atf_dynstr_t *d, const char *p, va_list ap)
+{
+    char *str;
+    atf_error_t err;
+    va_list ap2;
+
+    err = atf_dynstr_init(d);
+    if (atf_is_error(err))
+        goto out;
+
+    va_copy(ap2, ap);
+    err = atf_text_format_ap(&str, p, ap2);
+    va_end(ap2);
+    if (atf_is_error(err))
+        atf_dynstr_fini(d);
+    else {
+        err = normalize(d, str);
+        free(str);
+    }
+
+out:
+    return err;
+}
+
+static
+void
+replace_contents(atf_fs_path_t *p, const char *buf)
+{
+    atf_error_t err;
+
+    PRE(atf_dynstr_length(&p->m_data) == strlen(buf));
+
+    atf_dynstr_clear(&p->m_data);
+    err = atf_dynstr_append_fmt(&p->m_data, "%s", 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.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constructors/destructors.
+ */
+
+atf_error_t
+atf_fs_path_init_ap(atf_fs_path_t *p, const char *fmt, va_list ap)
+{
+    atf_error_t err;
+    va_list ap2;
+
+    va_copy(ap2, ap);
+    err = normalize_ap(&p->m_data, fmt, ap2);
+    va_end(ap2);
+
+    return err;
+}
+
+atf_error_t
+atf_fs_path_init_fmt(atf_fs_path_t *p, const char *fmt, ...)
+{
+    va_list ap;
+    atf_error_t err;
+
+    va_start(ap, fmt);
+    err = atf_fs_path_init_ap(p, fmt, ap);
+    va_end(ap);
+
+    return err;
+}
+
+atf_error_t
+atf_fs_path_copy(atf_fs_path_t *dest, const atf_fs_path_t *src)
+{
+    return atf_dynstr_copy(&dest->m_data, &src->m_data);
+}
+
+void
+atf_fs_path_fini(atf_fs_path_t *p)
+{
+    atf_dynstr_fini(&p->m_data);
+}
+
+/*
+ * Getters.
+ */
+
+atf_error_t
+atf_fs_path_branch_path(const atf_fs_path_t *p, atf_fs_path_t *bp)
+{
+    const size_t endpos = atf_dynstr_rfind_ch(&p->m_data, '/');
+    atf_error_t err;
+
+    if (endpos == atf_dynstr_npos)
+        err = atf_fs_path_init_fmt(bp, ".");
+    else if (endpos == 0)
+        err = atf_fs_path_init_fmt(bp, "/");
+    else
+        err = atf_dynstr_init_substr(&bp->m_data, &p->m_data, 0, endpos);
+
+#if defined(HAVE_CONST_DIRNAME)
+    INV(atf_equal_dynstr_cstring(&bp->m_data,
+                                 dirname(atf_dynstr_cstring(&p->m_data))));
+#endif /* defined(HAVE_CONST_DIRNAME) */
+
+    return err;
+}
+
+const char *
+atf_fs_path_cstring(const atf_fs_path_t *p)
+{
+    return atf_dynstr_cstring(&p->m_data);
+}
+
+atf_error_t
+atf_fs_path_leaf_name(const atf_fs_path_t *p, atf_dynstr_t *ln)
+{
+    size_t begpos = atf_dynstr_rfind_ch(&p->m_data, '/');
+    atf_error_t err;
+
+    if (begpos == atf_dynstr_npos)
+        begpos = 0;
+    else
+        begpos++;
+
+    err = atf_dynstr_init_substr(ln, &p->m_data, begpos, atf_dynstr_npos);
+
+#if defined(HAVE_CONST_BASENAME)
+    INV(atf_equal_dynstr_cstring(ln,
+                                 basename(atf_dynstr_cstring(&p->m_data))));
+#endif /* defined(HAVE_CONST_BASENAME) */
+
+    return err;
+}
+
+bool
+atf_fs_path_is_absolute(const atf_fs_path_t *p)
+{
+    return atf_dynstr_cstring(&p->m_data)[0] == '/';
+}
+
+bool
+atf_fs_path_is_root(const atf_fs_path_t *p)
+{
+    return atf_equal_dynstr_cstring(&p->m_data, "/");
+}
+
+/*
+ * Modifiers.
+ */
+
+atf_error_t
+atf_fs_path_append_ap(atf_fs_path_t *p, const char *fmt, va_list ap)
+{
+    atf_dynstr_t aux;
+    atf_error_t err;
+    va_list ap2;
+
+    va_copy(ap2, ap);
+    err = normalize_ap(&aux, fmt, ap2);
+    va_end(ap2);
+    if (!atf_is_error(err)) {
+        const char *auxstr = atf_dynstr_cstring(&aux);
+        const bool needslash = auxstr[0] != '/';
+
+        err = atf_dynstr_append_fmt(&p->m_data, "%s%s",
+                                    needslash ? "/" : "", auxstr);
+
+        atf_dynstr_fini(&aux);
+    }
+
+    return err;
+}
+
+atf_error_t
+atf_fs_path_append_fmt(atf_fs_path_t *p, const char *fmt, ...)
+{
+    va_list ap;
+    atf_error_t err;
+
+    va_start(ap, fmt);
+    err = atf_fs_path_append_ap(p, fmt, ap);
+    va_end(ap);
+
+    return err;
+}
+
+atf_error_t
+atf_fs_path_append_path(atf_fs_path_t *p, const atf_fs_path_t *p2)
+{
+    return atf_fs_path_append_fmt(p, "%s", atf_dynstr_cstring(&p2->m_data));
+}
+
+atf_error_t
+atf_fs_path_to_absolute(const atf_fs_path_t *p, atf_fs_path_t *pa)
+{
+    atf_error_t err;
+
+    PRE(!atf_fs_path_is_absolute(p));
+
+    err = atf_fs_getcwd(pa);
+    if (atf_is_error(err))
+        goto out;
+
+    err = atf_fs_path_append_path(pa, p);
+    if (atf_is_error(err))
+        atf_fs_path_fini(pa);
+
+out:
+    return err;
+}
+
+/*
+ * Operators.
+ */
+
+bool atf_equal_fs_path_fs_path(const atf_fs_path_t *p1,
+                               const atf_fs_path_t *p2)
+{
+    return atf_equal_dynstr_dynstr(&p1->m_data, &p2->m_data);
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_fs_path" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constants.
+ */
+
+const int atf_fs_stat_blk_type  = 1;
+const int atf_fs_stat_chr_type  = 2;
+const int atf_fs_stat_dir_type  = 3;
+const int atf_fs_stat_fifo_type = 4;
+const int atf_fs_stat_lnk_type  = 5;
+const int atf_fs_stat_reg_type  = 6;
+const int atf_fs_stat_sock_type = 7;
+const int atf_fs_stat_wht_type  = 8;
+
+/*
+ * Constructors/destructors.
+ */
+
+atf_error_t
+atf_fs_stat_init(atf_fs_stat_t *st, const atf_fs_path_t *p)
+{
+    atf_error_t err;
+    const char *pstr = atf_fs_path_cstring(p);
+
+    if (lstat(pstr, &st->m_sb) == -1) {
+        err = atf_libc_error(errno, "Cannot get information of %s; "
+                             "lstat(2) failed", pstr);
+    } else {
+        int type = st->m_sb.st_mode & S_IFMT;
+        err = atf_no_error();
+        switch (type) {
+            case S_IFBLK:  st->m_type = atf_fs_stat_blk_type;  break;
+            case S_IFCHR:  st->m_type = atf_fs_stat_chr_type;  break;
+            case S_IFDIR:  st->m_type = atf_fs_stat_dir_type;  break;
+            case S_IFIFO:  st->m_type = atf_fs_stat_fifo_type; break;
+            case S_IFLNK:  st->m_type = atf_fs_stat_lnk_type;  break;
+            case S_IFREG:  st->m_type = atf_fs_stat_reg_type;  break;
+            case S_IFSOCK: st->m_type = atf_fs_stat_sock_type; break;
+#if defined(S_IFWHT)
+            case S_IFWHT:  st->m_type = atf_fs_stat_wht_type;  break;
+#endif
+            default:
+                err = unknown_type_error(pstr, type);
+        }
+    }
+
+    return err;
+}
+
+void
+atf_fs_stat_copy(atf_fs_stat_t *dest, const atf_fs_stat_t *src)
+{
+    dest->m_type = src->m_type;
+    dest->m_sb = src->m_sb;
+}
+
+void
+atf_fs_stat_fini(atf_fs_stat_t *st ATF_DEFS_ATTRIBUTE_UNUSED)
+{
+}
+
+/*
+ * Getters.
+ */
+
+dev_t
+atf_fs_stat_get_device(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_dev;
+}
+
+ino_t
+atf_fs_stat_get_inode(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_ino;
+}
+
+mode_t
+atf_fs_stat_get_mode(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_mode & ~S_IFMT;
+}
+
+off_t
+atf_fs_stat_get_size(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_size;
+}
+
+int
+atf_fs_stat_get_type(const atf_fs_stat_t *st)
+{
+    return st->m_type;
+}
+
+bool
+atf_fs_stat_is_owner_readable(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_mode & S_IRUSR;
+}
+
+bool
+atf_fs_stat_is_owner_writable(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_mode & S_IWUSR;
+}
+
+bool
+atf_fs_stat_is_owner_executable(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_mode & S_IXUSR;
+}
+
+bool
+atf_fs_stat_is_group_readable(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_mode & S_IRGRP;
+}
+
+bool
+atf_fs_stat_is_group_writable(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_mode & S_IWGRP;
+}
+
+bool
+atf_fs_stat_is_group_executable(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_mode & S_IXGRP;
+}
+
+bool
+atf_fs_stat_is_other_readable(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_mode & S_IROTH;
+}
+
+bool
+atf_fs_stat_is_other_writable(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_mode & S_IWOTH;
+}
+
+bool
+atf_fs_stat_is_other_executable(const atf_fs_stat_t *st)
+{
+    return st->m_sb.st_mode & S_IXOTH;
+}
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+const int atf_fs_access_f = 1 << 0;
+const int atf_fs_access_r = 1 << 1;
+const int atf_fs_access_w = 1 << 2;
+const int atf_fs_access_x = 1 << 3;
+
+/*
+ * An implementation of access(2) but using the effective user value
+ * instead of the real one.  Also avoids false positives for root when
+ * asking for execute permissions, which appear in SunOS.
+ */
+atf_error_t
+atf_fs_eaccess(const atf_fs_path_t *p, int mode)
+{
+    atf_error_t err;
+    struct stat st;
+    bool ok;
+
+    PRE(mode & atf_fs_access_f || mode & atf_fs_access_r ||
+        mode & atf_fs_access_w || mode & atf_fs_access_x);
+
+    if (lstat(atf_fs_path_cstring(p), &st) == -1) {
+        err = atf_libc_error(errno, "Cannot get information from file %s",
+                             atf_fs_path_cstring(p));
+        goto out;
+    }
+
+    err = atf_no_error();
+
+    /* Early return if we are only checking for existence and the file
+     * exists (stat call returned). */
+    if (mode & atf_fs_access_f)
+        goto out;
+
+    ok = false;
+    if (atf_user_is_root()) {
+        if (!ok && !(mode & atf_fs_access_x)) {
+            /* Allow root to read/write any file. */
+            ok = true;
+        }
+
+        if (!ok && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
+            /* Allow root to execute the file if any of its execution bits
+             * are set. */
+            ok = true;
+        }
+    } else {
+        if (!ok && (atf_user_euid() == st.st_uid)) {
+            ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IRUSR)) ||
+                 ((mode & atf_fs_access_w) && (st.st_mode & S_IWUSR)) ||
+                 ((mode & atf_fs_access_x) && (st.st_mode & S_IXUSR));
+        }
+        if (!ok && atf_user_is_member_of_group(st.st_gid)) {
+            ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IRGRP)) ||
+                 ((mode & atf_fs_access_w) && (st.st_mode & S_IWGRP)) ||
+                 ((mode & atf_fs_access_x) && (st.st_mode & S_IXGRP));
+        }
+        if (!ok && ((atf_user_euid() != st.st_uid) &&
+                    !atf_user_is_member_of_group(st.st_gid))) {
+            ok = ((mode & atf_fs_access_r) && (st.st_mode & S_IROTH)) ||
+                 ((mode & atf_fs_access_w) && (st.st_mode & S_IWOTH)) ||
+                 ((mode & atf_fs_access_x) && (st.st_mode & S_IXOTH));
+        }
+    }
+
+    if (!ok)
+        err = atf_libc_error(EACCES, "Access check failed");
+
+out:
+    return err;
+}
+
+atf_error_t
+atf_fs_exists(const atf_fs_path_t *p, bool *b)
+{
+    atf_error_t err;
+
+    err = atf_fs_eaccess(p, atf_fs_access_f);
+    if (atf_is_error(err)) {
+        if (atf_error_is(err, "libc") && atf_libc_error_code(err) == ENOENT) {
+            atf_error_free(err);
+            err = atf_no_error();
+            *b = false;
+        }
+    } else
+        *b = true;
+
+    return err;
+}
+
+atf_error_t
+atf_fs_getcwd(atf_fs_path_t *p)
+{
+    atf_error_t err;
+    char *cwd;
+
+#if defined(HAVE_GETCWD_DYN)
+    cwd = getcwd(NULL, 0);
+#else
+    cwd = getcwd(NULL, MAXPATHLEN);
+#endif
+    if (cwd == NULL) {
+        err = atf_libc_error(errno, "Cannot determine current directory");
+        goto out;
+    }
+
+    err = atf_fs_path_init_fmt(p, "%s", cwd);
+    free(cwd);
+
+out:
+    return err;
+}
+
+atf_error_t
+atf_fs_mkdtemp(atf_fs_path_t *p)
+{
+    atf_error_t err;
+    char *buf;
+
+    if (!check_umask(S_IRWXU, S_IRWXU)) {
+        err = invalid_umask_error(p, atf_fs_stat_dir_type, current_umask());
+        goto out;
+    }
+
+    err = copy_contents(p, &buf);
+    if (atf_is_error(err))
+        goto out;
+
+    err = do_mkdtemp(buf);
+    if (atf_is_error(err))
+        goto out_buf;
+
+    replace_contents(p, buf);
+
+    INV(!atf_is_error(err));
+out_buf:
+    free(buf);
+out:
+    return err;
+}
+
+atf_error_t
+atf_fs_mkstemp(atf_fs_path_t *p, int *fdout)
+{
+    atf_error_t err;
+    char *buf;
+    int fd;
+
+    if (!check_umask(S_IRWXU, S_IRWXU)) {
+        err = invalid_umask_error(p, atf_fs_stat_reg_type, current_umask());
+        goto out;
+    }
+
+    err = copy_contents(p, &buf);
+    if (atf_is_error(err))
+        goto out;
+
+    err = do_mkstemp(buf, &fd);
+    if (atf_is_error(err))
+        goto out_buf;
+
+    replace_contents(p, buf);
+    *fdout = fd;
+
+    INV(!atf_is_error(err));
+out_buf:
+    free(buf);
+out:
+    return err;
+}
+
+atf_error_t
+atf_fs_rmdir(const atf_fs_path_t *p)
+{
+    atf_error_t err;
+
+    if (rmdir(atf_fs_path_cstring(p))) {
+        if (errno == EEXIST) {
+            /* Some operating systems (e.g. OpenSolaris 200906) return
+             * EEXIST instead of ENOTEMPTY for non-empty directories.
+             * Homogenize the return value so that callers don't need
+             * to bother about differences in operating systems. */
+            errno = ENOTEMPTY;
+        }
+        err = atf_libc_error(errno, "Cannot remove directory");
+    } else
+        err = atf_no_error();
+
+    return err;
+}
+
+atf_error_t
+atf_fs_unlink(const atf_fs_path_t *p)
+{
+    atf_error_t err;
+    const char *path;
+
+    path = atf_fs_path_cstring(p);
+
+    if (unlink(path) != 0)
+        err = atf_libc_error(errno, "Cannot unlink file: '%s'", path);
+    else
+        err = atf_no_error();
+
+    return err;
+}

Added: vendor/atf/dist/atf-c/detail/fs.h
===================================================================
--- vendor/atf/dist/atf-c/detail/fs.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/fs.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,128 @@
+/* Copyright (c) 2008 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_C_DETAIL_FS_H)
+#define ATF_C_DETAIL_FS_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <stdarg.h>
+#include <stdbool.h>
+
+#include <atf-c/detail/dynstr.h>
+#include <atf-c/error_fwd.h>
+
+/* ---------------------------------------------------------------------
+ * The "atf_fs_path" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_fs_path {
+    atf_dynstr_t m_data;
+};
+typedef struct atf_fs_path atf_fs_path_t;
+
+/* Constructors/destructors. */
+atf_error_t atf_fs_path_init_ap(atf_fs_path_t *, const char *, va_list);
+atf_error_t atf_fs_path_init_fmt(atf_fs_path_t *, const char *, ...);
+atf_error_t atf_fs_path_copy(atf_fs_path_t *, const atf_fs_path_t *);
+void atf_fs_path_fini(atf_fs_path_t *);
+
+/* Getters. */
+atf_error_t atf_fs_path_branch_path(const atf_fs_path_t *, atf_fs_path_t *);
+const char *atf_fs_path_cstring(const atf_fs_path_t *);
+atf_error_t atf_fs_path_leaf_name(const atf_fs_path_t *, atf_dynstr_t *);
+bool atf_fs_path_is_absolute(const atf_fs_path_t *);
+bool atf_fs_path_is_root(const atf_fs_path_t *);
+
+/* Modifiers. */
+atf_error_t atf_fs_path_append_ap(atf_fs_path_t *, const char *, va_list);
+atf_error_t atf_fs_path_append_fmt(atf_fs_path_t *, const char *, ...);
+atf_error_t atf_fs_path_append_path(atf_fs_path_t *, const atf_fs_path_t *);
+atf_error_t atf_fs_path_to_absolute(const atf_fs_path_t *, atf_fs_path_t *);
+
+/* Operators. */
+bool atf_equal_fs_path_fs_path(const atf_fs_path_t *,
+                               const atf_fs_path_t *);
+
+/* ---------------------------------------------------------------------
+ * The "atf_fs_stat" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_fs_stat {
+    int m_type;
+    struct stat m_sb;
+};
+typedef struct atf_fs_stat atf_fs_stat_t;
+
+/* Constants. */
+extern const int atf_fs_stat_blk_type;
+extern const int atf_fs_stat_chr_type;
+extern const int atf_fs_stat_dir_type;
+extern const int atf_fs_stat_fifo_type;
+extern const int atf_fs_stat_lnk_type;
+extern const int atf_fs_stat_reg_type;
+extern const int atf_fs_stat_sock_type;
+extern const int atf_fs_stat_wht_type;
+
+/* Constructors/destructors. */
+atf_error_t atf_fs_stat_init(atf_fs_stat_t *, const atf_fs_path_t *);
+void atf_fs_stat_copy(atf_fs_stat_t *, const atf_fs_stat_t *);
+void atf_fs_stat_fini(atf_fs_stat_t *);
+
+/* Getters. */
+dev_t atf_fs_stat_get_device(const atf_fs_stat_t *);
+ino_t atf_fs_stat_get_inode(const atf_fs_stat_t *);
+mode_t atf_fs_stat_get_mode(const atf_fs_stat_t *);
+off_t atf_fs_stat_get_size(const atf_fs_stat_t *);
+int atf_fs_stat_get_type(const atf_fs_stat_t *);
+bool atf_fs_stat_is_owner_readable(const atf_fs_stat_t *);
+bool atf_fs_stat_is_owner_writable(const atf_fs_stat_t *);
+bool atf_fs_stat_is_owner_executable(const atf_fs_stat_t *);
+bool atf_fs_stat_is_group_readable(const atf_fs_stat_t *);
+bool atf_fs_stat_is_group_writable(const atf_fs_stat_t *);
+bool atf_fs_stat_is_group_executable(const atf_fs_stat_t *);
+bool atf_fs_stat_is_other_readable(const atf_fs_stat_t *);
+bool atf_fs_stat_is_other_writable(const atf_fs_stat_t *);
+bool atf_fs_stat_is_other_executable(const atf_fs_stat_t *);
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+extern const int atf_fs_access_f;
+extern const int atf_fs_access_r;
+extern const int atf_fs_access_w;
+extern const int atf_fs_access_x;
+
+atf_error_t atf_fs_eaccess(const atf_fs_path_t *, int);
+atf_error_t atf_fs_exists(const atf_fs_path_t *, bool *);
+atf_error_t atf_fs_getcwd(atf_fs_path_t *);
+atf_error_t atf_fs_mkdtemp(atf_fs_path_t *);
+atf_error_t atf_fs_mkstemp(atf_fs_path_t *, int *);
+atf_error_t atf_fs_rmdir(const atf_fs_path_t *);
+atf_error_t atf_fs_unlink(const atf_fs_path_t *);
+
+#endif /* !defined(ATF_C_DETAIL_FS_H) */

Added: vendor/atf/dist/atf-c/detail/fs_test.c
===================================================================
--- vendor/atf/dist/atf-c/detail/fs_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/fs_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,1079 @@
+/* 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/fs.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/test_helpers.h"
+#include "atf-c/detail/user.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+create_dir(const char *p, int mode)
+{
+    int ret;
+
+    ret = mkdir(p, mode);
+    if (ret == -1)
+        atf_tc_fail("Could not create helper directory %s", p);
+}
+
+static
+void
+create_file(const char *p, int mode)
+{
+    int fd;
+
+    fd = open(p, O_CREAT | O_WRONLY | O_TRUNC, mode);
+    if (fd == -1)
+        atf_tc_fail("Could not create helper file %s", p);
+    close(fd);
+}
+
+static
+bool
+exists(const atf_fs_path_t *p)
+{
+    return access(atf_fs_path_cstring(p), F_OK) == 0;
+}
+
+static
+atf_error_t
+mkstemp_discard_fd(atf_fs_path_t *p)
+{
+    int fd;
+    atf_error_t err = atf_fs_mkstemp(p, &fd);
+    if (!atf_is_error(err))
+        close(fd);
+    return err;
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "atf_fs_path" type.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(path_normalize);
+ATF_TC_HEAD(path_normalize, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the path's normalization");
+}
+ATF_TC_BODY(path_normalize, tc)
+{
+    struct test {
+        const char *in;
+        const char *out;
+    } tests[] = {
+        { ".", ".", },
+        { "..", "..", },
+
+        { "/", "/", },
+        { "//", "/", }, /* NO_CHECK_STYLE */
+        { "///", "/", }, /* NO_CHECK_STYLE */
+
+        { "foo", "foo", },
+        { "foo/", "foo", },
+        { "foo/bar", "foo/bar", },
+        { "foo/bar/", "foo/bar", },
+
+        { "/foo", "/foo", },
+        { "/foo/bar", "/foo/bar", },
+        { "/foo/bar/", "/foo/bar", },
+
+        { "///foo", "/foo", }, /* NO_CHECK_STYLE */
+        { "///foo///bar", "/foo/bar", }, /* NO_CHECK_STYLE */
+        { "///foo///bar///", "/foo/bar", }, /* NO_CHECK_STYLE */
+
+        { NULL, NULL }
+    };
+    struct test *t;
+
+    for (t = &tests[0]; t->in != NULL; t++) {
+        atf_fs_path_t p;
+
+        printf("Input          : >%s<\n", t->in);
+        printf("Expected output: >%s<\n", t->out);
+
+        RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+        printf("Output         : >%s<\n", atf_fs_path_cstring(&p));
+        ATF_REQUIRE(strcmp(atf_fs_path_cstring(&p), t->out) == 0);
+        atf_fs_path_fini(&p);
+
+        printf("\n");
+    }
+}
+
+ATF_TC(path_copy);
+ATF_TC_HEAD(path_copy, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_copy constructor");
+}
+ATF_TC_BODY(path_copy, tc)
+{
+    atf_fs_path_t str, str2;
+
+    RE(atf_fs_path_init_fmt(&str, "foo"));
+    RE(atf_fs_path_copy(&str2, &str));
+
+    ATF_REQUIRE(atf_equal_fs_path_fs_path(&str, &str2));
+
+    RE(atf_fs_path_append_fmt(&str2, "bar"));
+
+    ATF_REQUIRE(!atf_equal_fs_path_fs_path(&str, &str2));
+
+    atf_fs_path_fini(&str2);
+    atf_fs_path_fini(&str);
+}
+
+ATF_TC(path_is_absolute);
+ATF_TC_HEAD(path_is_absolute, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the path::is_absolute function");
+}
+ATF_TC_BODY(path_is_absolute, tc)
+{
+    struct test {
+        const char *in;
+        bool abs;
+    } tests[] = {
+        { "/", true },
+        { "////", true }, /* NO_CHECK_STYLE */
+        { "////a", true }, /* NO_CHECK_STYLE */
+        { "//a//", true }, /* NO_CHECK_STYLE */
+        { "a////", false }, /* NO_CHECK_STYLE */
+        { "../foo", false },
+        { NULL, false },
+    };
+    struct test *t;
+
+    for (t = &tests[0]; t->in != NULL; t++) {
+        atf_fs_path_t p;
+
+        printf("Input          : %s\n", t->in);
+        printf("Expected result: %s\n", t->abs ? "true" : "false");
+
+        RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+        printf("Result         : %s\n",
+               atf_fs_path_is_absolute(&p) ? "true" : "false");
+        if (t->abs)
+            ATF_REQUIRE(atf_fs_path_is_absolute(&p));
+        else
+            ATF_REQUIRE(!atf_fs_path_is_absolute(&p));
+        atf_fs_path_fini(&p);
+
+        printf("\n");
+    }
+}
+
+ATF_TC(path_is_root);
+ATF_TC_HEAD(path_is_root, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the path::is_root function");
+}
+ATF_TC_BODY(path_is_root, tc)
+{
+    struct test {
+        const char *in;
+        bool root;
+    } tests[] = {
+        { "/", true },
+        { "////", true }, /* NO_CHECK_STYLE */
+        { "////a", false }, /* NO_CHECK_STYLE */
+        { "//a//", false }, /* NO_CHECK_STYLE */
+        { "a////", false }, /* NO_CHECK_STYLE */
+        { "../foo", false },
+        { NULL, false },
+    };
+    struct test *t;
+
+    for (t = &tests[0]; t->in != NULL; t++) {
+        atf_fs_path_t p;
+
+        printf("Input          : %s\n", t->in);
+        printf("Expected result: %s\n", t->root ? "true" : "false");
+
+        RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+        printf("Result         : %s\n",
+               atf_fs_path_is_root(&p) ? "true" : "false");
+        if (t->root)
+            ATF_REQUIRE(atf_fs_path_is_root(&p));
+        else
+            ATF_REQUIRE(!atf_fs_path_is_root(&p));
+        atf_fs_path_fini(&p);
+
+        printf("\n");
+    }
+}
+
+ATF_TC(path_branch_path);
+ATF_TC_HEAD(path_branch_path, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_branch_path "
+                      "function");
+}
+ATF_TC_BODY(path_branch_path, tc)
+{
+    struct test {
+        const char *in;
+        const char *branch;
+    } tests[] = {
+        { ".", "." },
+        { "foo", "." },
+        { "foo/bar", "foo" },
+        { "/foo", "/" },
+        { "/foo/bar", "/foo" },
+        { NULL, NULL },
+    };
+    struct test *t;
+
+    for (t = &tests[0]; t->in != NULL; t++) {
+        atf_fs_path_t p, bp;
+
+        printf("Input          : %s\n", t->in);
+        printf("Expected output: %s\n", t->branch);
+
+        RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+        RE(atf_fs_path_branch_path(&p, &bp));
+        printf("Output         : %s\n", atf_fs_path_cstring(&bp));
+        ATF_REQUIRE(strcmp(atf_fs_path_cstring(&bp), t->branch) == 0);
+        atf_fs_path_fini(&bp);
+        atf_fs_path_fini(&p);
+
+        printf("\n");
+    }
+}
+
+ATF_TC(path_leaf_name);
+ATF_TC_HEAD(path_leaf_name, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_leaf_name "
+                      "function");
+}
+ATF_TC_BODY(path_leaf_name, tc)
+{
+    struct test {
+        const char *in;
+        const char *leaf;
+    } tests[] = {
+        { ".", "." },
+        { "foo", "foo" },
+        { "foo/bar", "bar" },
+        { "/foo", "foo" },
+        { "/foo/bar", "bar" },
+        { NULL, NULL },
+    };
+    struct test *t;
+
+    for (t = &tests[0]; t->in != NULL; t++) {
+        atf_fs_path_t p;
+        atf_dynstr_t ln;
+
+        printf("Input          : %s\n", t->in);
+        printf("Expected output: %s\n", t->leaf);
+
+        RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+        RE(atf_fs_path_leaf_name(&p, &ln));
+        printf("Output         : %s\n", atf_dynstr_cstring(&ln));
+        ATF_REQUIRE(atf_equal_dynstr_cstring(&ln, t->leaf));
+        atf_dynstr_fini(&ln);
+        atf_fs_path_fini(&p);
+
+        printf("\n");
+    }
+}
+
+ATF_TC(path_append);
+ATF_TC_HEAD(path_append, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the concatenation of multiple "
+                      "paths");
+}
+ATF_TC_BODY(path_append, tc)
+{
+    struct test {
+        const char *in;
+        const char *ap;
+        const char *out;
+    } tests[] = {
+        { "foo", "bar", "foo/bar" },
+        { "foo/", "/bar", "foo/bar" },
+        { "foo/", "/bar/baz", "foo/bar/baz" },
+        { "foo/", "///bar///baz", "foo/bar/baz" }, /* NO_CHECK_STYLE */
+
+        { NULL, NULL, NULL }
+    };
+    struct test *t;
+
+    for (t = &tests[0]; t->in != NULL; t++) {
+        atf_fs_path_t p;
+
+        printf("Input          : >%s<\n", t->in);
+        printf("Append         : >%s<\n", t->ap);
+        printf("Expected output: >%s<\n", t->out);
+
+        RE(atf_fs_path_init_fmt(&p, "%s", t->in));
+
+        RE(atf_fs_path_append_fmt(&p, "%s", t->ap));
+
+        printf("Output         : >%s<\n", atf_fs_path_cstring(&p));
+        ATF_REQUIRE(strcmp(atf_fs_path_cstring(&p), t->out) == 0);
+
+        atf_fs_path_fini(&p);
+
+        printf("\n");
+    }
+}
+
+ATF_TC(path_to_absolute);
+ATF_TC_HEAD(path_to_absolute, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_path_to_absolute "
+                      "function");
+}
+ATF_TC_BODY(path_to_absolute, tc)
+{
+    const char *names[] = { ".", "dir", NULL };
+    const char **n;
+
+    ATF_REQUIRE(mkdir("dir", 0755) != -1);
+
+    for (n = names; *n != NULL; n++) {
+        atf_fs_path_t p, p2;
+        atf_fs_stat_t st1, st2;
+
+        RE(atf_fs_path_init_fmt(&p, "%s", *n));
+        RE(atf_fs_stat_init(&st1, &p));
+        printf("Relative path: %s\n", atf_fs_path_cstring(&p));
+
+        RE(atf_fs_path_to_absolute(&p, &p2));
+        printf("Absolute path: %s\n", atf_fs_path_cstring(&p2));
+
+        ATF_REQUIRE(atf_fs_path_is_absolute(&p2));
+        RE(atf_fs_stat_init(&st2, &p2));
+
+        ATF_REQUIRE_EQ(atf_fs_stat_get_device(&st1),
+                        atf_fs_stat_get_device(&st2));
+        ATF_REQUIRE_EQ(atf_fs_stat_get_inode(&st1),
+                        atf_fs_stat_get_inode(&st2));
+
+        atf_fs_stat_fini(&st2);
+        atf_fs_stat_fini(&st1);
+        atf_fs_path_fini(&p2);
+        atf_fs_path_fini(&p);
+
+        printf("\n");
+    }
+}
+
+ATF_TC(path_equal);
+ATF_TC_HEAD(path_equal, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the equality operators for paths");
+}
+ATF_TC_BODY(path_equal, tc)
+{
+    atf_fs_path_t p1, p2;
+
+    RE(atf_fs_path_init_fmt(&p1, "foo"));
+
+    RE(atf_fs_path_init_fmt(&p2, "foo"));
+    ATF_REQUIRE(atf_equal_fs_path_fs_path(&p1, &p2));
+    atf_fs_path_fini(&p2);
+
+    RE(atf_fs_path_init_fmt(&p2, "bar"));
+    ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2));
+    atf_fs_path_fini(&p2);
+
+    atf_fs_path_fini(&p1);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "atf_fs_stat" type.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(stat_mode);
+ATF_TC_HEAD(stat_mode, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_mode function "
+                      "and, indirectly, the constructor");
+}
+ATF_TC_BODY(stat_mode, tc)
+{
+    atf_fs_path_t p;
+    atf_fs_stat_t st;
+
+    create_file("f1", 0400);
+    create_file("f2", 0644);
+
+    RE(atf_fs_path_init_fmt(&p, "f1"));
+    RE(atf_fs_stat_init(&st, &p));
+    ATF_CHECK_EQ(0400, atf_fs_stat_get_mode(&st));
+    atf_fs_stat_fini(&st);
+    atf_fs_path_fini(&p);
+
+    RE(atf_fs_path_init_fmt(&p, "f2"));
+    RE(atf_fs_stat_init(&st, &p));
+    ATF_CHECK_EQ(0644, atf_fs_stat_get_mode(&st));
+    atf_fs_stat_fini(&st);
+    atf_fs_path_fini(&p);
+}
+
+ATF_TC(stat_type);
+ATF_TC_HEAD(stat_type, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_get_type function "
+                      "and, indirectly, the constructor");
+}
+ATF_TC_BODY(stat_type, tc)
+{
+    atf_fs_path_t p;
+    atf_fs_stat_t st;
+
+    create_dir("dir", 0755);
+    create_file("reg", 0644);
+
+    RE(atf_fs_path_init_fmt(&p, "dir"));
+    RE(atf_fs_stat_init(&st, &p));
+    ATF_REQUIRE_EQ(atf_fs_stat_get_type(&st), atf_fs_stat_dir_type);
+    atf_fs_stat_fini(&st);
+    atf_fs_path_fini(&p);
+
+    RE(atf_fs_path_init_fmt(&p, "reg"));
+    RE(atf_fs_stat_init(&st, &p));
+    ATF_REQUIRE_EQ(atf_fs_stat_get_type(&st), atf_fs_stat_reg_type);
+    atf_fs_stat_fini(&st);
+    atf_fs_path_fini(&p);
+}
+
+ATF_TC(stat_perms);
+ATF_TC_HEAD(stat_perms, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_stat_is_* functions");
+}
+ATF_TC_BODY(stat_perms, tc)
+{
+    atf_fs_path_t p;
+    atf_fs_stat_t st;
+
+    create_file("reg", 0);
+
+    RE(atf_fs_path_init_fmt(&p, "reg"));
+
+#define perms(ur, uw, ux, gr, gw, gx, othr, othw, othx) \
+    { \
+        RE(atf_fs_stat_init(&st, &p)); \
+        ATF_REQUIRE(atf_fs_stat_is_owner_readable(&st) == ur); \
+        ATF_REQUIRE(atf_fs_stat_is_owner_writable(&st) == uw); \
+        ATF_REQUIRE(atf_fs_stat_is_owner_executable(&st) == ux); \
+        ATF_REQUIRE(atf_fs_stat_is_group_readable(&st) == gr); \
+        ATF_REQUIRE(atf_fs_stat_is_group_writable(&st) == gw); \
+        ATF_REQUIRE(atf_fs_stat_is_group_executable(&st) == gx); \
+        ATF_REQUIRE(atf_fs_stat_is_other_readable(&st) == othr); \
+        ATF_REQUIRE(atf_fs_stat_is_other_writable(&st) == othw); \
+        ATF_REQUIRE(atf_fs_stat_is_other_executable(&st) == othx); \
+        atf_fs_stat_fini(&st); \
+    }
+
+    chmod("reg", 0000);
+    perms(false, false, false, false, false, false, false, false, false);
+
+    chmod("reg", 0001);
+    perms(false, false, false, false, false, false, false, false, true);
+
+    chmod("reg", 0010);
+    perms(false, false, false, false, false, true, false, false, false);
+
+    chmod("reg", 0100);
+    perms(false, false, true, false, false, false, false, false, false);
+
+    chmod("reg", 0002);
+    perms(false, false, false, false, false, false, false, true, false);
+
+    chmod("reg", 0020);
+    perms(false, false, false, false, true, false, false, false, false);
+
+    chmod("reg", 0200);
+    perms(false, true, false, false, false, false, false, false, false);
+
+    chmod("reg", 0004);
+    perms(false, false, false, false, false, false, true, false, false);
+
+    chmod("reg", 0040);
+    perms(false, false, false, true, false, false, false, false, false);
+
+    chmod("reg", 0400);
+    perms(true, false, false, false, false, false, false, false, false);
+
+    chmod("reg", 0644);
+    perms(true, true, false, true, false, false, true, false, false);
+
+    chmod("reg", 0755);
+    perms(true, true, true, true, false, true, true, false, true);
+
+    chmod("reg", 0777);
+    perms(true, true, true, true, true, true, true, true, true);
+
+#undef perms
+
+    atf_fs_path_fini(&p);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(exists);
+ATF_TC_HEAD(exists, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_exists function");
+}
+ATF_TC_BODY(exists, tc)
+{
+    atf_error_t err;
+    atf_fs_path_t pdir, pfile;
+    bool b;
+
+    RE(atf_fs_path_init_fmt(&pdir, "dir"));
+    RE(atf_fs_path_init_fmt(&pfile, "dir/file"));
+
+    create_dir(atf_fs_path_cstring(&pdir), 0755);
+    create_file(atf_fs_path_cstring(&pfile), 0644);
+
+    printf("Checking existence of a directory\n");
+    RE(atf_fs_exists(&pdir, &b));
+    ATF_REQUIRE(b);
+
+    printf("Checking existence of a file\n");
+    RE(atf_fs_exists(&pfile, &b));
+    ATF_REQUIRE(b);
+
+    /* XXX: This should probably be a separate test case to let the user
+     * be aware that some tests were skipped because privileges were not
+     * correct. */
+    if (!atf_user_is_root()) {
+        printf("Checking existence of a file inside a directory without "
+               "permissions\n");
+        ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0000) != -1);
+        err = atf_fs_exists(&pfile, &b);
+        ATF_REQUIRE(atf_is_error(err));
+        ATF_REQUIRE(atf_error_is(err, "libc"));
+        ATF_REQUIRE(chmod(atf_fs_path_cstring(&pdir), 0755) != -1);
+        atf_error_free(err);
+    }
+
+    printf("Checking existence of a non-existent file\n");
+    ATF_REQUIRE(unlink(atf_fs_path_cstring(&pfile)) != -1);
+    RE(atf_fs_exists(&pfile, &b));
+    ATF_REQUIRE(!b);
+
+    atf_fs_path_fini(&pfile);
+    atf_fs_path_fini(&pdir);
+}
+
+ATF_TC(eaccess);
+ATF_TC_HEAD(eaccess, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_eaccess function");
+}
+ATF_TC_BODY(eaccess, tc)
+{
+    const int modes[] = { atf_fs_access_f, atf_fs_access_r, atf_fs_access_w,
+                          atf_fs_access_x, 0 };
+    const int *m;
+    struct tests {
+        mode_t fmode;
+        int amode;
+        int uerror;
+        int rerror;
+    } tests[] = {
+        { 0000, atf_fs_access_r, EACCES, 0 },
+        { 0000, atf_fs_access_w, EACCES, 0 },
+        { 0000, atf_fs_access_x, EACCES, EACCES },
+
+        { 0001, atf_fs_access_r, EACCES, 0 },
+        { 0001, atf_fs_access_w, EACCES, 0 },
+        { 0001, atf_fs_access_x, EACCES, 0 },
+        { 0002, atf_fs_access_r, EACCES, 0 },
+        { 0002, atf_fs_access_w, EACCES, 0 },
+        { 0002, atf_fs_access_x, EACCES, EACCES },
+        { 0004, atf_fs_access_r, EACCES, 0 },
+        { 0004, atf_fs_access_w, EACCES, 0 },
+        { 0004, atf_fs_access_x, EACCES, EACCES },
+
+        { 0010, atf_fs_access_r, EACCES, 0 },
+        { 0010, atf_fs_access_w, EACCES, 0 },
+        { 0010, atf_fs_access_x, 0,      0 },
+        { 0020, atf_fs_access_r, EACCES, 0 },
+        { 0020, atf_fs_access_w, 0,      0 },
+        { 0020, atf_fs_access_x, EACCES, EACCES },
+        { 0040, atf_fs_access_r, 0,      0 },
+        { 0040, atf_fs_access_w, EACCES, 0 },
+        { 0040, atf_fs_access_x, EACCES, EACCES },
+
+        { 0100, atf_fs_access_r, EACCES, 0 },
+        { 0100, atf_fs_access_w, EACCES, 0 },
+        { 0100, atf_fs_access_x, 0,      0 },
+        { 0200, atf_fs_access_r, EACCES, 0 },
+        { 0200, atf_fs_access_w, 0,      0 },
+        { 0200, atf_fs_access_x, EACCES, EACCES },
+        { 0400, atf_fs_access_r, 0,      0 },
+        { 0400, atf_fs_access_w, EACCES, 0 },
+        { 0400, atf_fs_access_x, EACCES, EACCES },
+
+        { 0, 0, 0, 0 }
+    };
+    struct tests *t;
+    atf_fs_path_t p;
+    atf_error_t err;
+
+    RE(atf_fs_path_init_fmt(&p, "the-file"));
+
+    printf("Non-existent file checks\n");
+    for (m = &modes[0]; *m != 0; m++) {
+        err = atf_fs_eaccess(&p, *m);
+        ATF_REQUIRE(atf_is_error(err));
+        ATF_REQUIRE(atf_error_is(err, "libc"));
+        ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOENT);
+        atf_error_free(err);
+    }
+
+    create_file(atf_fs_path_cstring(&p), 0000);
+    ATF_REQUIRE(chown(atf_fs_path_cstring(&p), geteuid(), getegid()) != -1);
+
+    for (t = &tests[0]; t->amode != 0; t++) {
+        const int experr = atf_user_is_root() ? t->rerror : t->uerror;
+
+        printf("\n");
+        printf("File mode     : %04o\n", (unsigned int)t->fmode);
+        printf("Access mode   : 0x%02x\n", t->amode);
+
+        ATF_REQUIRE(chmod(atf_fs_path_cstring(&p), t->fmode) != -1);
+
+        /* First, existence check. */
+        err = atf_fs_eaccess(&p, atf_fs_access_f);
+        ATF_REQUIRE(!atf_is_error(err));
+
+        /* Now do the specific test case. */
+        printf("Expected error: %d\n", experr);
+        err = atf_fs_eaccess(&p, t->amode);
+        if (atf_is_error(err)) {
+            if (atf_error_is(err, "libc"))
+                printf("Error         : %d\n", atf_libc_error_code(err));
+            else
+                printf("Error         : Non-libc error\n");
+        } else
+                printf("Error         : None\n");
+        if (experr == 0) {
+            ATF_REQUIRE(!atf_is_error(err));
+        } else {
+            ATF_REQUIRE(atf_is_error(err));
+            ATF_REQUIRE(atf_error_is(err, "libc"));
+            ATF_REQUIRE_EQ(atf_libc_error_code(err), experr);
+            atf_error_free(err);
+        }
+    }
+
+    atf_fs_path_fini(&p);
+}
+
+ATF_TC(getcwd);
+ATF_TC_HEAD(getcwd, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_getcwd function");
+}
+ATF_TC_BODY(getcwd, tc)
+{
+    atf_fs_path_t cwd1, cwd2;
+
+    create_dir ("root", 0755);
+
+    RE(atf_fs_getcwd(&cwd1));
+    ATF_REQUIRE(chdir("root") != -1);
+    RE(atf_fs_getcwd(&cwd2));
+
+    RE(atf_fs_path_append_fmt(&cwd1, "root"));
+
+    ATF_REQUIRE(atf_equal_fs_path_fs_path(&cwd1, &cwd2));
+
+    atf_fs_path_fini(&cwd2);
+    atf_fs_path_fini(&cwd1);
+}
+
+ATF_TC(rmdir_empty);
+ATF_TC_HEAD(rmdir_empty, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");
+}
+ATF_TC_BODY(rmdir_empty, tc)
+{
+    atf_fs_path_t p;
+
+    RE(atf_fs_path_init_fmt(&p, "test-dir"));
+
+    ATF_REQUIRE(mkdir("test-dir", 0755) != -1);
+    ATF_REQUIRE(exists(&p));
+    RE(atf_fs_rmdir(&p));
+    ATF_REQUIRE(!exists(&p));
+
+    atf_fs_path_fini(&p);
+}
+
+ATF_TC(rmdir_enotempty);
+ATF_TC_HEAD(rmdir_enotempty, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");
+}
+ATF_TC_BODY(rmdir_enotempty, tc)
+{
+    atf_fs_path_t p;
+    atf_error_t err;
+
+    RE(atf_fs_path_init_fmt(&p, "test-dir"));
+
+    ATF_REQUIRE(mkdir("test-dir", 0755) != -1);
+    ATF_REQUIRE(exists(&p));
+    create_file("test-dir/foo", 0644);
+
+    err = atf_fs_rmdir(&p);
+    ATF_REQUIRE(atf_is_error(err));
+    ATF_REQUIRE(atf_error_is(err, "libc"));
+    ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOTEMPTY);
+    atf_error_free(err);
+
+    atf_fs_path_fini(&p);
+}
+
+ATF_TC(rmdir_eperm);
+ATF_TC_HEAD(rmdir_eperm, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_rmdir function");
+}
+ATF_TC_BODY(rmdir_eperm, tc)
+{
+    atf_fs_path_t p;
+    atf_error_t err;
+
+    RE(atf_fs_path_init_fmt(&p, "test-dir/foo"));
+
+    ATF_REQUIRE(mkdir("test-dir", 0755) != -1);
+    ATF_REQUIRE(mkdir("test-dir/foo", 0755) != -1);
+    ATF_REQUIRE(chmod("test-dir", 0555) != -1);
+    ATF_REQUIRE(exists(&p));
+
+    err = atf_fs_rmdir(&p);
+    if (atf_user_is_root()) {
+        ATF_REQUIRE(!atf_is_error(err));
+    } else {
+        ATF_REQUIRE(atf_is_error(err));
+        ATF_REQUIRE(atf_error_is(err, "libc"));
+        ATF_REQUIRE_EQ(atf_libc_error_code(err), EACCES);
+        atf_error_free(err);
+    }
+
+    atf_fs_path_fini(&p);
+}
+
+ATF_TC(mkdtemp_ok);
+ATF_TC_HEAD(mkdtemp_ok, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, "
+                      "successful execution");
+}
+ATF_TC_BODY(mkdtemp_ok, tc)
+{
+    atf_fs_path_t p1, p2;
+    atf_fs_stat_t s1, s2;
+
+    RE(atf_fs_path_init_fmt(&p1, "testdir.XXXXXX"));
+    RE(atf_fs_path_init_fmt(&p2, "testdir.XXXXXX"));
+    RE(atf_fs_mkdtemp(&p1));
+    RE(atf_fs_mkdtemp(&p2));
+    ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2));
+    ATF_REQUIRE(exists(&p1));
+    ATF_REQUIRE(exists(&p2));
+
+    RE(atf_fs_stat_init(&s1, &p1));
+    ATF_REQUIRE_EQ(atf_fs_stat_get_type(&s1), atf_fs_stat_dir_type);
+    ATF_REQUIRE( atf_fs_stat_is_owner_readable(&s1));
+    ATF_REQUIRE( atf_fs_stat_is_owner_writable(&s1));
+    ATF_REQUIRE( atf_fs_stat_is_owner_executable(&s1));
+    ATF_REQUIRE(!atf_fs_stat_is_group_readable(&s1));
+    ATF_REQUIRE(!atf_fs_stat_is_group_writable(&s1));
+    ATF_REQUIRE(!atf_fs_stat_is_group_executable(&s1));
+    ATF_REQUIRE(!atf_fs_stat_is_other_readable(&s1));
+    ATF_REQUIRE(!atf_fs_stat_is_other_writable(&s1));
+    ATF_REQUIRE(!atf_fs_stat_is_other_executable(&s1));
+
+    RE(atf_fs_stat_init(&s2, &p2));
+    ATF_REQUIRE_EQ(atf_fs_stat_get_type(&s2), atf_fs_stat_dir_type);
+    ATF_REQUIRE( atf_fs_stat_is_owner_readable(&s2));
+    ATF_REQUIRE( atf_fs_stat_is_owner_writable(&s2));
+    ATF_REQUIRE( atf_fs_stat_is_owner_executable(&s2));
+    ATF_REQUIRE(!atf_fs_stat_is_group_readable(&s2));
+    ATF_REQUIRE(!atf_fs_stat_is_group_writable(&s2));
+    ATF_REQUIRE(!atf_fs_stat_is_group_executable(&s2));
+    ATF_REQUIRE(!atf_fs_stat_is_other_readable(&s2));
+    ATF_REQUIRE(!atf_fs_stat_is_other_writable(&s2));
+    ATF_REQUIRE(!atf_fs_stat_is_other_executable(&s2));
+
+    atf_fs_stat_fini(&s2);
+    atf_fs_stat_fini(&s1);
+    atf_fs_path_fini(&p2);
+    atf_fs_path_fini(&p1);
+}
+
+ATF_TC(mkdtemp_err);
+ATF_TC_HEAD(mkdtemp_err, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function, "
+                      "error conditions");
+    atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+ATF_TC_BODY(mkdtemp_err, tc)
+{
+    atf_error_t err;
+    atf_fs_path_t p;
+
+    ATF_REQUIRE(mkdir("dir", 0555) != -1);
+
+    RE(atf_fs_path_init_fmt(&p, "dir/testdir.XXXXXX"));
+
+    err = atf_fs_mkdtemp(&p);
+    ATF_REQUIRE(atf_is_error(err));
+    ATF_REQUIRE(atf_error_is(err, "libc"));
+    ATF_CHECK_EQ(atf_libc_error_code(err), EACCES);
+    atf_error_free(err);
+
+    ATF_CHECK(!exists(&p));
+    ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testdir.XXXXXX") == 0);
+
+    atf_fs_path_fini(&p);
+}
+
+static
+void
+do_umask_check(atf_error_t (*const mk_func)(atf_fs_path_t *),
+               atf_fs_path_t *path, const mode_t test_mask,
+               const char *str_mask, const char *exp_name)
+{
+    char buf[1024];
+    int old_umask;
+    atf_error_t err;
+
+    printf("Creating temporary %s with umask %s\n", exp_name, str_mask);
+
+    old_umask = umask(test_mask);
+    err = mk_func(path);
+    (void)umask(old_umask);
+
+    ATF_REQUIRE(atf_is_error(err));
+    ATF_REQUIRE(atf_error_is(err, "invalid_umask"));
+    atf_error_format(err, buf, sizeof(buf));
+    ATF_CHECK(strstr(buf, exp_name) != NULL);
+    ATF_CHECK(strstr(buf, str_mask) != NULL);
+    atf_error_free(err);
+}
+
+ATF_TC(mkdtemp_umask);
+ATF_TC_HEAD(mkdtemp_umask, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkdtemp function "
+                      "causing an error due to a too strict umask");
+}
+ATF_TC_BODY(mkdtemp_umask, tc)
+{
+    atf_fs_path_t p;
+
+    RE(atf_fs_path_init_fmt(&p, "testdir.XXXXXX"));
+
+    do_umask_check(atf_fs_mkdtemp, &p, 00100, "00100", "directory");
+    do_umask_check(atf_fs_mkdtemp, &p, 00200, "00200", "directory");
+    do_umask_check(atf_fs_mkdtemp, &p, 00400, "00400", "directory");
+    do_umask_check(atf_fs_mkdtemp, &p, 00500, "00500", "directory");
+    do_umask_check(atf_fs_mkdtemp, &p, 00600, "00600", "directory");
+
+    atf_fs_path_fini(&p);
+}
+
+ATF_TC(mkstemp_ok);
+ATF_TC_HEAD(mkstemp_ok, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, "
+                      "successful execution");
+}
+ATF_TC_BODY(mkstemp_ok, tc)
+{
+    int fd1, fd2;
+    atf_fs_path_t p1, p2;
+    atf_fs_stat_t s1, s2;
+
+    RE(atf_fs_path_init_fmt(&p1, "testfile.XXXXXX"));
+    RE(atf_fs_path_init_fmt(&p2, "testfile.XXXXXX"));
+    fd1 = fd2 = -1;
+    RE(atf_fs_mkstemp(&p1, &fd1));
+    RE(atf_fs_mkstemp(&p2, &fd2));
+    ATF_REQUIRE(!atf_equal_fs_path_fs_path(&p1, &p2));
+    ATF_REQUIRE(exists(&p1));
+    ATF_REQUIRE(exists(&p2));
+
+    ATF_CHECK(fd1 != -1);
+    ATF_CHECK(fd2 != -1);
+    ATF_CHECK(write(fd1, "foo", 3) == 3);
+    ATF_CHECK(write(fd2, "bar", 3) == 3);
+    close(fd1);
+    close(fd2);
+
+    RE(atf_fs_stat_init(&s1, &p1));
+    ATF_CHECK_EQ(atf_fs_stat_get_type(&s1), atf_fs_stat_reg_type);
+    ATF_CHECK( atf_fs_stat_is_owner_readable(&s1));
+    ATF_CHECK( atf_fs_stat_is_owner_writable(&s1));
+    ATF_CHECK(!atf_fs_stat_is_owner_executable(&s1));
+    ATF_CHECK(!atf_fs_stat_is_group_readable(&s1));
+    ATF_CHECK(!atf_fs_stat_is_group_writable(&s1));
+    ATF_CHECK(!atf_fs_stat_is_group_executable(&s1));
+    ATF_CHECK(!atf_fs_stat_is_other_readable(&s1));
+    ATF_CHECK(!atf_fs_stat_is_other_writable(&s1));
+    ATF_CHECK(!atf_fs_stat_is_other_executable(&s1));
+
+    RE(atf_fs_stat_init(&s2, &p2));
+    ATF_CHECK_EQ(atf_fs_stat_get_type(&s2), atf_fs_stat_reg_type);
+    ATF_CHECK( atf_fs_stat_is_owner_readable(&s2));
+    ATF_CHECK( atf_fs_stat_is_owner_writable(&s2));
+    ATF_CHECK(!atf_fs_stat_is_owner_executable(&s2));
+    ATF_CHECK(!atf_fs_stat_is_group_readable(&s2));
+    ATF_CHECK(!atf_fs_stat_is_group_writable(&s2));
+    ATF_CHECK(!atf_fs_stat_is_group_executable(&s2));
+    ATF_CHECK(!atf_fs_stat_is_other_readable(&s2));
+    ATF_CHECK(!atf_fs_stat_is_other_writable(&s2));
+    ATF_CHECK(!atf_fs_stat_is_other_executable(&s2));
+
+    atf_fs_stat_fini(&s2);
+    atf_fs_stat_fini(&s1);
+    atf_fs_path_fini(&p2);
+    atf_fs_path_fini(&p1);
+}
+
+ATF_TC(mkstemp_err);
+ATF_TC_HEAD(mkstemp_err, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function, "
+                      "error conditions");
+    atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+ATF_TC_BODY(mkstemp_err, tc)
+{
+    int fd;
+    atf_error_t err;
+    atf_fs_path_t p;
+
+    ATF_REQUIRE(mkdir("dir", 0555) != -1);
+
+    RE(atf_fs_path_init_fmt(&p, "dir/testfile.XXXXXX"));
+    fd = 1234;
+
+    err = atf_fs_mkstemp(&p, &fd);
+    ATF_REQUIRE(atf_is_error(err));
+    ATF_REQUIRE(atf_error_is(err, "libc"));
+    ATF_CHECK_EQ(atf_libc_error_code(err), EACCES);
+    atf_error_free(err);
+
+    ATF_CHECK(!exists(&p));
+    ATF_CHECK(strcmp(atf_fs_path_cstring(&p), "dir/testfile.XXXXXX") == 0);
+    ATF_CHECK_EQ(fd, 1234);
+
+    atf_fs_path_fini(&p);
+}
+
+ATF_TC(mkstemp_umask);
+ATF_TC_HEAD(mkstemp_umask, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_fs_mkstemp function "
+                      "causing an error due to a too strict umask");
+}
+ATF_TC_BODY(mkstemp_umask, tc)
+{
+    atf_fs_path_t p;
+
+    RE(atf_fs_path_init_fmt(&p, "testfile.XXXXXX"));
+
+    do_umask_check(mkstemp_discard_fd, &p, 00100, "00100", "regular file");
+    do_umask_check(mkstemp_discard_fd, &p, 00200, "00200", "regular file");
+    do_umask_check(mkstemp_discard_fd, &p, 00400, "00400", "regular file");
+
+    atf_fs_path_fini(&p);
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    /* Add the tests for the "atf_fs_path" type. */
+    ATF_TP_ADD_TC(tp, path_normalize);
+    ATF_TP_ADD_TC(tp, path_copy);
+    ATF_TP_ADD_TC(tp, path_is_absolute);
+    ATF_TP_ADD_TC(tp, path_is_root);
+    ATF_TP_ADD_TC(tp, path_branch_path);
+    ATF_TP_ADD_TC(tp, path_leaf_name);
+    ATF_TP_ADD_TC(tp, path_append);
+    ATF_TP_ADD_TC(tp, path_to_absolute);
+    ATF_TP_ADD_TC(tp, path_equal);
+
+    /* Add the tests for the "atf_fs_stat" type. */
+    ATF_TP_ADD_TC(tp, stat_mode);
+    ATF_TP_ADD_TC(tp, stat_type);
+    ATF_TP_ADD_TC(tp, stat_perms);
+
+    /* Add the tests for the free functions. */
+    ATF_TP_ADD_TC(tp, eaccess);
+    ATF_TP_ADD_TC(tp, exists);
+    ATF_TP_ADD_TC(tp, getcwd);
+    ATF_TP_ADD_TC(tp, rmdir_empty);
+    ATF_TP_ADD_TC(tp, rmdir_enotempty);
+    ATF_TP_ADD_TC(tp, rmdir_eperm);
+    ATF_TP_ADD_TC(tp, mkdtemp_ok);
+    ATF_TP_ADD_TC(tp, mkdtemp_err);
+    ATF_TP_ADD_TC(tp, mkdtemp_umask);
+    ATF_TP_ADD_TC(tp, mkstemp_ok);
+    ATF_TP_ADD_TC(tp, mkstemp_err);
+    ATF_TP_ADD_TC(tp, mkstemp_umask);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/detail/list.c
===================================================================
--- vendor/atf/dist/atf-c/detail/list.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/list.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,388 @@
+/* Copyright (c) 2008 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/list.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "atf-c/detail/sanity.h"
+#include "atf-c/error.h"
+#include "atf-c/utils.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+struct list_entry {
+    struct list_entry *m_prev;
+    struct list_entry *m_next;
+    void *m_object;
+    bool m_managed;
+};
+
+static
+atf_list_citer_t
+entry_to_citer(const atf_list_t *l, const struct list_entry *le)
+{
+    atf_list_citer_t iter;
+    iter.m_list = l;
+    iter.m_entry = le;
+    return iter;
+}
+
+static
+atf_list_iter_t
+entry_to_iter(atf_list_t *l, struct list_entry *le)
+{
+    atf_list_iter_t iter;
+    iter.m_list = l;
+    iter.m_entry = le;
+    return iter;
+}
+
+static
+struct list_entry *
+new_entry(void *object, bool managed)
+{
+    struct list_entry *le;
+
+    le = (struct list_entry *)malloc(sizeof(*le));
+    if (le != NULL) {
+        le->m_prev = le->m_next = NULL;
+        le->m_object = object;
+        le->m_managed = managed;
+    } else
+        free(object);
+
+    return le;
+}
+
+static
+void
+delete_entry(struct list_entry *le)
+{
+    if (le->m_managed)
+        free(le->m_object);
+
+    free(le);
+}
+
+static
+struct list_entry *
+new_entry_and_link(void *object, bool managed, struct list_entry *prev,
+                   struct list_entry *next)
+{
+    struct list_entry *le;
+
+    le = new_entry(object, managed);
+    if (le != NULL) {
+        le->m_prev = prev;
+        le->m_next = next;
+
+        prev->m_next = le;
+        next->m_prev = le;
+    }
+
+    return le;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_list_citer" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Getters.
+ */
+
+const void *
+atf_list_citer_data(const atf_list_citer_t citer)
+{
+    const struct list_entry *le = citer.m_entry;
+    PRE(le != NULL);
+    return le->m_object;
+}
+
+atf_list_citer_t
+atf_list_citer_next(const atf_list_citer_t citer)
+{
+    const struct list_entry *le = citer.m_entry;
+    atf_list_citer_t newciter;
+
+    PRE(le != NULL);
+
+    newciter = citer;
+    newciter.m_entry = le->m_next;
+
+    return newciter;
+}
+
+bool
+atf_equal_list_citer_list_citer(const atf_list_citer_t i1,
+                                const atf_list_citer_t i2)
+{
+    return i1.m_list == i2.m_list && i1.m_entry == i2.m_entry;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_list_iter" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Getters.
+ */
+
+void *
+atf_list_iter_data(const atf_list_iter_t iter)
+{
+    const struct list_entry *le = iter.m_entry;
+    PRE(le != NULL);
+    return le->m_object;
+}
+
+atf_list_iter_t
+atf_list_iter_next(const atf_list_iter_t iter)
+{
+    const struct list_entry *le = iter.m_entry;
+    atf_list_iter_t newiter;
+
+    PRE(le != NULL);
+
+    newiter = iter;
+    newiter.m_entry = le->m_next;
+
+    return newiter;
+}
+
+bool
+atf_equal_list_iter_list_iter(const atf_list_iter_t i1,
+                              const atf_list_iter_t i2)
+{
+    return i1.m_list == i2.m_list && i1.m_entry == i2.m_entry;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_list" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constructors and destructors.
+ */
+
+atf_error_t
+atf_list_init(atf_list_t *l)
+{
+    struct list_entry *lebeg, *leend;
+
+    lebeg = new_entry(NULL, false);
+    if (lebeg == NULL) {
+        return atf_no_memory_error();
+    }
+
+    leend = new_entry(NULL, false);
+    if (leend == NULL) {
+        free(lebeg);
+        return atf_no_memory_error();
+    }
+
+    lebeg->m_next = leend;
+    lebeg->m_prev = NULL;
+
+    leend->m_next = NULL;
+    leend->m_prev = lebeg;
+
+    l->m_size = 0;
+    l->m_begin = lebeg;
+    l->m_end = leend;
+
+    return atf_no_error();
+}
+
+void
+atf_list_fini(atf_list_t *l)
+{
+    struct list_entry *le;
+    size_t freed;
+
+    le = (struct list_entry *)l->m_begin;
+    freed = 0;
+    while (le != NULL) {
+        struct list_entry *lenext;
+
+        lenext = le->m_next;
+        delete_entry(le);
+        le = lenext;
+
+        freed++;
+    }
+    INV(freed == l->m_size + 2);
+}
+
+/*
+ * Getters.
+ */
+
+atf_list_iter_t
+atf_list_begin(atf_list_t *l)
+{
+    struct list_entry *le = l->m_begin;
+    return entry_to_iter(l, le->m_next);
+}
+
+atf_list_citer_t
+atf_list_begin_c(const atf_list_t *l)
+{
+    const struct list_entry *le = l->m_begin;
+    return entry_to_citer(l, le->m_next);
+}
+
+atf_list_iter_t
+atf_list_end(atf_list_t *l)
+{
+    return entry_to_iter(l, l->m_end);
+}
+
+atf_list_citer_t
+atf_list_end_c(const atf_list_t *l)
+{
+    return entry_to_citer(l, l->m_end);
+}
+
+void *
+atf_list_index(atf_list_t *list, const size_t idx)
+{
+    atf_list_iter_t iter;
+
+    PRE(idx < atf_list_size(list));
+
+    iter = atf_list_begin(list);
+    {
+        size_t pos = 0;
+        while (pos < idx &&
+               !atf_equal_list_iter_list_iter((iter), atf_list_end(list))) {
+            iter = atf_list_iter_next(iter);
+            pos++;
+        }
+    }
+    return atf_list_iter_data(iter);
+}
+
+const void *
+atf_list_index_c(const atf_list_t *list, const size_t idx)
+{
+    atf_list_citer_t iter;
+
+    PRE(idx < atf_list_size(list));
+
+    iter = atf_list_begin_c(list);
+    {
+        size_t pos = 0;
+        while (pos < idx &&
+               !atf_equal_list_citer_list_citer((iter),
+                                                atf_list_end_c(list))) {
+            iter = atf_list_citer_next(iter);
+            pos++;
+        }
+    }
+    return atf_list_citer_data(iter);
+}
+
+size_t
+atf_list_size(const atf_list_t *l)
+{
+    return l->m_size;
+}
+
+char **
+atf_list_to_charpp(const atf_list_t *l)
+{
+    char **array;
+    atf_list_citer_t iter;
+    size_t i;
+
+    array = malloc(sizeof(char *) * (atf_list_size(l) + 1));
+    if (array == NULL)
+        goto out;
+
+    i = 0;
+    atf_list_for_each_c(iter, l) {
+        array[i] = strdup((const char *)atf_list_citer_data(iter));
+        if (array[i] == NULL) {
+            atf_utils_free_charpp(array);
+            array = NULL;
+            goto out;
+        }
+
+        i++;
+    }
+    array[i] = NULL;
+
+out:
+    return array;
+}
+
+/*
+ * Modifiers.
+ */
+
+atf_error_t
+atf_list_append(atf_list_t *l, void *data, bool managed)
+{
+    struct list_entry *le, *next, *prev;
+    atf_error_t err;
+
+    next = (struct list_entry *)l->m_end;
+    prev = next->m_prev;
+    le = new_entry_and_link(data, managed, prev, next);
+    if (le == NULL)
+        err = atf_no_memory_error();
+    else {
+        l->m_size++;
+        err = atf_no_error();
+    }
+
+    return err;
+}
+
+void
+atf_list_append_list(atf_list_t *l, atf_list_t *src)
+{
+    struct list_entry *e1, *e2, *ghost1, *ghost2;
+
+    ghost1 = (struct list_entry *)l->m_end;
+    ghost2 = (struct list_entry *)src->m_begin;
+
+    e1 = ghost1->m_prev;
+    e2 = ghost2->m_next;
+
+    delete_entry(ghost1);
+    delete_entry(ghost2);
+
+    e1->m_next = e2;
+    e2->m_prev = e1;
+
+    l->m_end = src->m_end;
+    l->m_size += src->m_size;
+}

Added: vendor/atf/dist/atf-c/detail/list.h
===================================================================
--- vendor/atf/dist/atf-c/detail/list.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/list.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,111 @@
+/* Copyright (c) 2008 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_C_DETAIL_LIST_H)
+#define ATF_C_DETAIL_LIST_H
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#include <atf-c/error_fwd.h>
+
+/* ---------------------------------------------------------------------
+ * The "atf_list_citer" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_list_citer {
+    const struct atf_list *m_list;
+    const void *m_entry;
+};
+typedef struct atf_list_citer atf_list_citer_t;
+
+/* Getters. */
+const void *atf_list_citer_data(const atf_list_citer_t);
+atf_list_citer_t atf_list_citer_next(const atf_list_citer_t);
+
+/* Operators. */
+bool atf_equal_list_citer_list_citer(const atf_list_citer_t,
+                                     const atf_list_citer_t);
+
+/* ---------------------------------------------------------------------
+ * The "atf_list_iter" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_list_iter {
+    struct atf_list *m_list;
+    void *m_entry;
+};
+typedef struct atf_list_iter atf_list_iter_t;
+
+/* Getters. */
+void *atf_list_iter_data(const atf_list_iter_t);
+atf_list_iter_t atf_list_iter_next(const atf_list_iter_t);
+
+/* Operators. */
+bool atf_equal_list_iter_list_iter(const atf_list_iter_t,
+                                   const atf_list_iter_t);
+
+/* ---------------------------------------------------------------------
+ * The "atf_list" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_list {
+    void *m_begin;
+    void *m_end;
+
+    size_t m_size;
+};
+typedef struct atf_list atf_list_t;
+
+/* Constructors and destructors */
+atf_error_t atf_list_init(atf_list_t *);
+void atf_list_fini(atf_list_t *);
+
+/* Getters. */
+atf_list_iter_t atf_list_begin(atf_list_t *);
+atf_list_citer_t atf_list_begin_c(const atf_list_t *);
+atf_list_iter_t atf_list_end(atf_list_t *);
+atf_list_citer_t atf_list_end_c(const atf_list_t *);
+void *atf_list_index(atf_list_t *, const size_t);
+const void *atf_list_index_c(const atf_list_t *, const size_t);
+size_t atf_list_size(const atf_list_t *);
+char **atf_list_to_charpp(const atf_list_t *);
+
+/* Modifiers. */
+atf_error_t atf_list_append(atf_list_t *, void *, bool);
+void atf_list_append_list(atf_list_t *, atf_list_t *);
+
+/* Macros. */
+#define atf_list_for_each(iter, list) \
+    for (iter = atf_list_begin(list); \
+         !atf_equal_list_iter_list_iter((iter), atf_list_end(list)); \
+         iter = atf_list_iter_next(iter))
+#define atf_list_for_each_c(iter, list) \
+    for (iter = atf_list_begin_c(list); \
+         !atf_equal_list_citer_list_citer((iter), atf_list_end_c(list)); \
+         iter = atf_list_citer_next(iter))
+
+#endif /* !defined(ATF_C_DETAIL_LIST_H) */

Added: vendor/atf/dist/atf-c/detail/list_test.c
===================================================================
--- vendor/atf/dist/atf-c/detail/list_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/list_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,365 @@
+/* Copyright (c) 2008 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/list.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/test_helpers.h"
+#include "atf-c/utils.h"
+
+/* ---------------------------------------------------------------------
+ * Tests for the "atf_list" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constructors and destructors.
+ */
+
+ATF_TC(list_init);
+ATF_TC_HEAD(list_init, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_init function");
+}
+ATF_TC_BODY(list_init, tc)
+{
+    atf_list_t list;
+
+    RE(atf_list_init(&list));
+    ATF_REQUIRE_EQ(atf_list_size(&list), 0);
+    atf_list_fini(&list);
+}
+
+/*
+ * Getters.
+ */
+
+ATF_TC(list_index);
+ATF_TC_HEAD(list_index, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_index function");
+}
+ATF_TC_BODY(list_index, tc)
+{
+    atf_list_t list;
+    int i1 = 1;
+    int i2 = 5;
+    int i3 = 9;
+
+    RE(atf_list_init(&list));
+    RE(atf_list_append(&list, &i1, false));
+    RE(atf_list_append(&list, &i2, false));
+    RE(atf_list_append(&list, &i3, false));
+
+    ATF_CHECK_EQ(*(int *)atf_list_index(&list, 0), 1);
+    ATF_CHECK_EQ(*(int *)atf_list_index(&list, 1), 5);
+    ATF_CHECK_EQ(*(int *)atf_list_index(&list, 2), 9);
+
+    atf_list_fini(&list);
+}
+
+ATF_TC(list_index_c);
+ATF_TC_HEAD(list_index_c, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_index_c function");
+}
+ATF_TC_BODY(list_index_c, tc)
+{
+    atf_list_t list;
+    int i1 = 1;
+    int i2 = 5;
+    int i3 = 9;
+
+    RE(atf_list_init(&list));
+    RE(atf_list_append(&list, &i1, false));
+    RE(atf_list_append(&list, &i2, false));
+    RE(atf_list_append(&list, &i3, false));
+
+    ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 0), 1);
+    ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 1), 5);
+    ATF_CHECK_EQ(*(const int *)atf_list_index_c(&list, 2), 9);
+
+    atf_list_fini(&list);
+}
+
+ATF_TC_WITHOUT_HEAD(list_to_charpp_empty);
+ATF_TC_BODY(list_to_charpp_empty, tc)
+{
+    atf_list_t list;
+    char **array;
+
+    RE(atf_list_init(&list));
+    ATF_REQUIRE((array = atf_list_to_charpp(&list)) != NULL);
+    atf_list_fini(&list);
+
+    ATF_CHECK_EQ(NULL, array[0]);
+    atf_utils_free_charpp(array);
+}
+
+ATF_TC_WITHOUT_HEAD(list_to_charpp_some);
+ATF_TC_BODY(list_to_charpp_some, tc)
+{
+    atf_list_t list;
+    char **array;
+
+    char s1[] = "one";
+    char s2[] = "two";
+    char s3[] = "three";
+
+    RE(atf_list_init(&list));
+    RE(atf_list_append(&list, s1, false));
+    RE(atf_list_append(&list, s2, false));
+    RE(atf_list_append(&list, s3, false));
+    ATF_REQUIRE((array = atf_list_to_charpp(&list)) != NULL);
+    atf_list_fini(&list);
+
+    ATF_CHECK_STREQ("one", array[0]);
+    ATF_CHECK_STREQ("two", array[1]);
+    ATF_CHECK_STREQ("three", array[2]);
+    ATF_CHECK_EQ(NULL, array[3]);
+    atf_utils_free_charpp(array);
+}
+
+/*
+ * Modifiers.
+ */
+
+ATF_TC(list_append);
+ATF_TC_HEAD(list_append, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_append function");
+}
+ATF_TC_BODY(list_append, tc)
+{
+    atf_list_t list;
+    size_t i;
+    char buf[] = "Test string";
+
+    RE(atf_list_init(&list));
+    for (i = 0; i < 1024; i++) {
+        ATF_REQUIRE_EQ(atf_list_size(&list), i);
+        RE(atf_list_append(&list, buf, false));
+    }
+    atf_list_fini(&list);
+}
+
+ATF_TC(list_append_list);
+ATF_TC_HEAD(list_append_list, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_append_list "
+                      "function");
+}
+ATF_TC_BODY(list_append_list, tc)
+{
+    {
+        atf_list_t l1, l2;
+
+        RE(atf_list_init(&l1));
+        RE(atf_list_init(&l2));
+
+        atf_list_append_list(&l1, &l2);
+        ATF_CHECK_EQ(atf_list_size(&l1), 0);
+
+        atf_list_fini(&l1);
+    }
+
+    {
+        atf_list_t l1, l2;
+        int item = 5;
+
+        RE(atf_list_init(&l1));
+        RE(atf_list_append(&l1, &item, false));
+        RE(atf_list_init(&l2));
+
+        atf_list_append_list(&l1, &l2);
+        ATF_CHECK_EQ(atf_list_size(&l1), 1);
+        ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item);
+
+        atf_list_fini(&l1);
+    }
+
+    {
+        atf_list_t l1, l2;
+        int item = 5;
+
+        RE(atf_list_init(&l1));
+        RE(atf_list_init(&l2));
+        RE(atf_list_append(&l2, &item, false));
+
+        atf_list_append_list(&l1, &l2);
+        ATF_CHECK_EQ(atf_list_size(&l1), 1);
+        ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item);
+
+        atf_list_fini(&l1);
+    }
+
+    {
+        atf_list_t l1, l2;
+        int item1 = 5;
+        int item2 = 9;
+
+        RE(atf_list_init(&l1));
+        RE(atf_list_append(&l1, &item1, false));
+        RE(atf_list_init(&l2));
+        RE(atf_list_append(&l2, &item2, false));
+
+        atf_list_append_list(&l1, &l2);
+        ATF_CHECK_EQ(atf_list_size(&l1), 2);
+        ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 0), item1);
+        ATF_CHECK_EQ(*(int *)atf_list_index(&l1, 1), item2);
+
+        atf_list_fini(&l1);
+    }
+
+    {
+        atf_list_t l1, l2;
+        atf_list_citer_t end1, end2;
+
+        RE(atf_list_init(&l1));
+        RE(atf_list_init(&l2));
+
+        end1 = atf_list_end_c(&l1);
+        end2 = atf_list_end_c(&l2);
+        /* XXX Shouldn't query m_entry here. */
+        ATF_CHECK(end1.m_entry != end2.m_entry);
+
+        atf_list_append_list(&l1, &l2);
+        ATF_CHECK(atf_list_end_c(&l1).m_entry == end2.m_entry);
+
+        atf_list_fini(&l1);
+    }
+}
+
+/*
+ * Macros.
+ */
+
+ATF_TC(list_for_each);
+ATF_TC_HEAD(list_for_each, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_for_each macro");
+}
+ATF_TC_BODY(list_for_each, tc)
+{
+    atf_list_t list;
+    atf_list_iter_t iter;
+    size_t count, i, size;
+    int nums[10];
+
+    printf("Iterating over empty list\n");
+    RE(atf_list_init(&list));
+    count = 0;
+    atf_list_for_each(iter, &list) {
+        count++;
+        printf("Item count is now %zd\n", count);
+    }
+    ATF_REQUIRE_EQ(count, 0);
+    atf_list_fini(&list);
+
+    for (size = 0; size <= 10; size++) {
+        printf("Iterating over list of %zd elements\n", size);
+        RE(atf_list_init(&list));
+        for (i = 0; i < size; i++) {
+            nums[i] = i + 1;
+            RE(atf_list_append(&list, &nums[i], false));
+        }
+        count = 0;
+        atf_list_for_each(iter, &list) {
+            printf("Retrieved item: %d\n", *(int *)atf_list_iter_data(iter));
+            count++;
+        }
+        ATF_REQUIRE_EQ(count, size);
+        atf_list_fini(&list);
+    }
+}
+
+ATF_TC(list_for_each_c);
+ATF_TC_HEAD(list_for_each_c, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_list_for_each_c macro");
+}
+ATF_TC_BODY(list_for_each_c, tc)
+{
+    atf_list_t list;
+    atf_list_citer_t iter;
+    size_t count, i, size;
+    int nums[10];
+
+    printf("Iterating over empty list\n");
+    RE(atf_list_init(&list));
+    count = 0;
+    atf_list_for_each_c(iter, &list) {
+        count++;
+        printf("Item count is now %zd\n", count);
+    }
+    ATF_REQUIRE_EQ(count, 0);
+    atf_list_fini(&list);
+
+    for (size = 0; size <= 10; size++) {
+        printf("Iterating over list of %zd elements\n", size);
+        RE(atf_list_init(&list));
+        for (i = 0; i < size; i++) {
+            nums[i] = i + 1;
+            RE(atf_list_append(&list, &nums[i], false));
+        }
+        count = 0;
+        atf_list_for_each_c(iter, &list) {
+            printf("Retrieved item: %d\n",
+                   *(const int *)atf_list_citer_data(iter));
+            count++;
+        }
+        ATF_REQUIRE_EQ(count, size);
+        atf_list_fini(&list);
+    }
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    /* Constructors and destructors. */
+    ATF_TP_ADD_TC(tp, list_init);
+
+    /* Getters. */
+    ATF_TP_ADD_TC(tp, list_index);
+    ATF_TP_ADD_TC(tp, list_index_c);
+    ATF_TP_ADD_TC(tp, list_to_charpp_empty);
+    ATF_TP_ADD_TC(tp, list_to_charpp_some);
+
+    /* Modifiers. */
+    ATF_TP_ADD_TC(tp, list_append);
+    ATF_TP_ADD_TC(tp, list_append_list);
+
+    /* Macros. */
+    ATF_TP_ADD_TC(tp, list_for_each);
+    ATF_TP_ADD_TC(tp, list_for_each_c);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/detail/map.c
===================================================================
--- vendor/atf/dist/atf-c/detail/map.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/map.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,378 @@
+/* Copyright (c) 2008 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/map.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "atf-c/detail/sanity.h"
+#include "atf-c/error.h"
+#include "atf-c/utils.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+struct map_entry {
+    char *m_key;
+    void *m_value;
+    bool m_managed;
+};
+
+static
+struct map_entry *
+new_entry(const char *key, void *value, bool managed)
+{
+    struct map_entry *me;
+
+    me = (struct map_entry *)malloc(sizeof(*me));
+    if (me != NULL) {
+        me->m_key = strdup(key);
+        if (me->m_key == NULL) {
+            free(me);
+            me = NULL;
+        } else {
+            me->m_value = value;
+            me->m_managed = managed;
+        }
+    }
+
+    return me;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_map_citer" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Getters.
+ */
+
+const char *
+atf_map_citer_key(const atf_map_citer_t citer)
+{
+    const struct map_entry *me = citer.m_entry;
+    PRE(me != NULL);
+    return me->m_key;
+}
+
+const void *
+atf_map_citer_data(const atf_map_citer_t citer)
+{
+    const struct map_entry *me = citer.m_entry;
+    PRE(me != NULL);
+    return me->m_value;
+}
+
+atf_map_citer_t
+atf_map_citer_next(const atf_map_citer_t citer)
+{
+    atf_map_citer_t newciter;
+
+    newciter = citer;
+    newciter.m_listiter = atf_list_citer_next(citer.m_listiter);
+    newciter.m_entry = ((const struct map_entry *)
+                        atf_list_citer_data(newciter.m_listiter));
+
+    return newciter;
+}
+
+bool
+atf_equal_map_citer_map_citer(const atf_map_citer_t i1,
+                              const atf_map_citer_t i2)
+{
+    return i1.m_map == i2.m_map && i1.m_entry == i2.m_entry;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_map_iter" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Getters.
+ */
+
+const char *
+atf_map_iter_key(const atf_map_iter_t iter)
+{
+    const struct map_entry *me = iter.m_entry;
+    PRE(me != NULL);
+    return me->m_key;
+}
+
+void *
+atf_map_iter_data(const atf_map_iter_t iter)
+{
+    const struct map_entry *me = iter.m_entry;
+    PRE(me != NULL);
+    return me->m_value;
+}
+
+atf_map_iter_t
+atf_map_iter_next(const atf_map_iter_t iter)
+{
+    atf_map_iter_t newiter;
+
+    newiter = iter;
+    newiter.m_listiter = atf_list_iter_next(iter.m_listiter);
+    newiter.m_entry = ((struct map_entry *)
+                       atf_list_iter_data(newiter.m_listiter));
+
+    return newiter;
+}
+
+bool
+atf_equal_map_iter_map_iter(const atf_map_iter_t i1,
+                            const atf_map_iter_t i2)
+{
+    return i1.m_map == i2.m_map && i1.m_entry == i2.m_entry;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_map" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constructors and destructors.
+ */
+
+atf_error_t
+atf_map_init(atf_map_t *m)
+{
+    return atf_list_init(&m->m_list);
+}
+
+atf_error_t
+atf_map_init_charpp(atf_map_t *m, const char *const *array)
+{
+    atf_error_t err;
+    const char *const *ptr = array;
+
+    err = atf_map_init(m);
+    if (array != NULL) {
+        while (!atf_is_error(err) && *ptr != NULL) {
+            const char *key, *value;
+
+            key = *ptr;
+            INV(key != NULL);
+            ptr++;
+
+            if ((value = *ptr) == NULL) {
+                err = atf_libc_error(EINVAL, "List too short; no value for "
+                    "key '%s' provided", key);  /* XXX: Not really libc_error */
+                break;
+            }
+            ptr++;
+
+            err = atf_map_insert(m, key, strdup(value), true);
+        }
+    }
+
+    if (atf_is_error(err))
+        atf_map_fini(m);
+
+    return err;
+}
+
+void
+atf_map_fini(atf_map_t *m)
+{
+    atf_list_iter_t iter;
+
+    atf_list_for_each(iter, &m->m_list) {
+        struct map_entry *me = atf_list_iter_data(iter);
+
+        if (me->m_managed)
+            free(me->m_value);
+        free(me->m_key);
+        free(me);
+    }
+    atf_list_fini(&m->m_list);
+}
+
+/*
+ * Getters.
+ */
+
+atf_map_iter_t
+atf_map_begin(atf_map_t *m)
+{
+    atf_map_iter_t iter;
+    iter.m_map = m;
+    iter.m_listiter = atf_list_begin(&m->m_list);
+    iter.m_entry = atf_list_iter_data(iter.m_listiter);
+    return iter;
+}
+
+atf_map_citer_t
+atf_map_begin_c(const atf_map_t *m)
+{
+    atf_map_citer_t citer;
+    citer.m_map = m;
+    citer.m_listiter = atf_list_begin_c(&m->m_list);
+    citer.m_entry = atf_list_citer_data(citer.m_listiter);
+    return citer;
+}
+
+atf_map_iter_t
+atf_map_end(atf_map_t *m)
+{
+    atf_map_iter_t iter;
+    iter.m_map = m;
+    iter.m_entry = NULL;
+    iter.m_listiter = atf_list_end(&m->m_list);
+    return iter;
+}
+
+atf_map_citer_t
+atf_map_end_c(const atf_map_t *m)
+{
+    atf_map_citer_t iter;
+    iter.m_map = m;
+    iter.m_entry = NULL;
+    iter.m_listiter = atf_list_end_c(&m->m_list);
+    return iter;
+}
+
+atf_map_iter_t
+atf_map_find(atf_map_t *m, const char *key)
+{
+    atf_list_iter_t iter;
+
+    atf_list_for_each(iter, &m->m_list) {
+        struct map_entry *me = atf_list_iter_data(iter);
+
+        if (strcmp(me->m_key, key) == 0) {
+            atf_map_iter_t i;
+            i.m_map = m;
+            i.m_entry = me;
+            i.m_listiter = iter;
+            return i;
+        }
+    }
+
+    return atf_map_end(m);
+}
+
+atf_map_citer_t
+atf_map_find_c(const atf_map_t *m, const char *key)
+{
+    atf_list_citer_t iter;
+
+    atf_list_for_each_c(iter, &m->m_list) {
+        const struct map_entry *me = atf_list_citer_data(iter);
+
+        if (strcmp(me->m_key, key) == 0) {
+            atf_map_citer_t i;
+            i.m_map = m;
+            i.m_entry = me;
+            i.m_listiter = iter;
+            return i;
+        }
+    }
+
+    return atf_map_end_c(m);
+}
+
+size_t
+atf_map_size(const atf_map_t *m)
+{
+    return atf_list_size(&m->m_list);
+}
+
+char **
+atf_map_to_charpp(const atf_map_t *l)
+{
+    char **array;
+    atf_map_citer_t iter;
+    size_t i;
+
+    array = malloc(sizeof(char *) * (atf_map_size(l) * 2 + 1));
+    if (array == NULL)
+        goto out;
+
+    i = 0;
+    atf_map_for_each_c(iter, l) {
+        array[i] = strdup(atf_map_citer_key(iter));
+        if (array[i] == NULL) {
+            atf_utils_free_charpp(array);
+            array = NULL;
+            goto out;
+        }
+
+        array[i + 1] = strdup((const char *)atf_map_citer_data(iter));
+        if (array[i + 1] == NULL) {
+            atf_utils_free_charpp(array);
+            array = NULL;
+            goto out;
+        }
+
+        i += 2;
+    }
+    array[i] = NULL;
+
+out:
+    return array;
+}
+
+/*
+ * Modifiers.
+ */
+
+atf_error_t
+atf_map_insert(atf_map_t *m, const char *key, void *value, bool managed)
+{
+    struct map_entry *me;
+    atf_error_t err;
+    atf_map_iter_t iter;
+
+    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)
+            err = atf_no_memory_error();
+        else {
+            err = atf_list_append(&m->m_list, me, false);
+            if (atf_is_error(err)) {
+                if (managed)
+                    free(value);
+            }
+        }
+    } else {
+        me = iter.m_entry;
+        if (me->m_managed)
+            free(me->m_value);
+
+        INV(strcmp(me->m_key, key) == 0);
+        me->m_value = value;
+        me->m_managed = managed;
+
+        err = atf_no_error();
+    }
+
+    return err;
+}

Added: vendor/atf/dist/atf-c/detail/map.h
===================================================================
--- vendor/atf/dist/atf-c/detail/map.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/map.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,114 @@
+/* Copyright (c) 2008 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_C_DETAIL_MAP_H)
+#define ATF_C_DETAIL_MAP_H
+
+#include <stdarg.h>
+#include <stdbool.h>
+
+#include <atf-c/detail/list.h>
+#include <atf-c/error_fwd.h>
+
+/* ---------------------------------------------------------------------
+ * The "atf_map_citer" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_map_citer {
+    const struct atf_map *m_map;
+    const void *m_entry;
+    atf_list_citer_t m_listiter;
+};
+typedef struct atf_map_citer atf_map_citer_t;
+
+/* Getters. */
+const char *atf_map_citer_key(const atf_map_citer_t);
+const void *atf_map_citer_data(const atf_map_citer_t);
+atf_map_citer_t atf_map_citer_next(const atf_map_citer_t);
+
+/* Operators. */
+bool atf_equal_map_citer_map_citer(const atf_map_citer_t,
+                                   const atf_map_citer_t);
+
+/* ---------------------------------------------------------------------
+ * The "atf_map_iter" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_map_iter {
+    struct atf_map *m_map;
+    void *m_entry;
+    atf_list_iter_t m_listiter;
+};
+typedef struct atf_map_iter atf_map_iter_t;
+
+/* Getters. */
+const char *atf_map_iter_key(const atf_map_iter_t);
+void *atf_map_iter_data(const atf_map_iter_t);
+atf_map_iter_t atf_map_iter_next(const atf_map_iter_t);
+
+/* Operators. */
+bool atf_equal_map_iter_map_iter(const atf_map_iter_t,
+                                 const atf_map_iter_t);
+
+/* ---------------------------------------------------------------------
+ * The "atf_map" type.
+ * --------------------------------------------------------------------- */
+
+/* A list-based map.  Typically very inefficient, but our maps are small
+ * enough. */
+struct atf_map {
+    atf_list_t m_list;
+};
+typedef struct atf_map atf_map_t;
+
+/* Constructors and destructors */
+atf_error_t atf_map_init(atf_map_t *);
+atf_error_t atf_map_init_charpp(atf_map_t *, const char *const *);
+void atf_map_fini(atf_map_t *);
+
+/* Getters. */
+atf_map_iter_t atf_map_begin(atf_map_t *);
+atf_map_citer_t atf_map_begin_c(const atf_map_t *);
+atf_map_iter_t atf_map_end(atf_map_t *);
+atf_map_citer_t atf_map_end_c(const atf_map_t *);
+atf_map_iter_t atf_map_find(atf_map_t *, const char *);
+atf_map_citer_t atf_map_find_c(const atf_map_t *, const char *);
+size_t atf_map_size(const atf_map_t *);
+char **atf_map_to_charpp(const atf_map_t *);
+
+/* Modifiers. */
+atf_error_t atf_map_insert(atf_map_t *, const char *, void *, bool);
+
+/* Macros. */
+#define atf_map_for_each(iter, map) \
+    for (iter = atf_map_begin(map); \
+         !atf_equal_map_iter_map_iter((iter), atf_map_end(map)); \
+         iter = atf_map_iter_next(iter))
+#define atf_map_for_each_c(iter, map) \
+    for (iter = atf_map_begin_c(map); \
+         !atf_equal_map_citer_map_citer((iter), atf_map_end_c(map)); \
+         iter = atf_map_citer_next(iter))
+
+#endif /* !defined(ATF_C_DETAIL_MAP_H) */

Added: vendor/atf/dist/atf-c/detail/map_test.c
===================================================================
--- vendor/atf/dist/atf-c/detail/map_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/map_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,421 @@
+/* Copyright (c) 2008 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/map.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/test_helpers.h"
+#include "atf-c/utils.h"
+
+/* ---------------------------------------------------------------------
+ * Tests for the "atf_map" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constructors and destructors.
+ */
+
+ATF_TC(map_init);
+ATF_TC_HEAD(map_init, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_map_init function");
+}
+ATF_TC_BODY(map_init, tc)
+{
+    atf_map_t map;
+
+    RE(atf_map_init(&map));
+    ATF_REQUIRE_EQ(atf_map_size(&map), 0);
+    atf_map_fini(&map);
+}
+
+ATF_TC_WITHOUT_HEAD(map_init_charpp_null);
+ATF_TC_BODY(map_init_charpp_null, tc)
+{
+    atf_map_t map;
+
+    RE(atf_map_init_charpp(&map, NULL));
+    ATF_REQUIRE_EQ(atf_map_size(&map), 0);
+    atf_map_fini(&map);
+}
+
+ATF_TC_WITHOUT_HEAD(map_init_charpp_empty);
+ATF_TC_BODY(map_init_charpp_empty, tc)
+{
+    const char *const array[] = { NULL };
+    atf_map_t map;
+
+    RE(atf_map_init_charpp(&map, array));
+    ATF_REQUIRE_EQ(atf_map_size(&map), 0);
+    atf_map_fini(&map);
+}
+
+ATF_TC_WITHOUT_HEAD(map_init_charpp_some);
+ATF_TC_BODY(map_init_charpp_some, tc)
+{
+    const char *const array[] = { "K1", "V1", "K2", "V2", NULL };
+    atf_map_t map;
+    atf_map_citer_t iter;
+
+    RE(atf_map_init_charpp(&map, array));
+    ATF_REQUIRE_EQ(atf_map_size(&map), 2);
+
+    iter = atf_map_find_c(&map, "K1");
+    ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+    ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K1") == 0);
+    ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V1") == 0);
+
+    iter = atf_map_find_c(&map, "K2");
+    ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+    ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K2") == 0);
+    ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V2") == 0);
+
+    atf_map_fini(&map);
+}
+
+ATF_TC_WITHOUT_HEAD(map_init_charpp_short);
+ATF_TC_BODY(map_init_charpp_short, tc)
+{
+    const char *const array[] = { "K1", "V1", "K2", NULL };
+    atf_map_t map;
+
+    atf_error_t err = atf_map_init_charpp(&map, array);
+    ATF_REQUIRE(atf_is_error(err));
+    ATF_REQUIRE(atf_error_is(err, "libc"));
+}
+
+/*
+ * Getters.
+ */
+
+ATF_TC(find);
+ATF_TC_HEAD(find, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_map_find function");
+}
+ATF_TC_BODY(find, tc)
+{
+    atf_map_t map;
+    char val1[] = "V1";
+    char val2[] = "V2";
+    atf_map_iter_t iter;
+
+    RE(atf_map_init(&map));
+    RE(atf_map_insert(&map, "K1", val1, false));
+    RE(atf_map_insert(&map, "K2", val2, false));
+
+    iter = atf_map_find(&map, "K0");
+    ATF_REQUIRE(atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
+
+    iter = atf_map_find(&map, "K1");
+    ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
+    ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K1") == 0);
+    ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "V1") == 0);
+    strcpy(atf_map_iter_data(iter), "Z1");
+
+    iter = atf_map_find(&map, "K1");
+    ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
+    ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K1") == 0);
+    ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "Z1") == 0);
+
+    iter = atf_map_find(&map, "K2");
+    ATF_REQUIRE(!atf_equal_map_iter_map_iter(iter, atf_map_end(&map)));
+    ATF_REQUIRE(strcmp(atf_map_iter_key(iter), "K2") == 0);
+    ATF_REQUIRE(strcmp(atf_map_iter_data(iter), "V2") == 0);
+
+    atf_map_fini(&map);
+}
+
+ATF_TC(find_c);
+ATF_TC_HEAD(find_c, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_map_find_c function");
+}
+ATF_TC_BODY(find_c, tc)
+{
+    atf_map_t map;
+    char val1[] = "V1";
+    char val2[] = "V2";
+    atf_map_citer_t iter;
+
+    RE(atf_map_init(&map));
+    RE(atf_map_insert(&map, "K1", val1, false));
+    RE(atf_map_insert(&map, "K2", val2, false));
+
+    iter = atf_map_find_c(&map, "K0");
+    ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+
+    iter = atf_map_find_c(&map, "K1");
+    ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+    ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K1") == 0);
+    ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V1") == 0);
+
+    iter = atf_map_find_c(&map, "K2");
+    ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+    ATF_REQUIRE(strcmp(atf_map_citer_key(iter), "K2") == 0);
+    ATF_REQUIRE(strcmp(atf_map_citer_data(iter), "V2") == 0);
+
+    atf_map_fini(&map);
+}
+
+ATF_TC_WITHOUT_HEAD(to_charpp_empty);
+ATF_TC_BODY(to_charpp_empty, tc)
+{
+    atf_map_t map;
+    char **array;
+
+    RE(atf_map_init(&map));
+    ATF_REQUIRE((array = atf_map_to_charpp(&map)) != NULL);
+    atf_map_fini(&map);
+
+    ATF_CHECK_EQ(NULL, array[0]);
+    atf_utils_free_charpp(array);
+}
+
+ATF_TC_WITHOUT_HEAD(to_charpp_some);
+ATF_TC_BODY(to_charpp_some, tc)
+{
+    atf_map_t map;
+    char **array;
+
+    char s1[] = "one";
+    char s2[] = "two";
+    char s3[] = "three";
+
+    RE(atf_map_init(&map));
+    RE(atf_map_insert(&map, "K1", s1, false));
+    RE(atf_map_insert(&map, "K2", s2, false));
+    RE(atf_map_insert(&map, "K3", s3, false));
+    ATF_REQUIRE((array = atf_map_to_charpp(&map)) != NULL);
+    atf_map_fini(&map);
+
+    ATF_CHECK_STREQ("K1", array[0]);
+    ATF_CHECK_STREQ("one", array[1]);
+    ATF_CHECK_STREQ("K2", array[2]);
+    ATF_CHECK_STREQ("two", array[3]);
+    ATF_CHECK_STREQ("K3", array[4]);
+    ATF_CHECK_STREQ("three", array[5]);
+    ATF_CHECK_EQ(NULL, array[6]);
+    atf_utils_free_charpp(array);
+}
+
+/*
+ * Modifiers.
+ */
+
+ATF_TC(map_insert);
+ATF_TC_HEAD(map_insert, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_map_insert function");
+}
+ATF_TC_BODY(map_insert, tc)
+{
+    atf_map_t map;
+    char buf[] = "1st test string";
+    char buf2[] = "2nd test string";
+    const char *ptr;
+    atf_map_citer_t iter;
+
+    RE(atf_map_init(&map));
+
+    printf("Inserting some values\n");
+    ATF_REQUIRE_EQ(atf_map_size(&map), 0);
+    RE(atf_map_insert(&map, "K1", buf, false));
+    ATF_REQUIRE_EQ(atf_map_size(&map), 1);
+    RE(atf_map_insert(&map, "K2", buf, false));
+    ATF_REQUIRE_EQ(atf_map_size(&map), 2);
+    RE(atf_map_insert(&map, "K3", buf, false));
+    ATF_REQUIRE_EQ(atf_map_size(&map), 3);
+
+    printf("Replacing a value\n");
+    iter = atf_map_find_c(&map, "K3");
+    ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+    ptr = atf_map_citer_data(iter);
+    ATF_REQUIRE_EQ(ptr, buf);
+    RE(atf_map_insert(&map, "K3", buf2, false));
+    ATF_REQUIRE_EQ(atf_map_size(&map), 3);
+    iter = atf_map_find_c(&map, "K3");
+    ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+    ptr = atf_map_citer_data(iter);
+    ATF_REQUIRE_EQ(ptr, buf2);
+
+    atf_map_fini(&map);
+}
+
+/*
+ * Macros.
+ */
+
+ATF_TC(map_for_each);
+ATF_TC_HEAD(map_for_each, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_map_for_each macro");
+}
+ATF_TC_BODY(map_for_each, tc)
+{
+    atf_map_t map;
+    atf_map_iter_t iter;
+    size_t count, i, size;
+    char keys[10][5];
+    int nums[10];
+
+    printf("Iterating over empty map\n");
+    RE(atf_map_init(&map));
+    count = 0;
+    atf_map_for_each(iter, &map) {
+        count++;
+        printf("Item count is now %zd\n", count);
+    }
+    ATF_REQUIRE_EQ(count, 0);
+    atf_map_fini(&map);
+
+    for (size = 0; size <= 10; size++) {
+        printf("Iterating over map of %zd elements\n", size);
+        RE(atf_map_init(&map));
+        for (i = 0; i < size; i++) {
+            nums[i] = i + 1;
+            snprintf(keys[i], sizeof(keys[i]), "%d", nums[i]);
+            RE(atf_map_insert(&map, keys[i], &nums[i], false));
+        }
+        count = 0;
+        atf_map_for_each(iter, &map) {
+            printf("Retrieved item: %d\n", *(int *)atf_map_iter_data(iter));
+            count++;
+        }
+        ATF_REQUIRE_EQ(count, size);
+        atf_map_fini(&map);
+    }
+}
+
+ATF_TC(map_for_each_c);
+ATF_TC_HEAD(map_for_each_c, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_map_for_each_c macro");
+}
+ATF_TC_BODY(map_for_each_c, tc)
+{
+    atf_map_t map;
+    atf_map_citer_t iter;
+    size_t count, i, size;
+    char keys[10][5];
+    int nums[10];
+
+    printf("Iterating over empty map\n");
+    RE(atf_map_init(&map));
+    count = 0;
+    atf_map_for_each_c(iter, &map) {
+        count++;
+        printf("Item count is now %zd\n", count);
+    }
+    ATF_REQUIRE_EQ(count, 0);
+    atf_map_fini(&map);
+
+    for (size = 0; size <= 10; size++) {
+        printf("Iterating over map of %zd elements\n", size);
+        RE(atf_map_init(&map));
+        for (i = 0; i < size; i++) {
+            nums[i] = i + 1;
+            snprintf(keys[i], sizeof(keys[i]), "%d", nums[i]);
+            RE(atf_map_insert(&map, keys[i], &nums[i], false));
+        }
+        count = 0;
+        atf_map_for_each_c(iter, &map) {
+            printf("Retrieved item: %d\n",
+                   *(const int *)atf_map_citer_data(iter));
+            count++;
+        }
+        ATF_REQUIRE_EQ(count, size);
+        atf_map_fini(&map);
+    }
+}
+
+/*
+ * Other.
+ */
+
+ATF_TC(stable_keys);
+ATF_TC_HEAD(stable_keys, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that the keys do not change "
+                      "even if their original values do");
+}
+ATF_TC_BODY(stable_keys, tc)
+{
+    atf_map_t map;
+    atf_map_citer_t iter;
+    char key[] = "K1";
+
+    RE(atf_map_init(&map));
+
+    RE(atf_map_insert(&map, key, strdup("test-value"), true));
+    iter = atf_map_find_c(&map, "K1");
+    ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+    iter = atf_map_find_c(&map, "K2");
+    ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+
+    strcpy(key, "K2");
+    iter = atf_map_find_c(&map, "K1");
+    ATF_REQUIRE(!atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+    iter = atf_map_find_c(&map, "K2");
+    ATF_REQUIRE(atf_equal_map_citer_map_citer(iter, atf_map_end_c(&map)));
+
+    atf_map_fini(&map);
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    /* Constructors and destructors. */
+    ATF_TP_ADD_TC(tp, map_init);
+    ATF_TP_ADD_TC(tp, map_init_charpp_null);
+    ATF_TP_ADD_TC(tp, map_init_charpp_empty);
+    ATF_TP_ADD_TC(tp, map_init_charpp_some);
+    ATF_TP_ADD_TC(tp, map_init_charpp_short);
+
+    /* Getters. */
+    ATF_TP_ADD_TC(tp, find);
+    ATF_TP_ADD_TC(tp, find_c);
+    ATF_TP_ADD_TC(tp, to_charpp_empty);
+    ATF_TP_ADD_TC(tp, to_charpp_some);
+
+    /* Modifiers. */
+    ATF_TP_ADD_TC(tp, map_insert);
+
+    /* Macros. */
+    ATF_TP_ADD_TC(tp, map_for_each);
+    ATF_TP_ADD_TC(tp, map_for_each_c);
+
+    /* Other. */
+    ATF_TP_ADD_TC(tp, stable_keys);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/detail/process.c
===================================================================
--- vendor/atf/dist/atf-c/detail/process.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/process.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,670 @@
+/* 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/process.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "atf-c/defs.h"
+#include "atf-c/detail/sanity.h"
+#include "atf-c/error.h"
+
+/* 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);
+
+/* ---------------------------------------------------------------------
+ * The "stream_prepare" auxiliary type.
+ * --------------------------------------------------------------------- */
+
+struct stream_prepare {
+    const atf_process_stream_t *m_sb;
+
+    bool m_pipefds_ok;
+    int m_pipefds[2];
+};
+typedef struct stream_prepare stream_prepare_t;
+
+static
+atf_error_t
+stream_prepare_init(stream_prepare_t *sp, const atf_process_stream_t *sb)
+{
+    atf_error_t err;
+
+    const int type = atf_process_stream_type(sb);
+
+    sp->m_sb = sb;
+    sp->m_pipefds_ok = false;
+
+    if (type == atf_process_stream_type_capture) {
+        if (pipe(sp->m_pipefds) == -1)
+            err = atf_libc_error(errno, "Failed to create pipe");
+        else {
+            err = atf_no_error();
+            sp->m_pipefds_ok = true;
+        }
+    } else
+        err = atf_no_error();
+
+    return err;
+}
+
+static
+void
+stream_prepare_fini(stream_prepare_t *sp)
+{
+    if (sp->m_pipefds_ok) {
+        close(sp->m_pipefds[0]);
+        close(sp->m_pipefds[1]);
+    }
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_process_stream" type.
+ * --------------------------------------------------------------------- */
+
+const int atf_process_stream_type_capture = 1;
+const int atf_process_stream_type_connect = 2;
+const int atf_process_stream_type_inherit = 3;
+const int atf_process_stream_type_redirect_fd = 4;
+const int atf_process_stream_type_redirect_path = 5;
+
+static
+bool
+stream_is_valid(const atf_process_stream_t *sb)
+{
+    return (sb->m_type == atf_process_stream_type_capture) ||
+           (sb->m_type == atf_process_stream_type_connect) ||
+           (sb->m_type == atf_process_stream_type_inherit) ||
+           (sb->m_type == atf_process_stream_type_redirect_fd) ||
+           (sb->m_type == atf_process_stream_type_redirect_path);
+}
+
+atf_error_t
+atf_process_stream_init_capture(atf_process_stream_t *sb)
+{
+    sb->m_type = atf_process_stream_type_capture;
+
+    POST(stream_is_valid(sb));
+    return atf_no_error();
+}
+
+atf_error_t
+atf_process_stream_init_connect(atf_process_stream_t *sb,
+                                const int src_fd, const int tgt_fd)
+{
+    PRE(src_fd >= 0);
+    PRE(tgt_fd >= 0);
+    PRE(src_fd != tgt_fd);
+
+    sb->m_type = atf_process_stream_type_connect;
+    sb->m_src_fd = src_fd;
+    sb->m_tgt_fd = tgt_fd;
+
+    POST(stream_is_valid(sb));
+    return atf_no_error();
+}
+
+atf_error_t
+atf_process_stream_init_inherit(atf_process_stream_t *sb)
+{
+    sb->m_type = atf_process_stream_type_inherit;
+
+    POST(stream_is_valid(sb));
+    return atf_no_error();
+}
+
+atf_error_t
+atf_process_stream_init_redirect_fd(atf_process_stream_t *sb,
+                                    const int fd)
+{
+    sb->m_type = atf_process_stream_type_redirect_fd;
+    sb->m_fd = fd;
+
+    POST(stream_is_valid(sb));
+    return atf_no_error();
+}
+
+atf_error_t
+atf_process_stream_init_redirect_path(atf_process_stream_t *sb,
+                                      const atf_fs_path_t *path)
+{
+    sb->m_type = atf_process_stream_type_redirect_path;
+    sb->m_path = path;
+
+    POST(stream_is_valid(sb));
+    return atf_no_error();
+}
+
+void
+atf_process_stream_fini(atf_process_stream_t *sb)
+{
+    PRE(stream_is_valid(sb));
+}
+
+int
+atf_process_stream_type(const atf_process_stream_t *sb)
+{
+    PRE(stream_is_valid(sb));
+
+    return sb->m_type;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_process_status" type.
+ * --------------------------------------------------------------------- */
+
+atf_error_t
+atf_process_status_init(atf_process_status_t *s, int status)
+{
+    s->m_status = status;
+
+    return atf_no_error();
+}
+
+void
+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);
+}
+
+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);
+}
+
+bool
+atf_process_status_signaled(const atf_process_status_t *s)
+{
+    int mutable_status = s->m_status;
+    return WIFSIGNALED(mutable_status);
+}
+
+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);
+}
+
+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
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_process_child" type.
+ * --------------------------------------------------------------------- */
+
+static
+atf_error_t
+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
+void
+atf_process_child_fini(atf_process_child_t *c)
+{
+    if (c->m_stdout != -1)
+        close(c->m_stdout);
+    if (c->m_stderr != -1)
+        close(c->m_stderr);
+}
+
+atf_error_t
+atf_process_child_wait(atf_process_child_t *c, atf_process_status_t *s)
+{
+    atf_error_t err;
+    int status;
+
+    if (waitpid(c->m_pid, &status, 0) == -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);
+    }
+
+    return err;
+}
+
+pid_t
+atf_process_child_pid(const atf_process_child_t *c)
+{
+    return c->m_pid;
+}
+
+int
+atf_process_child_stdout(atf_process_child_t *c)
+{
+    PRE(c->m_stdout != -1);
+    return c->m_stdout;
+}
+
+int
+atf_process_child_stderr(atf_process_child_t *c)
+{
+    PRE(c->m_stderr != -1);
+    return c->m_stderr;
+}
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+static
+atf_error_t
+safe_dup(const int oldfd, const int newfd)
+{
+    atf_error_t err;
+
+    if (oldfd != newfd) {
+        if (dup2(oldfd, newfd) == -1) {
+            err = atf_libc_error(errno, "Could not allocate file descriptor");
+        } else {
+            close(oldfd);
+            err = atf_no_error();
+        }
+    } else
+        err = atf_no_error();
+
+    return err;
+}
+
+static
+atf_error_t
+child_connect(const stream_prepare_t *sp, int procfd)
+{
+    atf_error_t err;
+    const int type = atf_process_stream_type(sp->m_sb);
+
+    if (type == atf_process_stream_type_capture) {
+        close(sp->m_pipefds[0]);
+        err = safe_dup(sp->m_pipefds[1], procfd);
+    } else if (type == atf_process_stream_type_connect) {
+        if (dup2(sp->m_sb->m_tgt_fd, sp->m_sb->m_src_fd) == -1)
+            err = atf_libc_error(errno, "Cannot connect descriptor %d to %d",
+                                 sp->m_sb->m_tgt_fd, sp->m_sb->m_src_fd);
+        else
+            err = atf_no_error();
+    } else if (type == atf_process_stream_type_inherit) {
+        err = atf_no_error();
+    } else if (type == atf_process_stream_type_redirect_fd) {
+        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);
+        if (aux == -1)
+            err = atf_libc_error(errno, "Could not create %s",
+                                 atf_fs_path_cstring(sp->m_sb->m_path));
+        else {
+            err = safe_dup(aux, procfd);
+            if (atf_is_error(err))
+                close(aux);
+        }
+    } else {
+        UNREACHABLE;
+        err = atf_no_error();
+    }
+
+    return err;
+}
+
+static
+void
+parent_connect(const stream_prepare_t *sp, int *fd)
+{
+    const int type = atf_process_stream_type(sp->m_sb);
+
+    if (type == atf_process_stream_type_capture) {
+        close(sp->m_pipefds[1]);
+        *fd = sp->m_pipefds[0];
+    } else if (type == atf_process_stream_type_connect) {
+        /* Do nothing. */
+    } else if (type == atf_process_stream_type_inherit) {
+        /* Do nothing. */
+    } else if (type == atf_process_stream_type_redirect_fd) {
+        /* Do nothing. */
+    } else if (type == atf_process_stream_type_redirect_path) {
+        /* Do nothing. */
+    } else {
+        UNREACHABLE;
+    }
+}
+
+static
+atf_error_t
+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
+void
+do_child(void (*)(void *),
+         void *,
+         const stream_prepare_t *,
+         const stream_prepare_t *) ATF_DEFS_ATTRIBUTE_NORETURN;
+
+static
+void
+do_child(void (*start)(void *),
+         void *v,
+         const stream_prepare_t *outsp,
+         const stream_prepare_t *errsp)
+{
+    atf_error_t err;
+
+    err = child_connect(outsp, STDOUT_FILENO);
+    if (atf_is_error(err))
+        goto out;
+
+    err = child_connect(errsp, STDERR_FILENO);
+    if (atf_is_error(err))
+        goto out;
+
+    start(v);
+    UNREACHABLE;
+
+out:
+    if (atf_is_error(err)) {
+        char buf[1024];
+
+        atf_error_format(err, buf, sizeof(buf));
+        fprintf(stderr, "Unhandled error: %s\n", buf);
+        atf_error_free(err);
+
+        exit(EXIT_FAILURE);
+    } else
+        exit(EXIT_SUCCESS);
+}
+
+static
+atf_error_t
+fork_with_streams(atf_process_child_t *c,
+                  void (*start)(void *),
+                  const atf_process_stream_t *outsb,
+                  const atf_process_stream_t *errsb,
+                  void *v)
+{
+    atf_error_t err;
+    stream_prepare_t outsp;
+    stream_prepare_t errsp;
+    pid_t pid;
+
+    err = stream_prepare_init(&outsp, outsb);
+    if (atf_is_error(err))
+        goto out;
+
+    err = stream_prepare_init(&errsp, errsb);
+    if (atf_is_error(err))
+        goto err_outpipe;
+
+    pid = fork();
+    if (pid == -1) {
+        err = atf_libc_error(errno, "Failed to fork");
+        goto err_errpipe;
+    }
+
+    if (pid == 0) {
+        do_child(start, v, &outsp, &errsp);
+        UNREACHABLE;
+        abort();
+        err = atf_no_error();
+    } else {
+        err = do_parent(c, pid, &outsp, &errsp);
+        if (atf_is_error(err))
+            goto err_errpipe;
+    }
+
+    goto out;
+
+err_errpipe:
+    stream_prepare_fini(&errsp);
+err_outpipe:
+    stream_prepare_fini(&outsp);
+
+out:
+    return err;
+}
+
+static
+atf_error_t
+init_stream_w_default(const atf_process_stream_t *usersb,
+                      atf_process_stream_t *inheritsb,
+                      const atf_process_stream_t **realsb)
+{
+    atf_error_t err;
+
+    if (usersb == NULL) {
+        err = atf_process_stream_init_inherit(inheritsb);
+        if (!atf_is_error(err))
+            *realsb = inheritsb;
+    } else {
+        err = atf_no_error();
+        *realsb = usersb;
+    }
+
+    return err;
+}
+
+atf_error_t
+atf_process_fork(atf_process_child_t *c,
+                 void (*start)(void *),
+                 const atf_process_stream_t *outsb,
+                 const atf_process_stream_t *errsb,
+                 void *v)
+{
+    atf_error_t err;
+    atf_process_stream_t inherit_outsb, inherit_errsb;
+    const atf_process_stream_t *real_outsb, *real_errsb;
+
+    real_outsb = NULL;  /* Shut up GCC warning. */
+    err = init_stream_w_default(outsb, &inherit_outsb, &real_outsb);
+    if (atf_is_error(err))
+        goto out;
+
+    real_errsb = NULL;  /* Shut up GCC warning. */
+    err = init_stream_w_default(errsb, &inherit_errsb, &real_errsb);
+    if (atf_is_error(err))
+        goto out_out;
+
+    err = fork_with_streams(c, start, real_outsb, real_errsb, v);
+
+    if (errsb == NULL)
+        atf_process_stream_fini(&inherit_errsb);
+out_out:
+    if (outsb == NULL)
+        atf_process_stream_fini(&inherit_outsb);
+out:
+    return err;
+}
+
+static
+int
+const_execvp(const char *file, const char *const *argv)
+{
+#define UNCONST(a) ((void *)(unsigned long)(const void *)(a))
+    return execvp(file, UNCONST(argv));
+#undef UNCONST
+}
+
+static
+atf_error_t
+list_to_array(const atf_list_t *l, const char ***ap)
+{
+    atf_error_t err;
+    const char **a;
+
+    a = (const char **)malloc((atf_list_size(l) + 1) * sizeof(const char *));
+    if (a == NULL)
+        err = atf_no_memory_error();
+    else {
+        const char **aiter;
+        atf_list_citer_t liter;
+
+        aiter = a;
+        atf_list_for_each_c(liter, l) {
+            *aiter = (const char *)atf_list_citer_data(liter);
+            aiter++;
+        }
+        *aiter = NULL;
+
+        err = atf_no_error();
+        *ap = a;
+    }
+
+    return err;
+}
+
+struct exec_args {
+    const atf_fs_path_t *m_prog;
+    const char *const *m_argv;
+    void (*m_prehook)(void);
+};
+
+static
+void
+do_exec(void *v)
+{
+    struct exec_args *ea = v;
+
+    if (ea->m_prehook != NULL)
+        ea->m_prehook();
+
+    const int ret = const_execvp(atf_fs_path_cstring(ea->m_prog), ea->m_argv);
+    const int errnocopy = errno;
+    INV(ret == -1);
+    fprintf(stderr, "exec(%s) failed: %s\n",
+            atf_fs_path_cstring(ea->m_prog), strerror(errnocopy));
+    exit(EXIT_FAILURE);
+}
+
+atf_error_t
+atf_process_exec_array(atf_process_status_t *s,
+                       const atf_fs_path_t *prog,
+                       const char *const *argv,
+                       const atf_process_stream_t *outsb,
+                       const atf_process_stream_t *errsb,
+                       void (*prehook)(void))
+{
+    atf_error_t err;
+    atf_process_child_t c;
+    struct exec_args ea = { prog, argv, prehook };
+
+    PRE(outsb == NULL ||
+        atf_process_stream_type(outsb) != atf_process_stream_type_capture);
+    PRE(errsb == NULL ||
+        atf_process_stream_type(errsb) != atf_process_stream_type_capture);
+
+    err = atf_process_fork(&c, do_exec, outsb, errsb, &ea);
+    if (atf_is_error(err))
+        goto out;
+
+again:
+    err = atf_process_child_wait(&c, s);
+    if (atf_is_error(err)) {
+        INV(atf_error_is(err, "libc") && atf_libc_error_code(err) == EINTR);
+        atf_error_free(err);
+        goto again;
+    }
+
+out:
+    return err;
+}
+
+atf_error_t
+atf_process_exec_list(atf_process_status_t *s,
+                      const atf_fs_path_t *prog,
+                      const atf_list_t *argv,
+                      const atf_process_stream_t *outsb,
+                      const atf_process_stream_t *errsb,
+                      void (*prehook)(void))
+{
+    atf_error_t err;
+    const char **argv2;
+
+    PRE(outsb == NULL ||
+        atf_process_stream_type(outsb) != atf_process_stream_type_capture);
+    PRE(errsb == NULL ||
+        atf_process_stream_type(errsb) != atf_process_stream_type_capture);
+
+    argv2 = NULL; /* Silence GCC warning. */
+    err = list_to_array(argv, &argv2);
+    if (atf_is_error(err))
+        goto out;
+
+    err = atf_process_exec_array(s, prog, argv2, outsb, errsb, prehook);
+
+    free(argv2);
+out:
+    return err;
+}

Added: vendor/atf/dist/atf-c/detail/process.h
===================================================================
--- vendor/atf/dist/atf-c/detail/process.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/process.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,131 @@
+/* Copyright (c) 2008 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_C_DETAIL_PROCESS_H)
+#define ATF_C_DETAIL_PROCESS_H
+
+#include <sys/types.h>
+
+#include <stdbool.h>
+
+#include <atf-c/detail/fs.h>
+#include <atf-c/detail/list.h>
+#include <atf-c/error_fwd.h>
+
+/* ---------------------------------------------------------------------
+ * The "atf_process_stream" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_process_stream {
+    int m_type;
+
+    /* Valid if m_type == connect. */
+    int m_src_fd;
+    int m_tgt_fd;
+
+    /* Valid if m_type == redirect_fd. */
+    int m_fd;
+
+    /* Valid if m_type == redirect_path. */
+    const atf_fs_path_t *m_path;
+};
+typedef struct atf_process_stream atf_process_stream_t;
+
+extern const int atf_process_stream_type_capture;
+extern const int atf_process_stream_type_connect;
+extern const int atf_process_stream_type_inherit;
+extern const int atf_process_stream_type_redirect_fd;
+extern const int atf_process_stream_type_redirect_path;
+
+atf_error_t atf_process_stream_init_capture(atf_process_stream_t *);
+atf_error_t atf_process_stream_init_connect(atf_process_stream_t *,
+                                            const int, const int);
+atf_error_t atf_process_stream_init_inherit(atf_process_stream_t *);
+atf_error_t atf_process_stream_init_redirect_fd(atf_process_stream_t *,
+                                                const int fd);
+atf_error_t atf_process_stream_init_redirect_path(atf_process_stream_t *,
+                                                  const atf_fs_path_t *);
+void atf_process_stream_fini(atf_process_stream_t *);
+
+int atf_process_stream_type(const atf_process_stream_t *);
+
+/* ---------------------------------------------------------------------
+ * The "atf_process_status" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_process_status {
+    int m_status;
+};
+typedef struct atf_process_status atf_process_status_t;
+
+void atf_process_status_fini(atf_process_status_t *);
+
+bool atf_process_status_exited(const atf_process_status_t *);
+int atf_process_status_exitstatus(const atf_process_status_t *);
+bool atf_process_status_signaled(const atf_process_status_t *);
+int atf_process_status_termsig(const atf_process_status_t *);
+bool atf_process_status_coredump(const atf_process_status_t *);
+
+/* ---------------------------------------------------------------------
+ * The "atf_process_child" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_process_child {
+    pid_t m_pid;
+
+    int m_stdout;
+    int m_stderr;
+};
+typedef struct atf_process_child atf_process_child_t;
+
+atf_error_t atf_process_child_wait(atf_process_child_t *,
+                                   atf_process_status_t *);
+pid_t atf_process_child_pid(const atf_process_child_t *);
+int atf_process_child_stdout(atf_process_child_t *);
+int atf_process_child_stderr(atf_process_child_t *);
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+atf_error_t atf_process_fork(atf_process_child_t *,
+                             void (*)(void *),
+                             const atf_process_stream_t *,
+                             const atf_process_stream_t *,
+                             void *);
+atf_error_t atf_process_exec_array(atf_process_status_t *,
+                                   const atf_fs_path_t *,
+                                   const char *const *,
+                                   const atf_process_stream_t *,
+                                   const atf_process_stream_t *,
+                                   void (*)(void));
+atf_error_t atf_process_exec_list(atf_process_status_t *,
+                                  const atf_fs_path_t *,
+                                  const atf_list_t *,
+                                  const atf_process_stream_t *,
+                                  const atf_process_stream_t *,
+                                  void (*)(void));
+
+#endif /* !defined(ATF_C_DETAIL_PROCESS_H) */

Added: vendor/atf/dist/atf-c/detail/process_helpers.c
===================================================================
--- vendor/atf/dist/atf-c/detail/process_helpers.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/process_helpers.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,113 @@
+/* Copyright (c) 2008 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 <sys/types.h>
+
+#include <assert.h> /* NO_CHECK_STYLE */
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static
+int
+h_echo(const char *msg)
+{
+    printf("%s\n", msg);
+    return EXIT_SUCCESS;
+}
+
+static
+int
+h_exit_failure(void)
+{
+    return EXIT_FAILURE;
+}
+
+static
+int
+h_exit_signal(void)
+{
+    kill(getpid(), SIGKILL);
+    assert(0); /* NO_CHECK_STYLE */
+    return EXIT_FAILURE;
+}
+
+static
+int
+h_exit_success(void)
+{
+    return EXIT_SUCCESS;
+}
+
+static
+int
+h_stdout_stderr(const char *id)
+{
+    fprintf(stdout, "Line 1 to stdout for %s\n", id);
+    fprintf(stdout, "Line 2 to stdout for %s\n", id);
+    fprintf(stderr, "Line 1 to stderr for %s\n", id);
+    fprintf(stderr, "Line 2 to stderr for %s\n", id);
+
+    return EXIT_SUCCESS;
+}
+
+static
+void
+check_args(const int argc, const char *const argv[], const int required)
+{
+    if (argc < required) {
+        fprintf(stderr, "Usage: %s helper-name [args]\n", argv[0]);
+        exit(EXIT_FAILURE);
+    }
+}
+
+int
+main(int argc, const char *const argv[])
+{
+    int exitcode;
+
+    check_args(argc, argv, 2);
+
+    if (strcmp(argv[1], "echo") == 0) {
+        check_args(argc, argv, 3);
+        exitcode = h_echo(argv[2]);
+    } else if (strcmp(argv[1], "exit-failure") == 0)
+        exitcode = h_exit_failure();
+    else if (strcmp(argv[1], "exit-signal") == 0)
+        exitcode = h_exit_signal();
+    else if (strcmp(argv[1], "exit-success") == 0)
+        exitcode = h_exit_success();
+    else if (strcmp(argv[1], "stdout-stderr") == 0) {
+        check_args(argc, argv, 3);
+        exitcode = h_stdout_stderr(argv[2]);
+    } else {
+        fprintf(stderr, "%s: Unknown helper %s\n", argv[0], argv[1]);
+        exitcode = EXIT_FAILURE;
+    }
+
+    return exitcode;
+}

Added: vendor/atf/dist/atf-c/detail/process_test.c
===================================================================
--- vendor/atf/dist/atf-c/detail/process_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/process_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,1159 @@
+/* Copyright (c) 2008 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/process.h"
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/defs.h"
+#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);
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions for testing of 'atf_process_fork'.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Testing of atf_process_fork is quite messy.  We want to be able to test
+ * all the possible combinations of stdout and stderr behavior to ensure
+ * that the streams are manipulated correctly.
+ *
+ * To do this, the do_fork function is a wrapper for atf_process_fork that
+ * issues stream-specific hooks before fork, while the child is running and
+ * after the child terminates.  We then provide test cases that just call
+ * do_fork with different hooks.
+ *
+ * The hooks are described by base_stream, and we then have one *_stream
+ * type for ever possible stream behavior.
+ */
+
+enum out_type { stdout_type, stderr_type };
+
+struct base_stream {
+    void (*init)(void *);
+    void (*process)(void *, atf_process_child_t *);
+    void (*fini)(void *);
+
+    /* m_sb is initialized by subclasses that need it, but all consumers
+     * must use m_sb_ptr, which may or may not point to m_sb.  This allows
+     * us to test the interface with a NULL value, which triggers a
+     * default behavior. */
+    atf_process_stream_t m_sb;
+    atf_process_stream_t *m_sb_ptr;
+    enum out_type m_type;
+};
+#define BASE_STREAM(ihook, phook, fhook, type) \
+    { .init = ihook, \
+      .process = phook, \
+      .fini = fhook, \
+      .m_type = type }
+
+static
+void
+check_file(const enum out_type type)
+{
+    switch (type) {
+    case stdout_type:
+        ATF_CHECK(atf_utils_grep_file("stdout: msg", "stdout"));
+        ATF_CHECK(!atf_utils_grep_file("stderr: msg", "stdout"));
+        break;
+    case stderr_type:
+        ATF_CHECK(atf_utils_grep_file("stderr: msg", "stderr"));
+        ATF_CHECK(!atf_utils_grep_file("stdout: msg", "stderr"));
+        break;
+    default:
+        UNREACHABLE;
+    }
+}
+
+struct capture_stream {
+    struct base_stream m_base;
+
+    char *m_msg;
+};
+#define CAPTURE_STREAM(type) \
+    { .m_base = BASE_STREAM(capture_stream_init, \
+                            capture_stream_process, \
+                            capture_stream_fini, \
+                            type) }
+
+static
+void
+capture_stream_init(void *v)
+{
+    struct capture_stream *s = v;
+
+    s->m_base.m_sb_ptr = &s->m_base.m_sb;
+    RE(atf_process_stream_init_capture(&s->m_base.m_sb));
+    s->m_msg = NULL;
+}
+
+static
+void
+capture_stream_process(void *v, atf_process_child_t *c)
+{
+    struct capture_stream *s = v;
+
+    switch (s->m_base.m_type) {
+    case stdout_type:
+        s->m_msg = atf_utils_readline(atf_process_child_stdout(c));
+        break;
+    case stderr_type:
+        s->m_msg = atf_utils_readline(atf_process_child_stderr(c));
+        break;
+    default:
+        UNREACHABLE;
+    }
+}
+
+static
+void
+capture_stream_fini(void *v)
+{
+    struct capture_stream *s = v;
+
+    switch (s->m_base.m_type) {
+    case stdout_type:
+        ATF_CHECK(atf_utils_grep_string("stdout: msg", s->m_msg));
+        ATF_CHECK(!atf_utils_grep_string("stderr: msg", s->m_msg));
+        break;
+    case stderr_type:
+        ATF_CHECK(!atf_utils_grep_string("stdout: msg", s->m_msg));
+        ATF_CHECK(atf_utils_grep_string("stderr: msg", s->m_msg));
+        break;
+    default:
+        UNREACHABLE;
+    }
+
+    free(s->m_msg);
+    atf_process_stream_fini(&s->m_base.m_sb);
+}
+
+struct connect_stream {
+    struct base_stream m_base;
+
+    int m_fd;
+};
+#define CONNECT_STREAM(type) \
+    { .m_base = BASE_STREAM(connect_stream_init, \
+                            NULL, \
+                            connect_stream_fini, \
+                            type) }
+
+static
+void
+connect_stream_init(void *v)
+{
+    struct connect_stream *s = v;
+    int src_fd;
+
+    switch (s->m_base.m_type) {
+    case stdout_type:
+        src_fd = STDOUT_FILENO;
+        s->m_fd = open("stdout", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+        break;
+    case stderr_type:
+        src_fd = STDERR_FILENO;
+        s->m_fd = open("stderr", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+        break;
+    default:
+        UNREACHABLE;
+        src_fd = -1;
+    }
+    ATF_REQUIRE(s->m_fd != -1);
+
+    s->m_base.m_sb_ptr = &s->m_base.m_sb;
+    RE(atf_process_stream_init_connect(&s->m_base.m_sb, src_fd, s->m_fd));
+}
+
+static
+void
+connect_stream_fini(void *v)
+{
+    struct connect_stream *s = v;
+
+    ATF_REQUIRE(close(s->m_fd) != -1);
+
+    atf_process_stream_fini(&s->m_base.m_sb);
+
+    check_file(s->m_base.m_type);
+}
+
+struct inherit_stream {
+    struct base_stream m_base;
+    int m_fd;
+
+    int m_old_fd;
+};
+#define INHERIT_STREAM(type) \
+    { .m_base = BASE_STREAM(inherit_stream_init, \
+                            NULL, \
+                            inherit_stream_fini, \
+                            type) }
+
+static
+void
+inherit_stream_init(void *v)
+{
+    struct inherit_stream *s = v;
+    const char *name;
+
+    s->m_base.m_sb_ptr = &s->m_base.m_sb;
+    RE(atf_process_stream_init_inherit(&s->m_base.m_sb));
+
+    switch (s->m_base.m_type) {
+    case stdout_type:
+        s->m_fd = STDOUT_FILENO;
+        name = "stdout";
+        break;
+    case stderr_type:
+        s->m_fd = STDERR_FILENO;
+        name = "stderr";
+        break;
+    default:
+        UNREACHABLE;
+        name = NULL;
+    }
+
+    s->m_old_fd = dup(s->m_fd);
+    ATF_REQUIRE(s->m_old_fd != -1);
+    ATF_REQUIRE(close(s->m_fd) != -1);
+    ATF_REQUIRE_EQ(open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644),
+                   s->m_fd);
+}
+
+static
+void
+inherit_stream_fini(void *v)
+{
+    struct inherit_stream *s = v;
+
+    ATF_REQUIRE(dup2(s->m_old_fd, s->m_fd) != -1);
+    ATF_REQUIRE(close(s->m_old_fd) != -1);
+
+    atf_process_stream_fini(&s->m_base.m_sb);
+
+    check_file(s->m_base.m_type);
+}
+
+#define default_stream inherit_stream
+#define DEFAULT_STREAM(type) \
+    { .m_base = BASE_STREAM(default_stream_init, \
+                            NULL, \
+                            default_stream_fini, \
+                            type) }
+
+static
+void
+default_stream_init(void *v)
+{
+    struct inherit_stream *s = v;
+
+    inherit_stream_init(v);
+    s->m_base.m_sb_ptr = NULL;
+}
+
+static
+void
+default_stream_fini(void *v)
+{
+    inherit_stream_fini(v);
+}
+
+struct redirect_fd_stream {
+    struct base_stream m_base;
+
+    int m_fd;
+};
+#define REDIRECT_FD_STREAM(type) \
+    { .m_base = BASE_STREAM(redirect_fd_stream_init, \
+                            NULL, \
+                            redirect_fd_stream_fini, \
+                            type) }
+
+static
+void
+redirect_fd_stream_init(void *v)
+{
+    struct redirect_fd_stream *s = v;
+
+    switch (s->m_base.m_type) {
+    case stdout_type:
+        s->m_fd = open("stdout", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+        break;
+    case stderr_type:
+        s->m_fd = open("stderr", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+        break;
+    default:
+        UNREACHABLE;
+    }
+    ATF_REQUIRE(s->m_fd != -1);
+
+    s->m_base.m_sb_ptr = &s->m_base.m_sb;
+    RE(atf_process_stream_init_redirect_fd(&s->m_base.m_sb, s->m_fd));
+}
+
+static
+void
+redirect_fd_stream_fini(void *v)
+{
+    struct redirect_fd_stream *s = v;
+
+    ATF_REQUIRE(close(s->m_fd) != -1);
+
+    atf_process_stream_fini(&s->m_base.m_sb);
+
+    check_file(s->m_base.m_type);
+}
+
+struct redirect_path_stream {
+    struct base_stream m_base;
+
+    atf_fs_path_t m_path;
+};
+#define REDIRECT_PATH_STREAM(type) \
+    { .m_base = BASE_STREAM(redirect_path_stream_init, \
+                            NULL, \
+                            redirect_path_stream_fini, \
+                            type) }
+
+static
+void
+redirect_path_stream_init(void *v)
+{
+    struct redirect_path_stream *s = v;
+
+    switch (s->m_base.m_type) {
+    case stdout_type:
+        RE(atf_fs_path_init_fmt(&s->m_path, "stdout"));
+        break;
+    case stderr_type:
+        RE(atf_fs_path_init_fmt(&s->m_path, "stderr"));
+        break;
+    default:
+        UNREACHABLE;
+    }
+
+    s->m_base.m_sb_ptr = &s->m_base.m_sb;
+    RE(atf_process_stream_init_redirect_path(&s->m_base.m_sb, &s->m_path));
+}
+
+static
+void
+redirect_path_stream_fini(void *v)
+{
+    struct redirect_path_stream *s = v;
+
+    atf_process_stream_fini(&s->m_base.m_sb);
+
+    atf_fs_path_fini(&s->m_path);
+
+    check_file(s->m_base.m_type);
+}
+
+static void child_print(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
+
+struct child_print_data {
+    const char *m_msg;
+};
+
+static
+void
+child_print(void *v)
+{
+    struct child_print_data *cpd = v;
+
+    fprintf(stdout, "stdout: %s\n", cpd->m_msg);
+    fprintf(stderr, "stderr: %s\n", cpd->m_msg);
+
+    exit(EXIT_SUCCESS);
+}
+
+static
+void
+do_fork(const struct base_stream *outfs, void *out,
+        const struct base_stream *errfs, void *err)
+{
+    atf_process_child_t child;
+    atf_process_status_t status;
+    struct child_print_data cpd = { "msg" };
+
+    outfs->init(out);
+    errfs->init(err);
+
+    RE(atf_process_fork(&child, child_print, outfs->m_sb_ptr,
+                        errfs->m_sb_ptr, &cpd));
+    if (outfs->process != NULL)
+        outfs->process(out, &child);
+    if (errfs->process != NULL)
+        errfs->process(err, &child);
+    RE(atf_process_child_wait(&child, &status));
+
+    outfs->fini(out);
+    errfs->fini(err);
+
+    atf_process_status_fini(&status);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "stream" type.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(stream_init_capture);
+ATF_TC_HEAD(stream_init_capture, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the "
+                      "atf_process_stream_init_capture function");
+}
+ATF_TC_BODY(stream_init_capture, tc)
+{
+    atf_process_stream_t sb;
+
+    RE(atf_process_stream_init_capture(&sb));
+
+    ATF_CHECK_EQ(atf_process_stream_type(&sb),
+                 atf_process_stream_type_capture);
+
+    atf_process_stream_fini(&sb);
+}
+
+ATF_TC(stream_init_connect);
+ATF_TC_HEAD(stream_init_connect, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the "
+                      "atf_process_stream_init_connect function");
+}
+ATF_TC_BODY(stream_init_connect, tc)
+{
+    atf_process_stream_t sb;
+
+    RE(atf_process_stream_init_connect(&sb, 1, 2));
+
+    ATF_CHECK_EQ(atf_process_stream_type(&sb),
+                 atf_process_stream_type_connect);
+
+    atf_process_stream_fini(&sb);
+}
+
+ATF_TC(stream_init_inherit);
+ATF_TC_HEAD(stream_init_inherit, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the "
+                      "atf_process_stream_init_inherit function");
+}
+ATF_TC_BODY(stream_init_inherit, tc)
+{
+    atf_process_stream_t sb;
+
+    RE(atf_process_stream_init_inherit(&sb));
+
+    ATF_CHECK_EQ(atf_process_stream_type(&sb),
+                 atf_process_stream_type_inherit);
+
+    atf_process_stream_fini(&sb);
+}
+
+ATF_TC(stream_init_redirect_fd);
+ATF_TC_HEAD(stream_init_redirect_fd, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the "
+                      "atf_process_stream_init_redirect_fd function");
+}
+ATF_TC_BODY(stream_init_redirect_fd, tc)
+{
+    atf_process_stream_t sb;
+
+    RE(atf_process_stream_init_redirect_fd(&sb, 1));
+
+    ATF_CHECK_EQ(atf_process_stream_type(&sb),
+                 atf_process_stream_type_redirect_fd);
+
+    atf_process_stream_fini(&sb);
+}
+
+ATF_TC(stream_init_redirect_path);
+ATF_TC_HEAD(stream_init_redirect_path, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the "
+                      "atf_process_stream_init_redirect_path function");
+}
+ATF_TC_BODY(stream_init_redirect_path, tc)
+{
+    atf_process_stream_t sb;
+    atf_fs_path_t path;
+
+    RE(atf_fs_path_init_fmt(&path, "foo"));
+    RE(atf_process_stream_init_redirect_path(&sb, &path));
+
+    ATF_CHECK_EQ(atf_process_stream_type(&sb),
+                 atf_process_stream_type_redirect_path);
+
+    atf_process_stream_fini(&sb);
+    atf_fs_path_fini(&path);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "status" type.
+ * --------------------------------------------------------------------- */
+
+static void child_exit_success(void) ATF_DEFS_ATTRIBUTE_NORETURN;
+static void child_exit_failure(void) ATF_DEFS_ATTRIBUTE_NORETURN;
+static void child_sigkill(void) ATF_DEFS_ATTRIBUTE_NORETURN;
+static void child_sigquit(void) ATF_DEFS_ATTRIBUTE_NORETURN;
+static void child_sigterm(void) ATF_DEFS_ATTRIBUTE_NORETURN;
+
+void
+child_exit_success(void)
+{
+    exit(EXIT_SUCCESS);
+}
+
+void
+child_exit_failure(void)
+{
+    exit(EXIT_FAILURE);
+}
+
+void
+child_sigkill(void)
+{
+    kill(getpid(), SIGKILL);
+    abort();
+}
+
+void
+child_sigquit(void)
+{
+    kill(getpid(), SIGQUIT);
+    abort();
+}
+
+void
+child_sigterm(void)
+{
+    kill(getpid(), SIGTERM);
+    abort();
+}
+
+static
+int
+fork_and_wait_child(void (*child_func)(void))
+{
+    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);
+    }
+
+    return status;
+}
+
+ATF_TC(status_exited);
+ATF_TC_HEAD(status_exited, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the status type for processes "
+                      "that exit cleanly");
+}
+ATF_TC_BODY(status_exited, tc)
+{
+    {
+        const int rawstatus = fork_and_wait_child(child_exit_success);
+        atf_process_status_t s;
+        RE(atf_process_status_init(&s, rawstatus));
+        ATF_CHECK(atf_process_status_exited(&s));
+        ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_SUCCESS);
+        ATF_CHECK(!atf_process_status_signaled(&s));
+        atf_process_status_fini(&s);
+    }
+
+    {
+        const int rawstatus = fork_and_wait_child(child_exit_failure);
+        atf_process_status_t s;
+        RE(atf_process_status_init(&s, rawstatus));
+        ATF_CHECK(atf_process_status_exited(&s));
+        ATF_CHECK_EQ(atf_process_status_exitstatus(&s), EXIT_FAILURE);
+        ATF_CHECK(!atf_process_status_signaled(&s));
+        atf_process_status_fini(&s);
+    }
+}
+
+ATF_TC(status_signaled);
+ATF_TC_HEAD(status_signaled, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the status type for processes "
+                      "that end due to a signal");
+}
+ATF_TC_BODY(status_signaled, tc)
+{
+    {
+        const int rawstatus = fork_and_wait_child(child_sigkill);
+        atf_process_status_t s;
+        RE(atf_process_status_init(&s, rawstatus));
+        ATF_CHECK(!atf_process_status_exited(&s));
+        ATF_CHECK(atf_process_status_signaled(&s));
+        ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGKILL);
+        ATF_CHECK(!atf_process_status_coredump(&s));
+        atf_process_status_fini(&s);
+    }
+
+    {
+        const int rawstatus = fork_and_wait_child(child_sigterm);
+        atf_process_status_t s;
+        RE(atf_process_status_init(&s, rawstatus));
+        ATF_CHECK(!atf_process_status_exited(&s));
+        ATF_CHECK(atf_process_status_signaled(&s));
+        ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGTERM);
+        ATF_CHECK(!atf_process_status_coredump(&s));
+        atf_process_status_fini(&s);
+    }
+}
+
+ATF_TC(status_coredump);
+ATF_TC_HEAD(status_coredump, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the status type for processes "
+                      "that crash");
+}
+ATF_TC_BODY(status_coredump, tc)
+{
+    struct rlimit rl;
+    rl.rlim_cur = RLIM_INFINITY;
+    rl.rlim_max = RLIM_INFINITY;
+    if (setrlimit(RLIMIT_CORE, &rl) == -1)
+        atf_tc_skip("Cannot unlimit the core file size; check limits "
+                    "manually");
+
+    const int rawstatus = fork_and_wait_child(child_sigquit);
+    atf_process_status_t s;
+    RE(atf_process_status_init(&s, rawstatus));
+    ATF_CHECK(!atf_process_status_exited(&s));
+    ATF_CHECK(atf_process_status_signaled(&s));
+    ATF_CHECK_EQ(atf_process_status_termsig(&s), SIGQUIT);
+    ATF_CHECK(atf_process_status_coredump(&s));
+    atf_process_status_fini(&s);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "child" type.
+ * --------------------------------------------------------------------- */
+
+static void child_report_pid(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
+
+static
+void
+child_report_pid(void *v ATF_DEFS_ATTRIBUTE_UNUSED)
+{
+    const pid_t pid = getpid();
+    if (write(STDOUT_FILENO, &pid, sizeof(pid)) != sizeof(pid))
+        abort();
+    fprintf(stderr, "Reporting %d to parent\n", (int)getpid());
+    exit(EXIT_SUCCESS);
+}
+
+ATF_TC(child_pid);
+ATF_TC_HEAD(child_pid, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the correctness of the pid "
+                      "stored in the child type");
+}
+ATF_TC_BODY(child_pid, tc)
+{
+    atf_process_stream_t outsb, errsb;
+    atf_process_child_t child;
+    atf_process_status_t status;
+    pid_t pid;
+
+    RE(atf_process_stream_init_capture(&outsb));
+    RE(atf_process_stream_init_inherit(&errsb));
+
+    RE(atf_process_fork(&child, child_report_pid, &outsb, &errsb, NULL));
+    ATF_CHECK_EQ(read(atf_process_child_stdout(&child), &pid, sizeof(pid)),
+                 sizeof(pid));
+    printf("Expected PID: %d\n", (int)atf_process_child_pid(&child));
+    printf("Actual PID: %d\n", (int)pid);
+    ATF_CHECK_EQ(atf_process_child_pid(&child), pid);
+
+    RE(atf_process_child_wait(&child, &status));
+    atf_process_status_fini(&status);
+
+    atf_process_stream_fini(&outsb);
+    atf_process_stream_fini(&errsb);
+}
+
+static
+void
+child_loop(void *v ATF_DEFS_ATTRIBUTE_UNUSED)
+{
+    for (;;)
+        sleep(1);
+}
+
+static
+void
+nop_signal(int sig ATF_DEFS_ATTRIBUTE_UNUSED)
+{
+}
+
+static
+void
+child_spawn_loop_and_wait_eintr(void *v ATF_DEFS_ATTRIBUTE_UNUSED)
+{
+    atf_process_child_t child;
+    atf_process_status_t status;
+    struct sigaction sighup, old_sighup;
+
+#define RE_ABORT(expr) \
+    do { \
+        atf_error_t _aux_err = expr; \
+        if (atf_is_error(_aux_err)) { \
+            atf_error_free(_aux_err); \
+            abort(); \
+        } \
+    } while (0)
+
+    {
+        atf_process_stream_t outsb, errsb;
+
+        RE_ABORT(atf_process_stream_init_capture(&outsb));
+        RE_ABORT(atf_process_stream_init_inherit(&errsb));
+        RE_ABORT(atf_process_fork(&child, child_loop, &outsb, &errsb, NULL));
+        atf_process_stream_fini(&outsb);
+        atf_process_stream_fini(&errsb);
+    }
+
+    sighup.sa_handler = nop_signal;
+    sigemptyset(&sighup.sa_mask);
+    sighup.sa_flags = 0;
+    if (sigaction(SIGHUP, &sighup, &old_sighup) == -1)
+        abort();
+
+    printf("waiting\n");
+    fflush(stdout);
+
+    fprintf(stderr, "Child entering wait(2)\n");
+    atf_error_t err = atf_process_child_wait(&child, &status);
+    fprintf(stderr, "Child's wait(2) terminated\n");
+    if (!atf_is_error(err)) {
+        fprintf(stderr, "wait completed successfully (not interrupted)\n");
+        abort();
+    }
+    if (!atf_error_is(err, "libc")) {
+        fprintf(stderr, "wait did not raise libc_error\n");
+        abort();
+    }
+    if (atf_libc_error_code(err) != EINTR) {
+        fprintf(stderr, "libc_error is not EINTR\n");
+        abort();
+    }
+    atf_error_free(err);
+
+    sigaction(SIGHUP, &old_sighup, NULL);
+
+    fprintf(stderr, "Child is killing subchild\n");
+    kill(atf_process_child_pid(&child), SIGTERM);
+
+    RE_ABORT(atf_process_child_wait(&child, &status));
+    atf_process_status_fini(&status);
+
+#undef RE_ABORT
+
+    exit(EXIT_SUCCESS);
+}
+
+ATF_TC(child_wait_eintr);
+ATF_TC_HEAD(child_wait_eintr, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the interruption of the wait "
+                      "method by an external signal, and the return of "
+                      "an EINTR error");
+    atf_tc_set_md_var(tc, "timeout", "30");
+}
+ATF_TC_BODY(child_wait_eintr, tc)
+{
+    atf_process_child_t child;
+    atf_process_status_t status;
+
+    {
+        atf_process_stream_t outsb, errsb;
+
+        RE(atf_process_stream_init_capture(&outsb));
+        RE(atf_process_stream_init_inherit(&errsb));
+        RE(atf_process_fork(&child, child_spawn_loop_and_wait_eintr,
+                            &outsb, &errsb, NULL));
+        atf_process_stream_fini(&outsb);
+        atf_process_stream_fini(&errsb);
+    }
+
+    {
+        /* Wait until the child process performs the wait call.  This is
+         * racy, because the message we get from it is sent *before*
+         * doing the real system call... but I can't figure any other way
+         * to do this. */
+        char buf[16];
+        printf("Waiting for child to issue wait(2)\n");
+        ATF_REQUIRE(read(atf_process_child_stdout(&child), buf,
+                         sizeof(buf)) > 0);
+        sleep(1);
+    }
+
+    printf("Interrupting child's wait(2) call\n");
+    kill(atf_process_child_pid(&child), SIGHUP);
+
+    printf("Waiting for child's completion\n");
+    RE(atf_process_child_wait(&child, &status));
+    ATF_REQUIRE(atf_process_status_exited(&status));
+    ATF_REQUIRE_EQ(atf_process_status_exitstatus(&status), EXIT_SUCCESS);
+    atf_process_status_fini(&status);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+do_exec(const atf_tc_t *tc, const char *helper_name, atf_process_status_t *s,
+        void (*prehook)(void))
+{
+    atf_fs_path_t process_helpers;
+    const char *argv[3];
+
+    get_process_helpers_path(tc, true, &process_helpers);
+
+    argv[0] = atf_fs_path_cstring(&process_helpers);
+    argv[1] = helper_name;
+    argv[2] = NULL;
+    printf("Executing %s %s\n", argv[0], argv[1]);
+
+    RE(atf_process_exec_array(s, &process_helpers, argv, NULL, NULL, prehook));
+    atf_fs_path_fini(&process_helpers);
+}
+
+static
+void
+check_line(int fd, const char *exp)
+{
+    char *line = atf_utils_readline(fd);
+    ATF_CHECK(line != NULL);
+    ATF_CHECK_STREQ_MSG(exp, line, "read: '%s', expected: '%s'", line, exp);
+    free(line);
+}
+
+ATF_TC(exec_failure);
+ATF_TC_HEAD(exec_failure, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests execing a command");
+}
+ATF_TC_BODY(exec_failure, tc)
+{
+    atf_process_status_t status;
+
+    do_exec(tc, "exit-failure", &status, NULL);
+    ATF_CHECK(atf_process_status_exited(&status));
+    ATF_CHECK_EQ(atf_process_status_exitstatus(&status), EXIT_FAILURE);
+    atf_process_status_fini(&status);
+}
+
+ATF_TC(exec_list);
+ATF_TC_HEAD(exec_list, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests execing a command");
+}
+ATF_TC_BODY(exec_list, tc)
+{
+    atf_fs_path_t process_helpers;
+    atf_list_t argv;
+    atf_process_status_t status;
+
+    RE(atf_list_init(&argv));
+
+    get_process_helpers_path(tc, true, &process_helpers);
+    atf_list_append(&argv, strdup(atf_fs_path_cstring(&process_helpers)), true);
+    atf_list_append(&argv, strdup("echo"), true);
+    atf_list_append(&argv, strdup("test-message"), true);
+    {
+        atf_fs_path_t outpath;
+        atf_process_stream_t outsb;
+
+        RE(atf_fs_path_init_fmt(&outpath, "stdout"));
+        RE(atf_process_stream_init_redirect_path(&outsb, &outpath));
+        RE(atf_process_exec_list(&status, &process_helpers, &argv, &outsb,
+                                 NULL, NULL));
+        atf_process_stream_fini(&outsb);
+        atf_fs_path_fini(&outpath);
+    }
+    atf_list_fini(&argv);
+
+    ATF_CHECK(atf_process_status_exited(&status));
+    ATF_CHECK_EQ(atf_process_status_exitstatus(&status), EXIT_SUCCESS);
+
+    {
+        int fd = open("stdout", O_RDONLY);
+        ATF_CHECK(fd != -1);
+        check_line(fd, "test-message");
+        close(fd);
+    }
+
+    atf_process_status_fini(&status);
+    atf_fs_path_fini(&process_helpers);
+}
+
+static void
+exit_early(void)
+{
+    exit(80);
+}
+
+ATF_TC(exec_prehook);
+ATF_TC_HEAD(exec_prehook, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests execing a command with a prehook");
+}
+ATF_TC_BODY(exec_prehook, tc)
+{
+    atf_process_status_t status;
+
+    do_exec(tc, "exit-success", &status, exit_early);
+    ATF_CHECK(atf_process_status_exited(&status));
+    ATF_CHECK_EQ(atf_process_status_exitstatus(&status), 80);
+    atf_process_status_fini(&status);
+}
+
+ATF_TC(exec_success);
+ATF_TC_HEAD(exec_success, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests execing a command");
+}
+ATF_TC_BODY(exec_success, tc)
+{
+    atf_process_status_t status;
+
+    do_exec(tc, "exit-success", &status, NULL);
+    ATF_CHECK(atf_process_status_exited(&status));
+    ATF_CHECK_EQ(atf_process_status_exitstatus(&status), EXIT_SUCCESS);
+    atf_process_status_fini(&status);
+}
+
+static const int exit_v_null = 1;
+static const int exit_v_notnull = 2;
+
+static
+void
+child_cookie(void *v)
+{
+    if (v == NULL)
+        exit(exit_v_null);
+    else
+        exit(exit_v_notnull);
+
+    UNREACHABLE;
+}
+
+ATF_TC(fork_cookie);
+ATF_TC_HEAD(fork_cookie, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests forking a child, with "
+                      "a null and non-null data cookie");
+}
+ATF_TC_BODY(fork_cookie, tc)
+{
+    atf_process_stream_t outsb, errsb;
+
+    RE(atf_process_stream_init_inherit(&outsb));
+    RE(atf_process_stream_init_inherit(&errsb));
+
+    {
+        atf_process_child_t child;
+        atf_process_status_t status;
+
+        RE(atf_process_fork(&child, child_cookie, &outsb, &errsb, NULL));
+        RE(atf_process_child_wait(&child, &status));
+
+        ATF_CHECK(atf_process_status_exited(&status));
+        ATF_CHECK_EQ(atf_process_status_exitstatus(&status), exit_v_null);
+
+        atf_process_status_fini(&status);
+    }
+
+    {
+        atf_process_child_t child;
+        atf_process_status_t status;
+        int dummy_int;
+
+        RE(atf_process_fork(&child, child_cookie, &outsb, &errsb, &dummy_int));
+        RE(atf_process_child_wait(&child, &status));
+
+        ATF_CHECK(atf_process_status_exited(&status));
+        ATF_CHECK_EQ(atf_process_status_exitstatus(&status), exit_v_notnull);
+
+        atf_process_status_fini(&status);
+    }
+
+    atf_process_stream_fini(&errsb);
+    atf_process_stream_fini(&outsb);
+}
+
+#define TC_FORK_STREAMS(outlc, outuc, errlc, erruc) \
+    ATF_TC(fork_out_ ## outlc ## _err_ ## errlc); \
+    ATF_TC_HEAD(fork_out_ ## outlc ## _err_ ## errlc, tc) \
+    { \
+        atf_tc_set_md_var(tc, "descr", "Tests forking a child, with " \
+                          "stdout " #outlc " and stderr " #errlc); \
+    } \
+    ATF_TC_BODY(fork_out_ ## outlc ## _err_ ## errlc, tc) \
+    { \
+        struct outlc ## _stream out = outuc ## _STREAM(stdout_type); \
+        struct errlc ## _stream err = erruc ## _STREAM(stderr_type); \
+        do_fork(&out.m_base, &out, &err.m_base, &err); \
+    }
+
+TC_FORK_STREAMS(capture, CAPTURE, capture, CAPTURE);
+TC_FORK_STREAMS(capture, CAPTURE, connect, CONNECT);
+TC_FORK_STREAMS(capture, CAPTURE, default, DEFAULT);
+TC_FORK_STREAMS(capture, CAPTURE, inherit, INHERIT);
+TC_FORK_STREAMS(capture, CAPTURE, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(capture, CAPTURE, redirect_path, REDIRECT_PATH);
+TC_FORK_STREAMS(connect, CONNECT, capture, CAPTURE);
+TC_FORK_STREAMS(connect, CONNECT, connect, CONNECT);
+TC_FORK_STREAMS(connect, CONNECT, default, DEFAULT);
+TC_FORK_STREAMS(connect, CONNECT, inherit, INHERIT);
+TC_FORK_STREAMS(connect, CONNECT, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(connect, CONNECT, redirect_path, REDIRECT_PATH);
+TC_FORK_STREAMS(default, DEFAULT, capture, CAPTURE);
+TC_FORK_STREAMS(default, DEFAULT, connect, CONNECT);
+TC_FORK_STREAMS(default, DEFAULT, default, DEFAULT);
+TC_FORK_STREAMS(default, DEFAULT, inherit, INHERIT);
+TC_FORK_STREAMS(default, DEFAULT, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(default, DEFAULT, redirect_path, REDIRECT_PATH);
+TC_FORK_STREAMS(inherit, INHERIT, capture, CAPTURE);
+TC_FORK_STREAMS(inherit, INHERIT, connect, CONNECT);
+TC_FORK_STREAMS(inherit, INHERIT, default, DEFAULT);
+TC_FORK_STREAMS(inherit, INHERIT, inherit, INHERIT);
+TC_FORK_STREAMS(inherit, INHERIT, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(inherit, INHERIT, redirect_path, REDIRECT_PATH);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, capture, CAPTURE);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, connect, CONNECT);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, default, DEFAULT);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, inherit, INHERIT);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(redirect_fd, REDIRECT_FD, redirect_path, REDIRECT_PATH);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, capture, CAPTURE);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, connect, CONNECT);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, default, DEFAULT);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, inherit, INHERIT);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, redirect_fd, REDIRECT_FD);
+TC_FORK_STREAMS(redirect_path, REDIRECT_PATH, redirect_path, REDIRECT_PATH);
+
+#undef TC_FORK_STREAMS
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    /* Add the tests for the "stream" type. */
+    ATF_TP_ADD_TC(tp, stream_init_capture);
+    ATF_TP_ADD_TC(tp, stream_init_connect);
+    ATF_TP_ADD_TC(tp, stream_init_inherit);
+    ATF_TP_ADD_TC(tp, stream_init_redirect_fd);
+    ATF_TP_ADD_TC(tp, stream_init_redirect_path);
+
+    /* Add the tests for the "status" type. */
+    ATF_TP_ADD_TC(tp, status_exited);
+    ATF_TP_ADD_TC(tp, status_signaled);
+    ATF_TP_ADD_TC(tp, status_coredump);
+
+    /* Add the tests for the "child" type. */
+    ATF_TP_ADD_TC(tp, child_pid);
+    ATF_TP_ADD_TC(tp, child_wait_eintr);
+
+    /* Add the tests for the free functions. */
+    ATF_TP_ADD_TC(tp, exec_failure);
+    ATF_TP_ADD_TC(tp, exec_list);
+    ATF_TP_ADD_TC(tp, exec_prehook);
+    ATF_TP_ADD_TC(tp, exec_success);
+    ATF_TP_ADD_TC(tp, fork_cookie);
+    ATF_TP_ADD_TC(tp, fork_out_capture_err_capture);
+    ATF_TP_ADD_TC(tp, fork_out_capture_err_connect);
+    ATF_TP_ADD_TC(tp, fork_out_capture_err_default);
+    ATF_TP_ADD_TC(tp, fork_out_capture_err_inherit);
+    ATF_TP_ADD_TC(tp, fork_out_capture_err_redirect_fd);
+    ATF_TP_ADD_TC(tp, fork_out_capture_err_redirect_path);
+    ATF_TP_ADD_TC(tp, fork_out_connect_err_capture);
+    ATF_TP_ADD_TC(tp, fork_out_connect_err_connect);
+    ATF_TP_ADD_TC(tp, fork_out_connect_err_default);
+    ATF_TP_ADD_TC(tp, fork_out_connect_err_inherit);
+    ATF_TP_ADD_TC(tp, fork_out_connect_err_redirect_fd);
+    ATF_TP_ADD_TC(tp, fork_out_connect_err_redirect_path);
+    ATF_TP_ADD_TC(tp, fork_out_default_err_capture);
+    ATF_TP_ADD_TC(tp, fork_out_default_err_connect);
+    ATF_TP_ADD_TC(tp, fork_out_default_err_default);
+    ATF_TP_ADD_TC(tp, fork_out_default_err_inherit);
+    ATF_TP_ADD_TC(tp, fork_out_default_err_redirect_fd);
+    ATF_TP_ADD_TC(tp, fork_out_default_err_redirect_path);
+    ATF_TP_ADD_TC(tp, fork_out_inherit_err_capture);
+    ATF_TP_ADD_TC(tp, fork_out_inherit_err_connect);
+    ATF_TP_ADD_TC(tp, fork_out_inherit_err_default);
+    ATF_TP_ADD_TC(tp, fork_out_inherit_err_inherit);
+    ATF_TP_ADD_TC(tp, fork_out_inherit_err_redirect_fd);
+    ATF_TP_ADD_TC(tp, fork_out_inherit_err_redirect_path);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_capture);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_connect);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_default);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_inherit);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_redirect_fd);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_fd_err_redirect_path);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_capture);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_connect);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_default);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_inherit);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_redirect_fd);
+    ATF_TP_ADD_TC(tp, fork_out_redirect_path_err_redirect_path);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/detail/sanity.c
===================================================================
--- vendor/atf/dist/atf-c/detail/sanity.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/sanity.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,74 @@
+/* Copyright (c) 2008 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/sanity.h"
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <err.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static
+void
+fail(const char *fmt, ...)
+{
+    va_list ap;
+    char buf[4096];
+
+    va_start(ap, fmt);
+    vsnprintf(buf, sizeof(buf), fmt, ap);
+    va_end(ap);
+    warnx("%s", buf);
+    warnx("%s", "");
+    warnx("This is probably a bug in this application or one of the "
+          "libraries it uses.  If you believe this problem is caused "
+          "by, or is related to " PACKAGE_STRING ", please report it "
+          "to " PACKAGE_BUGREPORT " and provide as many details as "
+          "possible describing how you got to this condition.");
+
+    abort();
+}
+
+void
+atf_sanity_inv(const char *file, int line, const char *cond)
+{
+    fail("Invariant check failed at %s:%d: %s", file, line, cond);
+}
+
+void
+atf_sanity_pre(const char *file, int line, const char *cond)
+{
+    fail("Precondition check failed at %s:%d: %s", file, line, cond);
+}
+
+void
+atf_sanity_post(const char *file, int line, const char *cond)
+{
+    fail("Postcondition check failed at %s:%d: %s", file, line, cond);
+}

Added: vendor/atf/dist/atf-c/detail/sanity.h
===================================================================
--- vendor/atf/dist/atf-c/detail/sanity.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/sanity.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,69 @@
+/* Copyright (c) 2008 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_C_DETAIL_SANITY_H)
+#define ATF_C_DETAIL_SANITY_H
+
+void atf_sanity_inv(const char *, int, const char *);
+void atf_sanity_pre(const char *, int, const char *);
+void atf_sanity_post(const char *, int, const char *);
+
+#if !defined(NDEBUG)
+
+#define INV(x) \
+    do { \
+        if (!(x)) \
+            atf_sanity_inv(__FILE__, __LINE__, #x); \
+    } while (0)
+#define PRE(x) \
+    do { \
+        if (!(x)) \
+            atf_sanity_pre(__FILE__, __LINE__, #x); \
+    } while (0)
+#define POST(x) \
+    do { \
+        if (!(x)) \
+            atf_sanity_post(__FILE__, __LINE__, #x); \
+    } while (0)
+
+#else /* defined(NDEBUG) */
+
+#define INV(x) \
+    do { \
+    } while (0)
+
+#define PRE(x) \
+    do { \
+    } while (0)
+
+#define POST(x) \
+    do { \
+    } while (0)
+
+#endif /* !defined(NDEBUG) */
+
+#define UNREACHABLE INV(0)
+
+#endif /* !defined(ATF_C_DETAIL_SANITY_H) */

Added: vendor/atf/dist/atf-c/detail/sanity_test.c
===================================================================
--- vendor/atf/dist/atf-c/detail/sanity_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/sanity_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,230 @@
+/* Copyright (c) 2008 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/sanity.h"
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/dynstr.h"
+#include "atf-c/detail/process.h"
+#include "atf-c/detail/test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+enum type { inv, pre, post, unreachable };
+
+struct test_data {
+    enum type m_type;
+    bool m_cond;
+};
+
+static void do_test_child(void *) ATF_DEFS_ATTRIBUTE_NORETURN;
+
+static
+void
+do_test_child(void *v)
+{
+    struct test_data *td = v;
+
+    switch (td->m_type) {
+    case inv:
+        INV(td->m_cond);
+        break;
+
+    case pre:
+        PRE(td->m_cond);
+        break;
+
+    case post:
+        POST(td->m_cond);
+        break;
+
+    case unreachable:
+        if (!td->m_cond)
+            UNREACHABLE;
+        break;
+    }
+
+    exit(EXIT_SUCCESS);
+}
+
+static
+void
+do_test(enum type t, bool cond)
+{
+    atf_process_child_t child;
+    atf_process_status_t status;
+    int nlines;
+    char *lines[3];
+
+    {
+        atf_process_stream_t outsb, errsb;
+        struct test_data td = { t, cond };
+
+        RE(atf_process_stream_init_inherit(&outsb));
+        RE(atf_process_stream_init_capture(&errsb));
+        RE(atf_process_fork(&child, do_test_child, &outsb, &errsb, &td));
+        atf_process_stream_fini(&errsb);
+        atf_process_stream_fini(&outsb);
+    }
+
+    nlines = 0;
+    while (nlines < 3 && (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(atf_process_status_signaled(&status));
+        ATF_REQUIRE(atf_process_status_termsig(&status) == SIGABRT);
+    } else {
+        ATF_REQUIRE(atf_process_status_exited(&status));
+        ATF_REQUIRE(atf_process_status_exitstatus(&status) == EXIT_SUCCESS);
+    }
+    atf_process_status_fini(&status);
+
+    if (!cond) {
+        switch (t) {
+        case inv:
+            ATF_REQUIRE(atf_utils_grep_string("Invariant", lines[0]));
+            break;
+
+        case pre:
+            ATF_REQUIRE(atf_utils_grep_string("Precondition", lines[0]));
+            break;
+
+        case post:
+            ATF_REQUIRE(atf_utils_grep_string("Postcondition", lines[0]));
+            break;
+
+        case unreachable:
+            ATF_REQUIRE(atf_utils_grep_string("Invariant", lines[0]));
+            break;
+        }
+
+        ATF_REQUIRE(atf_utils_grep_string(__FILE__, lines[0]));
+        ATF_REQUIRE(atf_utils_grep_string(PACKAGE_BUGREPORT, lines[2]));
+    }
+
+    while (nlines > 0) {
+        nlines--;
+        free(lines[nlines]);
+    }
+}
+
+static
+void
+require_ndebug(void)
+{
+#if defined(NDEBUG)
+    atf_tc_skip("Sanity checks not available; code built with -DNDEBUG");
+#endif
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(inv);
+ATF_TC_HEAD(inv, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the INV macro");
+}
+ATF_TC_BODY(inv, tc)
+{
+    require_ndebug();
+
+    do_test(inv, false);
+    do_test(inv, true);
+}
+
+ATF_TC(pre);
+ATF_TC_HEAD(pre, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the PRE macro");
+}
+ATF_TC_BODY(pre, tc)
+{
+    require_ndebug();
+
+    do_test(pre, false);
+    do_test(pre, true);
+}
+
+ATF_TC(post);
+ATF_TC_HEAD(post, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the POST macro");
+}
+ATF_TC_BODY(post, tc)
+{
+    require_ndebug();
+
+    do_test(post, false);
+    do_test(post, true);
+}
+
+ATF_TC(unreachable);
+ATF_TC_HEAD(unreachable, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the UNREACHABLE macro");
+}
+ATF_TC_BODY(unreachable, tc)
+{
+    require_ndebug();
+
+    do_test(unreachable, false);
+    do_test(unreachable, true);
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    ATF_TP_ADD_TC(tp, inv);
+    ATF_TP_ADD_TC(tp, pre);
+    ATF_TP_ADD_TC(tp, post);
+    ATF_TP_ADD_TC(tp, unreachable);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/detail/test_helpers.c
===================================================================
--- vendor/atf/dist/atf-c/detail/test_helpers.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/test_helpers.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,147 @@
+/* Copyright (c) 2008 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/test_helpers.h"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/build.h"
+#include "atf-c/check.h"
+#include "atf-c/detail/dynstr.h"
+#include "atf-c/detail/env.h"
+#include "atf-c/detail/fs.h"
+#include "atf-c/detail/process.h"
+#include "atf-c/error.h"
+
+bool
+build_check_c_o(const char *path)
+{
+    bool success;
+    atf_dynstr_t iflag;
+    const char *optargs[4];
+
+    RE(atf_dynstr_init_fmt(&iflag, "-I%s", atf_env_get_with_default(
+        "ATF_INCLUDEDIR", ATF_INCLUDEDIR)));
+
+    optargs[0] = atf_dynstr_cstring(&iflag);
+    optargs[1] = "-Wall";
+    optargs[2] = "-Werror";
+    optargs[3] = NULL;
+
+    RE(atf_check_build_c_o(path, "test.o", optargs, &success));
+
+    atf_dynstr_fini(&iflag);
+
+    return success;
+}
+
+bool
+build_check_c_o_srcdir(const atf_tc_t *tc, const char *sfile)
+{
+    atf_fs_path_t path;
+
+    RE(atf_fs_path_init_fmt(&path, "%s/%s",
+                            atf_tc_get_config_var(tc, "srcdir"), sfile));
+    const bool result = build_check_c_o(atf_fs_path_cstring(&path));
+    atf_fs_path_fini(&path);
+    return result;
+}
+
+void
+header_check(const char *hdrname)
+{
+    FILE *srcfile;
+    char failmsg[128];
+
+    srcfile = fopen("test.c", "w");
+    ATF_REQUIRE(srcfile != NULL);
+    fprintf(srcfile, "#include <%s>\n", hdrname);
+    fclose(srcfile);
+
+    snprintf(failmsg, sizeof(failmsg),
+             "Header check failed; %s is not self-contained", hdrname);
+
+    if (!build_check_c_o("test.c"))
+        atf_tc_fail("%s", failmsg);
+}
+
+void
+get_process_helpers_path(const atf_tc_t *tc, const bool is_detail,
+                         atf_fs_path_t *path)
+{
+    RE(atf_fs_path_init_fmt(path, "%s/%sprocess_helpers",
+                            atf_tc_get_config_var(tc, "srcdir"),
+                            is_detail ? "" : "detail/"));
+}
+
+struct run_h_tc_data {
+    atf_tc_t *m_tc;
+    const char *m_resname;
+};
+
+static
+void
+run_h_tc_child(void *v)
+{
+    struct run_h_tc_data *data = (struct run_h_tc_data *)v;
+
+    RE(atf_tc_run(data->m_tc, data->m_resname));
+}
+
+/* TODO: Investigate if it's worth to add this functionality as part of
+ * the public API.  I.e. a function to easily run a test case body in a
+ * subprocess. */
+void
+run_h_tc(atf_tc_t *tc, const char *outname, const char *errname,
+         const char *resname)
+{
+    atf_fs_path_t outpath, errpath;
+    atf_process_stream_t outb, errb;
+    atf_process_child_t child;
+    atf_process_status_t status;
+
+    RE(atf_fs_path_init_fmt(&outpath, outname));
+    RE(atf_fs_path_init_fmt(&errpath, errname));
+
+    struct run_h_tc_data data = { tc, resname };
+
+    RE(atf_process_stream_init_redirect_path(&outb, &outpath));
+    RE(atf_process_stream_init_redirect_path(&errb, &errpath));
+    RE(atf_process_fork(&child, run_h_tc_child, &outb, &errb, &data));
+    atf_process_stream_fini(&errb);
+    atf_process_stream_fini(&outb);
+
+    RE(atf_process_child_wait(&child, &status));
+    ATF_CHECK(atf_process_status_exited(&status));
+    atf_process_status_fini(&status);
+
+    atf_fs_path_fini(&errpath);
+    atf_fs_path_fini(&outpath);
+}

Added: vendor/atf/dist/atf-c/detail/test_helpers.h
===================================================================
--- vendor/atf/dist/atf-c/detail/test_helpers.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/test_helpers.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,75 @@
+/* Copyright (c) 2008 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_C_DETAIL_TEST_HELPERS_H)
+#   error "Cannot include test_helpers.h more than once."
+#else
+#   define ATF_C_DETAIL_TEST_HELPERS_H
+#endif
+
+#include <stdbool.h>
+
+#include <atf-c.h>
+
+#include <atf-c/error_fwd.h>
+#include <atf-c/tc.h>
+
+struct atf_dynstr;
+struct atf_fs_path;
+
+#define CE(stm) ATF_CHECK(!atf_is_error(stm))
+#define RE(stm) ATF_REQUIRE(!atf_is_error(stm))
+
+#define HEADER_TC(name, hdrname) \
+    ATF_TC(name); \
+    ATF_TC_HEAD(name, tc) \
+    { \
+        atf_tc_set_md_var(tc, "descr", "Tests that the " hdrname " file can " \
+            "be included on its own, without any prerequisites"); \
+    } \
+    ATF_TC_BODY(name, tc) \
+    { \
+        header_check(hdrname); \
+    }
+
+#define BUILD_TC(name, sfile, descr, failmsg) \
+    ATF_TC(name); \
+    ATF_TC_HEAD(name, tc) \
+    { \
+        atf_tc_set_md_var(tc, "descr", descr); \
+    } \
+    ATF_TC_BODY(name, tc) \
+    { \
+        if (!build_check_c_o_srcdir(tc, sfile)) \
+            atf_tc_fail("%s", failmsg); \
+    }
+
+bool build_check_c_o(const char *);
+bool build_check_c_o_srcdir(const atf_tc_t *, const char *);
+void header_check(const char *);
+void get_process_helpers_path(const atf_tc_t *, const bool,
+                              struct atf_fs_path *);
+bool read_line(int, struct atf_dynstr *);
+void run_h_tc(atf_tc_t *, const char *, const char *, const char *);

Added: vendor/atf/dist/atf-c/detail/text.c
===================================================================
--- vendor/atf/dist/atf-c/detail/text.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/text.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,180 @@
+/* Copyright (c) 2008 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/text.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "atf-c/detail/dynstr.h"
+#include "atf-c/detail/sanity.h"
+#include "atf-c/error.h"
+
+atf_error_t
+atf_text_for_each_word(const char *instr, const char *sep,
+                       atf_error_t (*func)(const char *, void *),
+                       void *data)
+{
+    atf_error_t err;
+    char *str, *str2, *last;
+
+    str = strdup(instr);
+    if (str == NULL) {
+        err = atf_no_memory_error();
+        goto out;
+    }
+
+    err = atf_no_error();
+    str2 = strtok_r(str, sep, &last);
+    while (str2 != NULL && !atf_is_error(err)) {
+        err = func(str2, data);
+        str2 = strtok_r(NULL, sep, &last);
+    }
+
+    free(str);
+out:
+    return err;
+}
+
+atf_error_t
+atf_text_format(char **dest, const char *fmt, ...)
+{
+    atf_error_t err;
+    va_list ap;
+
+    va_start(ap, fmt);
+    err = atf_text_format_ap(dest, fmt, ap);
+    va_end(ap);
+
+    return err;
+}
+
+atf_error_t
+atf_text_format_ap(char **dest, const char *fmt, va_list ap)
+{
+    atf_error_t err;
+    atf_dynstr_t tmp;
+    va_list ap2;
+
+    va_copy(ap2, ap);
+    err = atf_dynstr_init_ap(&tmp, fmt, ap2);
+    va_end(ap2);
+    if (!atf_is_error(err))
+        *dest = atf_dynstr_fini_disown(&tmp);
+
+    return err;
+}
+
+atf_error_t
+atf_text_split(const char *str, const char *delim, atf_list_t *words)
+{
+    atf_error_t err;
+    const char *end;
+    const char *iter;
+
+    err = atf_list_init(words);
+    if (atf_is_error(err))
+        goto err;
+
+    end = str + strlen(str);
+    INV(*end == '\0');
+    iter = str;
+    while (iter < end) {
+        const char *ptr;
+
+        INV(iter != NULL);
+        ptr = strstr(iter, delim);
+        if (ptr == NULL)
+            ptr = end;
+
+        INV(ptr >= iter);
+        if (ptr > iter) {
+            atf_dynstr_t word;
+
+            err = atf_dynstr_init_raw(&word, iter, ptr - iter);
+            if (atf_is_error(err))
+                goto err_list;
+
+            err = atf_list_append(words, atf_dynstr_fini_disown(&word), true);
+            if (atf_is_error(err))
+                goto err_list;
+        }
+
+        iter = ptr + strlen(delim);
+    }
+
+    INV(!atf_is_error(err));
+    return err;
+
+err_list:
+    atf_list_fini(words);
+err:
+    return err;
+}
+
+atf_error_t
+atf_text_to_bool(const char *str, bool *b)
+{
+    atf_error_t err;
+
+    if (strcasecmp(str, "yes") == 0 ||
+        strcasecmp(str, "true") == 0) {
+        *b = true;
+        err = atf_no_error();
+    } else if (strcasecmp(str, "no") == 0 ||
+               strcasecmp(str, "false") == 0) {
+        *b = false;
+        err = atf_no_error();
+    } else {
+        /* XXX Not really a libc error. */
+        err = atf_libc_error(EINVAL, "Cannot convert string '%s' "
+                             "to boolean", str);
+    }
+
+    return err;
+}
+
+atf_error_t
+atf_text_to_long(const char *str, long *l)
+{
+    atf_error_t err;
+    char *endptr;
+    long tmp;
+
+    errno = 0;
+    tmp = strtol(str, &endptr, 10);
+    if (str[0] == '\0' || *endptr != '\0')
+        err = atf_libc_error(EINVAL, "'%s' is not a number", str);
+    else if (errno == ERANGE || (tmp == LONG_MAX || tmp == LONG_MIN))
+        err = atf_libc_error(ERANGE, "'%s' is out of range", str);
+    else {
+        *l = tmp;
+        err = atf_no_error();
+    }
+
+    return err;
+}

Added: vendor/atf/dist/atf-c/detail/text.h
===================================================================
--- vendor/atf/dist/atf-c/detail/text.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/text.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,44 @@
+/* Copyright (c) 2008 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_C_DETAIL_TEXT_H)
+#define ATF_C_DETAIL_TEXT_H
+
+#include <stdarg.h>
+#include <stdbool.h>
+
+#include <atf-c/detail/list.h>
+#include <atf-c/error_fwd.h>
+
+atf_error_t atf_text_for_each_word(const char *, const char *,
+                                   atf_error_t (*)(const char *, void *),
+                                   void *);
+atf_error_t atf_text_format(char **, const char *, ...);
+atf_error_t atf_text_format_ap(char **, const char *, va_list);
+atf_error_t atf_text_split(const char *, const char *, atf_list_t *);
+atf_error_t atf_text_to_bool(const char *, bool *);
+atf_error_t atf_text_to_long(const char *, long *);
+
+#endif /* !defined(ATF_C_DETAIL_TEXT_H) */

Added: vendor/atf/dist/atf-c/detail/text_test.c
===================================================================
--- vendor/atf/dist/atf-c/detail/text_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/text_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,421 @@
+/* Copyright (c) 2008 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/text.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/sanity.h"
+#include "atf-c/detail/test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+#define REQUIRE_ERROR(exp) \
+    do { \
+        atf_error_t err = exp; \
+        ATF_REQUIRE(atf_is_error(err)); \
+        atf_error_free(err); \
+    } while (0)
+
+static
+size_t
+array_size(const char *words[])
+{
+    size_t count;
+    const char **word;
+
+    count = 0;
+    for (word = words; *word != NULL; word++)
+        count++;
+
+    return count;
+}
+
+static
+void
+check_split(const char *str, const char *delim, const char *words[])
+{
+    atf_list_t list;
+    const char **word;
+    size_t i;
+
+    printf("Splitting '%s' with delimiter '%s'\n", str, delim);
+    CE(atf_text_split(str, delim, &list));
+
+    printf("Expecting %zd words\n", array_size(words));
+    ATF_CHECK_EQ(atf_list_size(&list), array_size(words));
+
+    for (word = words, i = 0; *word != NULL; word++, i++) {
+        printf("Word at position %zd should be '%s'\n", i, words[i]);
+        ATF_CHECK_STREQ((const char *)atf_list_index_c(&list, i), words[i]);
+    }
+
+    atf_list_fini(&list);
+}
+
+static
+atf_error_t
+word_acum(const char *word, void *data)
+{
+    char *acum = data;
+
+    strcat(acum, word);
+
+    return atf_no_error();
+}
+
+static
+atf_error_t
+word_count(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data)
+{
+    size_t *counter = data;
+
+    (*counter)++;
+
+    return atf_no_error();
+}
+
+struct fail_at {
+    int failpos;
+    int curpos;
+};
+
+static
+atf_error_t
+word_fail_at(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data)
+{
+    struct fail_at *fa = data;
+    atf_error_t err;
+
+    if (fa->failpos == fa->curpos)
+        err = atf_no_memory_error(); /* Just a random error. */
+    else {
+        fa->curpos++;
+        err = atf_no_error();
+    }
+
+    return err;
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(for_each_word);
+ATF_TC_HEAD(for_each_word, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_text_for_each_word"
+                      "function");
+}
+ATF_TC_BODY(for_each_word, tc)
+{
+    size_t cnt;
+    char acum[1024];
+
+    cnt = 0;
+    strcpy(acum, "");
+    RE(atf_text_for_each_word("1 2 3", " ", word_count, &cnt));
+    RE(atf_text_for_each_word("1 2 3", " ", word_acum, acum));
+    ATF_REQUIRE(cnt == 3);
+    ATF_REQUIRE(strcmp(acum, "123") == 0);
+
+    cnt = 0;
+    strcpy(acum, "");
+    RE(atf_text_for_each_word("1 2 3", ".", word_count, &cnt));
+    RE(atf_text_for_each_word("1 2 3", ".", word_acum, acum));
+    ATF_REQUIRE(cnt == 1);
+    ATF_REQUIRE(strcmp(acum, "1 2 3") == 0);
+
+    cnt = 0;
+    strcpy(acum, "");
+    RE(atf_text_for_each_word("1 2 3 4 5", " ", word_count, &cnt));
+    RE(atf_text_for_each_word("1 2 3 4 5", " ", word_acum, acum));
+    ATF_REQUIRE(cnt == 5);
+    ATF_REQUIRE(strcmp(acum, "12345") == 0);
+
+    cnt = 0;
+    strcpy(acum, "");
+    RE(atf_text_for_each_word("1 2.3.4 5", " .", word_count, &cnt));
+    RE(atf_text_for_each_word("1 2.3.4 5", " .", word_acum, acum));
+    ATF_REQUIRE(cnt == 5);
+    ATF_REQUIRE(strcmp(acum, "12345") == 0);
+
+    {
+        struct fail_at fa;
+        fa.failpos = 3;
+        fa.curpos = 0;
+        atf_error_t err = atf_text_for_each_word("a b c d e", " ",
+                                                 word_fail_at, &fa);
+        ATF_REQUIRE(atf_is_error(err));
+        ATF_REQUIRE(atf_error_is(err, "no_memory"));
+        ATF_REQUIRE(fa.curpos == 3);
+        atf_error_free(err);
+    }
+}
+
+ATF_TC(format);
+ATF_TC_HEAD(format, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form "
+                      "strings using a variable parameters list");
+}
+ATF_TC_BODY(format, tc)
+{
+    char *str;
+    atf_error_t err;
+
+    err = atf_text_format(&str, "%s %s %d", "Test", "string", 1);
+    ATF_REQUIRE(!atf_is_error(err));
+    ATF_REQUIRE(strcmp(str, "Test string 1") == 0);
+    free(str);
+}
+
+static
+void
+format_ap(char **dest, const char *fmt, ...)
+{
+    va_list ap;
+    atf_error_t err;
+
+    va_start(ap, fmt);
+    err = atf_text_format_ap(dest, fmt, ap);
+    va_end(ap);
+
+    ATF_REQUIRE(!atf_is_error(err));
+}
+
+ATF_TC(format_ap);
+ATF_TC_HEAD(format_ap, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form "
+                      "strings using a va_list argument");
+}
+ATF_TC_BODY(format_ap, tc)
+{
+    char *str;
+
+    format_ap(&str, "%s %s %d", "Test", "string", 1);
+    ATF_REQUIRE(strcmp(str, "Test string 1") == 0);
+    free(str);
+}
+
+ATF_TC(split);
+ATF_TC_HEAD(split, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the split function");
+}
+ATF_TC_BODY(split, tc)
+{
+    {
+        const char *words[] = { NULL };
+        check_split("", " ", words);
+    }
+
+    {
+        const char *words[] = { NULL };
+        check_split(" ", " ", words);
+    }
+
+    {
+        const char *words[] = { NULL };
+        check_split("    ", " ", words);
+    }
+
+    {
+        const char *words[] = { "a", "b", NULL };
+        check_split("a b", " ", words);
+    }
+
+    {
+        const char *words[] = { "a", "b", "c", "d", NULL };
+        check_split("a b c d", " ", words);
+    }
+
+    {
+        const char *words[] = { "foo", "bar", NULL };
+        check_split("foo bar", " ", words);
+    }
+
+    {
+        const char *words[] = { "foo", "bar", "baz", "foobar", NULL };
+        check_split("foo bar baz foobar", " ", words);
+    }
+
+    {
+        const char *words[] = { "foo", "bar", NULL };
+        check_split(" foo bar", " ", words);
+    }
+
+    {
+        const char *words[] = { "foo", "bar", NULL };
+        check_split("foo  bar", " ", words);
+    }
+
+    {
+        const char *words[] = { "foo", "bar", NULL };
+        check_split("foo bar ", " ", words);
+    }
+
+    {
+        const char *words[] = { "foo", "bar", NULL };
+        check_split("  foo  bar  ", " ", words);
+    }
+}
+
+ATF_TC(split_delims);
+ATF_TC_HEAD(split_delims, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the split function using "
+                      "different delimiters");
+}
+ATF_TC_BODY(split_delims, tc)
+{
+
+    {
+        const char *words[] = { NULL };
+        check_split("", "/", words);
+    }
+
+    {
+        const char *words[] = { " ", NULL };
+        check_split(" ", "/", words);
+    }
+
+    {
+        const char *words[] = { "    ", NULL };
+        check_split("    ", "/", words);
+    }
+
+    {
+        const char *words[] = { "a", "b", NULL };
+        check_split("a/b", "/", words);
+    }
+
+    {
+        const char *words[] = { "a", "bcd", "ef", NULL };
+        check_split("aLONGDELIMbcdLONGDELIMef", "LONGDELIM", words);
+    }
+}
+
+ATF_TC(to_bool);
+ATF_TC_HEAD(to_bool, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_bool function");
+}
+ATF_TC_BODY(to_bool, tc)
+{
+    bool b;
+
+    RE(atf_text_to_bool("true", &b)); ATF_REQUIRE(b);
+    RE(atf_text_to_bool("TRUE", &b)); ATF_REQUIRE(b);
+    RE(atf_text_to_bool("yes", &b)); ATF_REQUIRE(b);
+    RE(atf_text_to_bool("YES", &b)); ATF_REQUIRE(b);
+
+    RE(atf_text_to_bool("false", &b)); ATF_REQUIRE(!b);
+    RE(atf_text_to_bool("FALSE", &b)); ATF_REQUIRE(!b);
+    RE(atf_text_to_bool("no", &b)); ATF_REQUIRE(!b);
+    RE(atf_text_to_bool("NO", &b)); ATF_REQUIRE(!b);
+
+    b = false;
+    REQUIRE_ERROR(atf_text_to_bool("", &b));
+    ATF_REQUIRE(!b);
+    b = true;
+    REQUIRE_ERROR(atf_text_to_bool("", &b));
+    ATF_REQUIRE(b);
+
+    b = false;
+    REQUIRE_ERROR(atf_text_to_bool("tru", &b));
+    ATF_REQUIRE(!b);
+    b = true;
+    REQUIRE_ERROR(atf_text_to_bool("tru", &b));
+    ATF_REQUIRE(b);
+
+    b = false;
+    REQUIRE_ERROR(atf_text_to_bool("true2", &b));
+    ATF_REQUIRE(!b);
+    b = true;
+    REQUIRE_ERROR(atf_text_to_bool("true2", &b));
+    ATF_REQUIRE(b);
+
+    b = false;
+    REQUIRE_ERROR(atf_text_to_bool("fals", &b));
+    ATF_REQUIRE(!b);
+    b = true;
+    REQUIRE_ERROR(atf_text_to_bool("fals", &b));
+    ATF_REQUIRE(b);
+
+    b = false;
+    REQUIRE_ERROR(atf_text_to_bool("false2", &b));
+    ATF_REQUIRE(!b);
+    b = true;
+    REQUIRE_ERROR(atf_text_to_bool("false2", &b));
+    ATF_REQUIRE(b);
+}
+
+ATF_TC(to_long);
+ATF_TC_HEAD(to_long, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_long function");
+}
+ATF_TC_BODY(to_long, tc)
+{
+    long l;
+
+    RE(atf_text_to_long("0", &l)); ATF_REQUIRE_EQ(l, 0);
+    RE(atf_text_to_long("-5", &l)); ATF_REQUIRE_EQ(l, -5);
+    RE(atf_text_to_long("5", &l)); ATF_REQUIRE_EQ(l, 5);
+    RE(atf_text_to_long("123456789", &l)); ATF_REQUIRE_EQ(l, 123456789);
+
+    l = 1212;
+    REQUIRE_ERROR(atf_text_to_long("", &l));
+    ATF_REQUIRE_EQ(l, 1212);
+    REQUIRE_ERROR(atf_text_to_long("foo", &l));
+    ATF_REQUIRE_EQ(l, 1212);
+    REQUIRE_ERROR(atf_text_to_long("1234x", &l));
+    ATF_REQUIRE_EQ(l, 1212);
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    ATF_TP_ADD_TC(tp, for_each_word);
+    ATF_TP_ADD_TC(tp, format);
+    ATF_TP_ADD_TC(tp, format_ap);
+    ATF_TP_ADD_TC(tp, split);
+    ATF_TP_ADD_TC(tp, split_delims);
+    ATF_TP_ADD_TC(tp, to_bool);
+    ATF_TP_ADD_TC(tp, to_long);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/detail/tp_main.c
===================================================================
--- vendor/atf/dist/atf-c/detail/tp_main.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/tp_main.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,612 @@
+/* Copyright (c) 2008 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(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "atf-c/detail/dynstr.h"
+#include "atf-c/detail/env.h"
+#include "atf-c/detail/fs.h"
+#include "atf-c/detail/map.h"
+#include "atf-c/detail/sanity.h"
+#include "atf-c/error.h"
+#include "atf-c/tc.h"
+#include "atf-c/tp.h"
+#include "atf-c/utils.h"
+
+#if defined(HAVE_GNU_GETOPT)
+#   define GETOPT_POSIX "+"
+#else
+#   define GETOPT_POSIX ""
+#endif
+
+static const char *progname = NULL;
+
+/* This prototype is provided by macros.h during instantiation of the test
+ * program, so it can be kept private.  Don't know if that's the best idea
+ * though. */
+int atf_tp_main(int, char **, atf_error_t (*)(atf_tp_t *));
+
+enum tc_part {
+    BODY,
+    CLEANUP,
+};
+
+/* ---------------------------------------------------------------------
+ * The "usage" and "user" error types.
+ * --------------------------------------------------------------------- */
+
+#define FREE_FORM_ERROR(name) \
+    struct name ## _error_data { \
+        char m_what[2048]; \
+    }; \
+    \
+    static \
+    void \
+    name ## _format(const atf_error_t err, char *buf, size_t buflen) \
+    { \
+        const struct name ## _error_data *data; \
+        \
+        PRE(atf_error_is(err, #name)); \
+        \
+        data = atf_error_data(err); \
+        snprintf(buf, buflen, "%s", data->m_what); \
+    } \
+    \
+    static \
+    atf_error_t \
+    name ## _error(const char *fmt, ...) \
+    { \
+        atf_error_t err; \
+        struct name ## _error_data data; \
+        va_list ap; \
+        \
+        va_start(ap, fmt); \
+        vsnprintf(data.m_what, sizeof(data.m_what), fmt, ap); \
+        va_end(ap); \
+        \
+        err = atf_error_new(#name, &data, sizeof(data), name ## _format); \
+        \
+        return err; \
+    }
+
+FREE_FORM_ERROR(usage);
+FREE_FORM_ERROR(user);
+
+/* ---------------------------------------------------------------------
+ * Printing functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+print_error(const atf_error_t err)
+{
+    char buf[4096];
+
+    PRE(atf_is_error(err));
+
+    atf_error_format(err, buf, sizeof(buf));
+    fprintf(stderr, "%s: ERROR: %s\n", progname, buf);
+
+    if (atf_error_is(err, "usage"))
+        fprintf(stderr, "%s: See atf-test-program(1) for usage details.\n",
+                progname);
+}
+
+static
+void
+print_warning(const char *message)
+{
+    fprintf(stderr, "%s: WARNING: %s\n", progname, message);
+}
+
+/* ---------------------------------------------------------------------
+ * Options handling.
+ * --------------------------------------------------------------------- */
+
+struct params {
+    bool m_do_list;
+    atf_fs_path_t m_srcdir;
+    char *m_tcname;
+    enum tc_part m_tcpart;
+    atf_fs_path_t m_resfile;
+    atf_map_t m_config;
+};
+
+static
+atf_error_t
+argv0_to_dir(const char *argv0, atf_fs_path_t *dir)
+{
+    atf_error_t err;
+    atf_fs_path_t temp;
+
+    err = atf_fs_path_init_fmt(&temp, "%s", argv0);
+    if (atf_is_error(err))
+        goto out;
+
+    err = atf_fs_path_branch_path(&temp, dir);
+
+    atf_fs_path_fini(&temp);
+out:
+    return err;
+}
+
+static
+atf_error_t
+params_init(struct params *p, const char *argv0)
+{
+    atf_error_t err;
+
+    p->m_do_list = false;
+    p->m_tcname = NULL;
+    p->m_tcpart = BODY;
+
+    err = argv0_to_dir(argv0, &p->m_srcdir);
+    if (atf_is_error(err))
+        return err;
+
+    err = atf_fs_path_init_fmt(&p->m_resfile, "/dev/stdout");
+    if (atf_is_error(err)) {
+        atf_fs_path_fini(&p->m_srcdir);
+        return err;
+    }
+
+    err = atf_map_init(&p->m_config);
+    if (atf_is_error(err)) {
+        atf_fs_path_fini(&p->m_resfile);
+        atf_fs_path_fini(&p->m_srcdir);
+        return err;
+    }
+
+    return err;
+}
+
+static
+void
+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);
+}
+
+static
+atf_error_t
+parse_vflag(char *arg, atf_map_t *config)
+{
+    atf_error_t err;
+    char *split;
+
+    split = strchr(arg, '=');
+    if (split == NULL) {
+        err = usage_error("-v requires an argument of the form var=value");
+        goto out;
+    }
+
+    *split = '\0';
+    split++;
+
+    err = atf_map_insert(config, arg, split, false);
+
+out:
+    return err;
+}
+
+static
+atf_error_t
+replace_path_param(atf_fs_path_t *param, const char *value)
+{
+    atf_error_t err;
+    atf_fs_path_t temp;
+
+    err = atf_fs_path_init_fmt(&temp, "%s", value);
+    if (!atf_is_error(err)) {
+        atf_fs_path_fini(param);
+        *param = temp;
+    }
+
+    return err;
+}
+
+/* ---------------------------------------------------------------------
+ * Test case listing.
+ * --------------------------------------------------------------------- */
+
+static
+void
+list_tcs(const atf_tp_t *tp)
+{
+    const atf_tc_t *const *tcs;
+    const atf_tc_t *const *tcsptr;
+
+    printf("Content-Type: application/X-atf-tp; version=\"1\"\n\n");
+
+    tcs = atf_tp_get_tcs(tp);
+    INV(tcs != NULL);  /* Should be checked. */
+    for (tcsptr = tcs; *tcsptr != NULL; tcsptr++) {
+        const atf_tc_t *tc = *tcsptr;
+        char **vars = atf_tc_get_md_vars(tc);
+        char **ptr;
+
+        INV(vars != NULL);  /* Should be checked. */
+
+        if (tcsptr != tcs)  /* Not first. */
+            printf("\n");
+
+        for (ptr = vars; *ptr != NULL; ptr += 2) {
+            if (strcmp(*ptr, "ident") == 0) {
+                printf("ident: %s\n", *(ptr + 1));
+                break;
+            }
+        }
+
+        for (ptr = vars; *ptr != NULL; ptr += 2) {
+            if (strcmp(*ptr, "ident") != 0) {
+                printf("%s: %s\n", *ptr, *(ptr + 1));
+            }
+        }
+
+        atf_utils_free_charpp(vars);
+    }
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+static
+atf_error_t
+handle_tcarg(const char *tcarg, char **tcname, enum tc_part *tcpart)
+{
+    atf_error_t err;
+
+    err = atf_no_error();
+
+    *tcname = strdup(tcarg);
+    if (*tcname == NULL) {
+        err = atf_no_memory_error();
+        goto out;
+    }
+
+    char *delim = strchr(*tcname, ':');
+    if (delim != NULL) {
+        *delim = '\0';
+
+        delim++;
+        if (strcmp(delim, "body") == 0) {
+            *tcpart = BODY;
+        } else if (strcmp(delim, "cleanup") == 0) {
+            *tcpart = CLEANUP;
+        } else {
+            err = usage_error("Invalid test case part `%s'", delim);
+            goto out;
+        }
+    }
+
+out:
+    return err;
+}
+
+static
+atf_error_t
+process_params(int argc, char **argv, struct params *p)
+{
+    atf_error_t err;
+    int ch;
+    int old_opterr;
+
+    err = params_init(p, argv[0]);
+    if (atf_is_error(err))
+        goto out;
+
+    old_opterr = opterr;
+    opterr = 0;
+    while (!atf_is_error(err) &&
+           (ch = getopt(argc, argv, GETOPT_POSIX ":lr:s:v:")) != -1) {
+        switch (ch) {
+        case 'l':
+            p->m_do_list = true;
+            break;
+
+        case 'r':
+            err = replace_path_param(&p->m_resfile, optarg);
+            break;
+
+        case 's':
+            err = replace_path_param(&p->m_srcdir, optarg);
+            break;
+
+        case 'v':
+            err = parse_vflag(optarg, &p->m_config);
+            break;
+
+        case ':':
+            err = usage_error("Option -%c requires an argument.", optopt);
+            break;
+
+        case '?':
+        default:
+            err = usage_error("Unknown option -%c.", optopt);
+        }
+    }
+    argc -= optind;
+    argv += optind;
+
+    /* Clear getopt state just in case the test wants to use it. */
+    opterr = old_opterr;
+    optind = 1;
+#if defined(HAVE_OPTRESET)
+    optreset = 1;
+#endif
+
+    if (!atf_is_error(err)) {
+        if (p->m_do_list) {
+            if (argc > 0)
+                err = usage_error("Cannot provide test case names with -l");
+        } else {
+            if (argc == 0)
+                err = usage_error("Must provide a test case name");
+            else if (argc == 1)
+                err = handle_tcarg(argv[0], &p->m_tcname, &p->m_tcpart);
+            else if (argc > 1) {
+                err = usage_error("Cannot provide more than one test case "
+                                  "name");
+            }
+        }
+    }
+
+    if (atf_is_error(err))
+        params_fini(p);
+
+out:
+    return err;
+}
+
+static
+atf_error_t
+srcdir_strip_libtool(atf_fs_path_t *srcdir)
+{
+    atf_error_t err;
+    atf_fs_path_t parent;
+
+    err = atf_fs_path_branch_path(srcdir, &parent);
+    if (atf_is_error(err))
+        goto out;
+
+    atf_fs_path_fini(srcdir);
+    *srcdir = parent;
+
+    INV(!atf_is_error(err));
+out:
+    return err;
+}
+
+static
+atf_error_t
+handle_srcdir(struct params *p)
+{
+    atf_error_t err;
+    atf_dynstr_t leafname;
+    atf_fs_path_t exe, srcdir;
+    bool b;
+
+    err = atf_fs_path_copy(&srcdir, &p->m_srcdir);
+    if (atf_is_error(err))
+        goto out;
+
+    if (!atf_fs_path_is_absolute(&srcdir)) {
+        atf_fs_path_t srcdirabs;
+
+        err = atf_fs_path_to_absolute(&srcdir, &srcdirabs);
+        if (atf_is_error(err))
+            goto out_srcdir;
+
+        atf_fs_path_fini(&srcdir);
+        srcdir = srcdirabs;
+    }
+
+    err = atf_fs_path_leaf_name(&srcdir, &leafname);
+    if (atf_is_error(err))
+        goto out_srcdir;
+    else {
+        const bool libs = atf_equal_dynstr_cstring(&leafname, ".libs");
+        atf_dynstr_fini(&leafname);
+
+        if (libs) {
+            err = srcdir_strip_libtool(&srcdir);
+            if (atf_is_error(err))
+                goto out;
+        }
+    }
+
+    err = atf_fs_path_copy(&exe, &srcdir);
+    if (atf_is_error(err))
+        goto out_srcdir;
+
+    err = atf_fs_path_append_fmt(&exe, "%s", progname);
+    if (atf_is_error(err))
+        goto out_exe;
+
+    err = atf_fs_exists(&exe, &b);
+    if (!atf_is_error(err)) {
+        if (b) {
+            err = atf_map_insert(&p->m_config, "srcdir",
+                                 strdup(atf_fs_path_cstring(&srcdir)), true);
+        } else {
+            err = user_error("Cannot find the test program in the source "
+                             "directory `%s'", atf_fs_path_cstring(&srcdir));
+        }
+    }
+
+out_exe:
+    atf_fs_path_fini(&exe);
+out_srcdir:
+    atf_fs_path_fini(&srcdir);
+out:
+    return err;
+}
+
+static
+atf_error_t
+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)) {
+        err = usage_error("Unknown test case `%s'", p->m_tcname);
+        goto out;
+    }
+
+    if (!atf_env_has("__RUNNING_INSIDE_ATF_RUN") || strcmp(atf_env_get(
+        "__RUNNING_INSIDE_ATF_RUN"), "internal-yes-value") != 0)
+    {
+        print_warning("Running test cases outside of kyua(1) is unsupported");
+        print_warning("No isolation nor timeout control is being applied; you "
+                      "may get unexpected failures; see atf-test-case(4)");
+    }
+
+    switch (p->m_tcpart) {
+    case BODY:
+        err = atf_tp_run(tp, p->m_tcname, atf_fs_path_cstring(&p->m_resfile));
+        if (atf_is_error(err)) {
+            /* TODO: Handle error */
+            *exitcode = EXIT_FAILURE;
+            atf_error_free(err);
+        } else {
+            *exitcode = EXIT_SUCCESS;
+        }
+
+        break;
+
+    case CLEANUP:
+        err = atf_tp_cleanup(tp, p->m_tcname);
+        if (atf_is_error(err)) {
+            /* TODO: Handle error */
+            *exitcode = EXIT_FAILURE;
+            atf_error_free(err);
+        } else {
+            *exitcode = EXIT_SUCCESS;
+        }
+
+        break;
+
+    default:
+        UNREACHABLE;
+    }
+
+    INV(!atf_is_error(err));
+out:
+    return err;
+}
+
+static
+atf_error_t
+controlled_main(int argc, char **argv,
+                atf_error_t (*add_tcs_hook)(atf_tp_t *),
+                int *exitcode)
+{
+    atf_error_t err;
+    struct params p;
+    atf_tp_t tp;
+    char **raw_config;
+
+    err = process_params(argc, argv, &p);
+    if (atf_is_error(err))
+        goto out;
+
+    err = handle_srcdir(&p);
+    if (atf_is_error(err))
+        goto out_p;
+
+    raw_config = atf_map_to_charpp(&p.m_config);
+    if (raw_config == NULL) {
+        err = atf_no_memory_error();
+        goto out_p;
+    }
+    err = atf_tp_init(&tp, (const char* const*)raw_config);
+    atf_utils_free_charpp(raw_config);
+    if (atf_is_error(err))
+        goto out_p;
+
+    err = add_tcs_hook(&tp);
+    if (atf_is_error(err))
+        goto out_tp;
+
+    if (p.m_do_list) {
+        list_tcs(&tp);
+        INV(!atf_is_error(err));
+        *exitcode = EXIT_SUCCESS;
+    } else {
+        err = run_tc(&tp, &p, exitcode);
+    }
+
+out_tp:
+    atf_tp_fini(&tp);
+out_p:
+    params_fini(&p);
+out:
+    return err;
+}
+
+int
+atf_tp_main(int argc, char **argv, atf_error_t (*add_tcs_hook)(atf_tp_t *))
+{
+    atf_error_t err;
+    int exitcode;
+
+    progname = strrchr(argv[0], '/');
+    if (progname == NULL)
+        progname = argv[0];
+    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)) {
+        print_error(err);
+        atf_error_free(err);
+        exitcode = EXIT_FAILURE;
+    }
+
+    return exitcode;
+}

Added: vendor/atf/dist/atf-c/detail/user.c
===================================================================
--- vendor/atf/dist/atf-c/detail/user.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/user.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,75 @@
+/* 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/user.h"
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "atf-c/detail/sanity.h"
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+uid_t
+atf_user_euid(void)
+{
+    return geteuid();
+}
+
+bool
+atf_user_is_member_of_group(gid_t gid)
+{
+    static gid_t groups[NGROUPS_MAX];
+    static int ngroups = -1;
+    bool found;
+    int i;
+
+    if (ngroups == -1) {
+        ngroups = getgroups(NGROUPS_MAX, groups);
+        INV(ngroups >= 0);
+    }
+
+    found = false;
+    for (i = 0; !found && i < ngroups; i++)
+        if (groups[i] == gid)
+            found = true;
+    return found;
+}
+
+bool
+atf_user_is_root(void)
+{
+    return geteuid() == 0;
+}
+
+bool
+atf_user_is_unprivileged(void)
+{
+    return geteuid() != 0;
+}

Added: vendor/atf/dist/atf-c/detail/user.h
===================================================================
--- vendor/atf/dist/atf-c/detail/user.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/user.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,45 @@
+/* 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_C_DETAIL_USER_H)
+#define ATF_C_DETAIL_USER_H
+
+#include <sys/types.h>
+
+#include <stdbool.h>
+
+/* TODO: Would be nice to have an atf_user_t type and transform all of
+ * the functions below to methods. */
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+uid_t atf_user_euid(void);
+bool atf_user_is_member_of_group(gid_t);
+bool atf_user_is_root(void);
+bool atf_user_is_unprivileged(void);
+
+#endif /* !defined(ATF_C_DETAIL_USER_H) */

Added: vendor/atf/dist/atf-c/detail/user_test.c
===================================================================
--- vendor/atf/dist/atf-c/detail/user_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/user_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,146 @@
+/* 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/user.h"
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(euid);
+ATF_TC_HEAD(euid, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_user_euid function");
+}
+ATF_TC_BODY(euid, tc)
+{
+    ATF_REQUIRE_EQ(atf_user_euid(), geteuid());
+}
+
+ATF_TC(is_member_of_group);
+ATF_TC_HEAD(is_member_of_group, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_user_is_member_of_group "
+                      "function");
+}
+ATF_TC_BODY(is_member_of_group, tc)
+{
+    gid_t gids[NGROUPS_MAX];
+    gid_t g, maxgid;
+    int ngids;
+    const gid_t maxgid_limit = 1 << 16;
+
+    {
+        int i;
+
+        ngids = getgroups(NGROUPS_MAX, gids);
+        if (ngids == -1)
+            atf_tc_fail("Call to getgroups failed");
+        maxgid = 0;
+        for (i = 0; i < ngids; i++) {
+            printf("User group %d is %u\n", i, gids[i]);
+            if (maxgid < gids[i])
+                maxgid = gids[i];
+        }
+        printf("User belongs to %d groups\n", ngids);
+        printf("Last GID is %u\n", maxgid);
+    }
+
+    if (maxgid > maxgid_limit) {
+        printf("Test truncated from %u groups to %u to keep the run time "
+               "reasonable enough\n", maxgid, maxgid_limit);
+        maxgid = maxgid_limit;
+    }
+
+    for (g = 0; g < maxgid; g++) {
+        bool found = false;
+        int i;
+
+        for (i = 0; !found && i < ngids; i++) {
+            if (gids[i] == g)
+                found = true;
+        }
+
+        if (found) {
+            printf("Checking if user belongs to group %d\n", g);
+            ATF_REQUIRE(atf_user_is_member_of_group(g));
+        } else {
+            printf("Checking if user does not belong to group %d\n", g);
+            ATF_REQUIRE(!atf_user_is_member_of_group(g));
+        }
+    }
+}
+
+ATF_TC(is_root);
+ATF_TC_HEAD(is_root, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_user_is_root function");
+}
+ATF_TC_BODY(is_root, tc)
+{
+    if (geteuid() == 0)
+        ATF_REQUIRE(atf_user_is_root());
+    else
+        ATF_REQUIRE(!atf_user_is_root());
+}
+
+ATF_TC(is_unprivileged);
+ATF_TC_HEAD(is_unprivileged, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_user_is_unprivileged "
+                      "function");
+}
+ATF_TC_BODY(is_unprivileged, tc)
+{
+    if (geteuid() != 0)
+        ATF_REQUIRE(atf_user_is_unprivileged());
+    else
+        ATF_REQUIRE(!atf_user_is_unprivileged());
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    ATF_TP_ADD_TC(tp, euid);
+    ATF_TP_ADD_TC(tp, is_member_of_group);
+    ATF_TP_ADD_TC(tp, is_root);
+    ATF_TP_ADD_TC(tp, is_unprivileged);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/detail/version_helper.c
===================================================================
--- vendor/atf/dist/atf-c/detail/version_helper.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/detail/version_helper.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2014 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+ * OWNER 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(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main(void)
+{
+    printf("%s\n", PACKAGE_VERSION);
+    return EXIT_SUCCESS;
+}

Added: vendor/atf/dist/atf-c/error.c
===================================================================
--- vendor/atf/dist/atf-c/error.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/error.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,263 @@
+/* Copyright (c) 2008 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/error.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "atf-c/detail/sanity.h"
+
+/* Theoretically, there can only be a single error intance 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
+ * error.
+ *
+ * This is per-thread information and will break threaded tests, but we
+ * currently do not have any threading support; therefore, this is fine. */
+static bool error_on_flight = false;
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+error_format(const atf_error_t err, char *buf, size_t buflen)
+{
+    PRE(err != NULL);
+    snprintf(buf, buflen, "Error '%s'", err->m_type);
+}
+
+static
+bool
+error_init(atf_error_t err, const char *type, void *data, size_t datalen,
+           void (*format)(const atf_error_t, char *, size_t))
+{
+    bool ok;
+
+    PRE(data != NULL || datalen == 0);
+    PRE(datalen != 0 || data == NULL);
+
+    err->m_free = false;
+    err->m_type = type;
+    err->m_format = (format == NULL) ? error_format : format;
+
+    ok = true;
+    if (data == NULL) {
+        err->m_data = NULL;
+    } else {
+        err->m_data = malloc(datalen);
+        if (err->m_data == NULL) {
+            ok = false;
+        } else
+            memcpy(err->m_data, data, datalen);
+    }
+
+    return ok;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_error" type.
+ * --------------------------------------------------------------------- */
+
+atf_error_t
+atf_error_new(const char *type, void *data, size_t datalen,
+              void (*format)(const atf_error_t, char *, size_t))
+{
+    atf_error_t err;
+
+    PRE(!error_on_flight);
+    PRE(data != NULL || datalen == 0);
+    PRE(datalen != 0 || data == NULL);
+
+    err = malloc(sizeof(*err));
+    if (err == NULL)
+        err = atf_no_memory_error();
+    else {
+        if (!error_init(err, type, data, datalen, format)) {
+            free(err);
+            err = atf_no_memory_error();
+        } else {
+            err->m_free = true;
+            error_on_flight = true;
+        }
+    }
+
+    INV(err != NULL);
+    POST(error_on_flight);
+    return err;
+}
+
+void
+atf_error_free(atf_error_t err)
+{
+    bool freeit;
+
+    PRE(error_on_flight);
+    PRE(err != NULL);
+
+    freeit = err->m_free;
+
+    if (err->m_data != NULL)
+        free(err->m_data);
+
+    if (freeit)
+        free(err);
+
+    error_on_flight = false;
+}
+
+atf_error_t
+atf_no_error(void)
+{
+    return NULL;
+}
+
+bool
+atf_is_error(const atf_error_t err)
+{
+    return err != NULL;
+}
+
+bool
+atf_error_is(const atf_error_t err, const char *type)
+{
+    PRE(err != NULL);
+
+    return strcmp(err->m_type, type) == 0;
+}
+
+const void *
+atf_error_data(const atf_error_t err)
+{
+    PRE(err != NULL);
+
+    return err->m_data;
+}
+
+void
+atf_error_format(const atf_error_t err, char *buf, size_t buflen)
+{
+    PRE(err != NULL);
+    err->m_format(err, buf, buflen);
+}
+
+/* ---------------------------------------------------------------------
+ * Common error types.
+ * --------------------------------------------------------------------- */
+
+/*
+ * The "libc" error.
+ */
+
+struct atf_libc_error_data {
+    int m_errno;
+    char m_what[4096];
+};
+typedef struct atf_libc_error_data atf_libc_error_data_t;
+
+static
+void
+libc_format(const atf_error_t err, char *buf, size_t buflen)
+{
+    const atf_libc_error_data_t *data;
+
+    PRE(atf_error_is(err, "libc"));
+
+    data = atf_error_data(err);
+    snprintf(buf, buflen, "%s: %s", data->m_what, strerror(data->m_errno));
+}
+
+atf_error_t
+atf_libc_error(int syserrno, const char *fmt, ...)
+{
+    atf_error_t err;
+    atf_libc_error_data_t data;
+    va_list ap;
+
+    data.m_errno = syserrno;
+    va_start(ap, fmt);
+    vsnprintf(data.m_what, sizeof(data.m_what), fmt, ap);
+    va_end(ap);
+
+    err = atf_error_new("libc", &data, sizeof(data), libc_format);
+
+    return err;
+}
+
+int
+atf_libc_error_code(const atf_error_t err)
+{
+    const struct atf_libc_error_data *data;
+
+    PRE(atf_error_is(err, "libc"));
+
+    data = atf_error_data(err);
+
+    return data->m_errno;
+}
+
+const char *
+atf_libc_error_msg(const atf_error_t err)
+{
+    const struct atf_libc_error_data *data;
+
+    PRE(atf_error_is(err, "libc"));
+
+    data = atf_error_data(err);
+
+    return data->m_what;
+}
+
+/*
+ * The "no_memory" error.
+ */
+
+static struct atf_error no_memory_error;
+
+static
+void
+no_memory_format(const atf_error_t err, char *buf, size_t buflen)
+{
+    PRE(atf_error_is(err, "no_memory"));
+
+    snprintf(buf, buflen, "Not enough memory");
+}
+
+atf_error_t
+atf_no_memory_error(void)
+{
+    PRE(!error_on_flight);
+
+    error_init(&no_memory_error, "no_memory", NULL, 0,
+               no_memory_format);
+
+    error_on_flight = true;
+    return &no_memory_error;
+}

Added: vendor/atf/dist/atf-c/error.h
===================================================================
--- vendor/atf/dist/atf-c/error.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/error.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,67 @@
+/* Copyright (c) 2008 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_C_ERROR_H)
+#define ATF_C_ERROR_H
+
+#include <atf-c/error_fwd.h>
+
+#include <stdbool.h>
+#include <stddef.h>
+
+/* ---------------------------------------------------------------------
+ * The "atf_error" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_error {
+    bool m_free;
+    const char *m_type;
+    void *m_data;
+
+    void (*m_format)(struct atf_error *, char *, size_t);
+};
+
+atf_error_t atf_error_new(const char *, void *, size_t,
+                          void (*)(const atf_error_t, char *, size_t));
+void atf_error_free(atf_error_t);
+
+atf_error_t atf_no_error(void);
+bool atf_is_error(const atf_error_t);
+
+bool atf_error_is(const atf_error_t, const char *);
+const void *atf_error_data(const atf_error_t);
+void atf_error_format(const atf_error_t, char *, size_t);
+
+/* ---------------------------------------------------------------------
+ * Common error types.
+ * --------------------------------------------------------------------- */
+
+atf_error_t atf_libc_error(int, const char *, ...);
+int atf_libc_error_code(const atf_error_t);
+const char *atf_libc_error_msg(const atf_error_t);
+
+atf_error_t atf_no_memory_error(void);
+
+#endif /* !defined(ATF_C_ERROR_H) */

Added: vendor/atf/dist/atf-c/error_fwd.h
===================================================================
--- vendor/atf/dist/atf-c/error_fwd.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/error_fwd.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,36 @@
+/* Copyright (c) 2008 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_C_ERROR_FWD_H)
+#define ATF_C_ERROR_FWD_H
+
+/* ---------------------------------------------------------------------
+ * The "atf_error" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_error;
+typedef struct atf_error *atf_error_t;
+
+#endif /* !defined(ATF_C_ERROR_FWD_H) */

Added: vendor/atf/dist/atf-c/error_test.c
===================================================================
--- vendor/atf/dist/atf-c/error_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/error_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,297 @@
+/* Copyright (c) 2008 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/error.h"
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/defs.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+test_format(const atf_error_t err ATF_DEFS_ATTRIBUTE_UNUSED,
+            char *buf, size_t buflen)
+{
+    snprintf(buf, buflen, "Test formatting function");
+}
+
+/* ---------------------------------------------------------------------
+ * Tests for the "atf_error" type.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(error_new);
+ATF_TC_HEAD(error_new, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the construction of an error "
+                      "object");
+}
+ATF_TC_BODY(error_new, tc)
+{
+    atf_error_t err;
+    int data;
+
+    err = atf_error_new("test_error", NULL, 0, NULL);
+    ATF_REQUIRE(atf_error_is(err, "test_error"));
+    ATF_REQUIRE(!atf_error_is(err, "unknown_error"));
+    ATF_REQUIRE(atf_error_data(err) == NULL);
+    atf_error_free(err);
+
+    data = 5;
+    err = atf_error_new("test_data_error", &data, sizeof(data), NULL);
+    ATF_REQUIRE(atf_error_is(err, "test_data_error"));
+    ATF_REQUIRE(!atf_error_is(err, "unknown_error"));
+    ATF_REQUIRE(atf_error_data(err) != NULL);
+    ATF_REQUIRE_EQ(*((const int *)atf_error_data(err)), 5);
+    atf_error_free(err);
+}
+
+ATF_TC(error_new_wo_memory);
+ATF_TC_HEAD(error_new_wo_memory, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that an unavailable memory error "
+                      "raised when constructing an error object "
+                            "is properly converted to the no_memory "
+                            "static error type");
+}
+ATF_TC_BODY(error_new_wo_memory, tc)
+{
+    atf_error_t err;
+    void *invalid;
+
+    invalid = (void *)1;
+
+    err = atf_error_new("test_error", invalid, SIZE_MAX, NULL);
+    ATF_REQUIRE(atf_error_is(err, "no_memory"));
+    ATF_REQUIRE(atf_error_data(err) == NULL);
+    atf_error_free(err);
+}
+
+ATF_TC(no_error);
+ATF_TC_HEAD(no_error, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks that constructing a non-error "
+                      "object works");
+}
+ATF_TC_BODY(no_error, tc)
+{
+    atf_error_t err;
+
+    err = atf_no_error();
+    ATF_REQUIRE(!atf_is_error(err));
+}
+
+ATF_TC(is_error);
+ATF_TC_HEAD(is_error, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the is_error method to determine "
+                      "if an error object holds success or an error");
+}
+ATF_TC_BODY(is_error, tc)
+{
+    atf_error_t err;
+
+    err = atf_no_error();
+    ATF_REQUIRE(!atf_is_error(err));
+
+    err = atf_error_new("test_error", NULL, 0, NULL);
+    ATF_REQUIRE(atf_is_error(err));
+    atf_error_free(err);
+}
+
+ATF_TC(format);
+ATF_TC_HEAD(format, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the default formatting function "
+                      "and the ability to change it");
+}
+ATF_TC_BODY(format, tc)
+{
+    atf_error_t err;
+    char buf[1024];
+
+    printf("Testing default formatting function\n");
+    err = atf_error_new("test_error", NULL, 0, NULL);
+    atf_error_format(err, buf, sizeof(buf));
+    printf("Error string is: %s\n", buf);
+    ATF_REQUIRE(strcmp(buf, "Error 'test_error'") == 0);
+    atf_error_free(err);
+
+    printf("Testing custom formatting function\n");
+    err = atf_error_new("test_error", NULL, 0, test_format);
+    atf_error_format(err, buf, sizeof(buf));
+    printf("Error string is: %s\n", buf);
+    ATF_REQUIRE(strcmp(buf, "Test formatting function") == 0);
+    atf_error_free(err);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests for the "libc" error.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(libc_new);
+ATF_TC_HEAD(libc_new, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the construction of libc errors");
+}
+ATF_TC_BODY(libc_new, tc)
+{
+    atf_error_t err;
+
+    err = atf_libc_error(ENOMEM, "Test message 1");
+    ATF_REQUIRE(atf_error_is(err, "libc"));
+    ATF_REQUIRE_EQ(atf_libc_error_code(err), ENOMEM);
+    ATF_REQUIRE(strcmp(atf_libc_error_msg(err), "Test message 1") == 0);
+    atf_error_free(err);
+
+    err = atf_libc_error(EPERM, "%s message %d", "Test", 2);
+    ATF_REQUIRE(atf_error_is(err, "libc"));
+    ATF_REQUIRE_EQ(atf_libc_error_code(err), EPERM);
+    ATF_REQUIRE(strcmp(atf_libc_error_msg(err), "Test message 2") == 0);
+    atf_error_free(err);
+}
+
+ATF_TC(libc_format);
+ATF_TC_HEAD(libc_format, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the formatting of libc errors");
+}
+ATF_TC_BODY(libc_format, tc)
+{
+    atf_error_t err;
+    char buf[1024];
+
+    err = atf_libc_error(ENOMEM, "Test message 1");
+    atf_error_format(err, buf, sizeof(buf));
+    ATF_REQUIRE(strstr(buf, strerror(ENOMEM)) != NULL);
+    ATF_REQUIRE(strstr(buf, "Test message 1") != NULL);
+    atf_error_free(err);
+
+    err = atf_libc_error(EPERM, "Test message 2");
+    atf_error_format(err, buf, sizeof(buf));
+    ATF_REQUIRE(strstr(buf, strerror(EPERM)) != NULL);
+    ATF_REQUIRE(strstr(buf, "Test message 2") != NULL);
+    atf_error_free(err);
+
+    err = atf_libc_error(EPERM, "%s message %d", "Test", 3);
+    atf_error_format(err, buf, sizeof(buf));
+    ATF_REQUIRE(strstr(buf, strerror(EPERM)) != NULL);
+    ATF_REQUIRE(strstr(buf, "Test message 3") != NULL);
+    atf_error_free(err);
+}
+
+/* ---------------------------------------------------------------------
+ * Tests for the "no_memory" error.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(no_memory_new);
+ATF_TC_HEAD(no_memory_new, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the construction of no_memory "
+                      "errors");
+}
+ATF_TC_BODY(no_memory_new, tc)
+{
+    atf_error_t err;
+
+    err = atf_no_memory_error();
+    ATF_REQUIRE(atf_error_is(err, "no_memory"));
+    ATF_REQUIRE(atf_error_data(err) == NULL);
+    atf_error_free(err);
+}
+
+ATF_TC(no_memory_format);
+ATF_TC_HEAD(no_memory_format, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the formatting of no_memory "
+                      "errors");
+}
+ATF_TC_BODY(no_memory_format, tc)
+{
+    atf_error_t err;
+    char buf[1024];
+
+    err = atf_no_memory_error();
+    atf_error_format(err, buf, sizeof(buf));
+    ATF_REQUIRE(strcmp(buf, "Not enough memory") == 0);
+    atf_error_free(err);
+}
+
+ATF_TC(no_memory_twice);
+ATF_TC_HEAD(no_memory_twice, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks the construction of no_memory "
+                      "errors multiple times, as this error is initialized "
+                      "statically");
+}
+ATF_TC_BODY(no_memory_twice, tc)
+{
+    {
+        atf_error_t err = atf_no_memory_error();
+        ATF_REQUIRE(atf_error_is(err, "no_memory"));
+        ATF_REQUIRE(atf_error_data(err) == NULL);
+        atf_error_free(err);
+    }
+
+    {
+        atf_error_t err = atf_no_memory_error();
+        ATF_REQUIRE(atf_error_is(err, "no_memory"));
+        ATF_REQUIRE(atf_error_data(err) == NULL);
+        atf_error_free(err);
+    }
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    /* Add the tests for the "atf_error" type. */
+    ATF_TP_ADD_TC(tp, error_new);
+    ATF_TP_ADD_TC(tp, error_new_wo_memory);
+    ATF_TP_ADD_TC(tp, no_error);
+    ATF_TP_ADD_TC(tp, is_error);
+    ATF_TP_ADD_TC(tp, format);
+
+    /* Add the tests for the "libc" error. */
+    ATF_TP_ADD_TC(tp, libc_new);
+    ATF_TP_ADD_TC(tp, libc_format);
+
+    /* Add the tests for the "no_memory" error. */
+    ATF_TP_ADD_TC(tp, no_memory_new);
+    ATF_TP_ADD_TC(tp, no_memory_format);
+    ATF_TP_ADD_TC(tp, no_memory_twice);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/h_build.h
===================================================================
--- vendor/atf/dist/atf-c/h_build.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/h_build.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,410 @@
+/* Copyright (c) 2009 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_C_H_BUILD_H)
+#   error "Cannot include h_build.h more than once."
+#else
+#   define ATF_C_H_BUILD_H
+#endif
+
+/* ---------------------------------------------------------------------
+ * Test case data.
+ * --------------------------------------------------------------------- */
+
+static struct c_o_test {
+    const char *msg;
+    const char *cc;
+    const char *cflags;
+    const char *cppflags;
+    const char *sfile;
+    const char *ofile;
+    bool hasoptargs;
+    const char *const optargs[16];
+    const char *const expargv[16];
+} c_o_tests[] = {
+    {
+        "No flags",
+        "cc",
+        "",
+        "",
+        "test.c",
+        "test.o",
+        false,
+        {
+            NULL
+        },
+        {
+            "cc", "-o", "test.o", "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Multi-word program name",
+        "cc -foo",
+        "",
+        "",
+        "test.c",
+        "test.o",
+        false,
+        {
+            NULL
+        },
+        {
+            "cc", "-foo", "-o", "test.o", "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Some cflags",
+        "cc",
+        "-f1 -f2    -f3 -f4-f5",
+        "",
+        "test.c",
+        "test.o",
+        false,
+        {
+            NULL
+        },
+        {
+            "cc", "-f1", "-f2", "-f3", "-f4-f5", "-o", "test.o",
+            "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Some cppflags",
+        "cc",
+        "",
+        "-f1 -f2    -f3 -f4-f5",
+        "test.c",
+        "test.o",
+        false,
+        {
+            NULL
+        },
+        {
+            "cc", "-f1", "-f2", "-f3", "-f4-f5", "-o", "test.o",
+            "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Some cflags and cppflags",
+        "cc",
+        "-f2",
+        "-f1",
+        "test.c",
+        "test.o",
+        false,
+        {
+            NULL
+        },
+        {
+            "cc", "-f1", "-f2", "-o", "test.o", "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Some optional arguments",
+        "cc",
+        "",
+        "",
+        "test.c",
+        "test.o",
+        true,
+        {
+            "-o1", "-o2", NULL
+        },
+        {
+            "cc", "-o1", "-o2", "-o", "test.o", "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Some cflags, cppflags and optional arguments",
+        "cc",
+        "-f2",
+        "-f1",
+        "test.c",
+        "test.o",
+        true,
+        {
+            "-o1", "-o2", NULL
+        },
+        {
+            "cc", "-f1", "-f2", "-o1", "-o2", "-o", "test.o",
+            "-c", "test.c", NULL
+        },
+    },
+
+    {
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        false,
+        { NULL },
+        { NULL },
+    },
+};
+
+static struct cpp_test {
+    const char *msg;
+    const char *cpp;
+    const char *cppflags;
+    const char *sfile;
+    const char *ofile;
+    bool hasoptargs;
+    const char *const optargs[16];
+    const char *const expargv[16];
+} cpp_tests[] = {
+    {
+        "No flags",
+        "cpp",
+        "",
+        "test.c",
+        "test.out",
+        false,
+        {
+            NULL
+        },
+        {
+            "cpp", "-o", "test.out", "test.c", NULL
+        },
+    },
+
+    {
+        "Multi-word program name",
+        "cpp -foo",
+        "",
+        "test.c",
+        "test.out",
+        false,
+        {
+            NULL
+        },
+        {
+            "cpp", "-foo", "-o", "test.out", "test.c", NULL
+        },
+    },
+
+    {
+        "Some cppflags",
+        "cpp",
+        "-f1 -f2    -f3 -f4-f5",
+        "test.c",
+        "test.out",
+        false,
+        {
+            NULL
+        },
+        {
+            "cpp", "-f1", "-f2", "-f3", "-f4-f5", "-o", "test.out",
+            "test.c", NULL
+        },
+    },
+
+    {
+        "Some optional arguments",
+        "cpp",
+        "",
+        "test.c",
+        "test.out",
+        true,
+        {
+            "-o1", "-o2", NULL
+        },
+        {
+            "cpp", "-o1", "-o2", "-o", "test.out", "test.c", NULL
+        },
+    },
+
+    {
+        "Some cppflags and optional arguments",
+        "cpp",
+        "-f1",
+        "test.c",
+        "test.out",
+        true,
+        {
+            "-o1", "-o2", NULL
+        },
+        {
+            "cpp", "-f1", "-o1", "-o2", "-o", "test.out", "test.c", NULL
+        },
+    },
+
+    {
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        false,
+        { NULL },
+        { NULL },
+    },
+};
+
+static struct cxx_o_test {
+    const char *msg;
+    const char *cxx;
+    const char *cxxflags;
+    const char *cppflags;
+    const char *sfile;
+    const char *ofile;
+    bool hasoptargs;
+    const char *const optargs[16];
+    const char *const expargv[16];
+} cxx_o_tests[] = {
+    {
+        "No flags",
+        "c++",
+        "",
+        "",
+        "test.c",
+        "test.o",
+        false,
+        {
+            NULL
+        },
+        {
+            "c++", "-o", "test.o", "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Multi-word program name",
+        "c++ -foo",
+        "",
+        "",
+        "test.c",
+        "test.o",
+        false,
+        {
+            NULL
+        },
+        {
+            "c++", "-foo", "-o", "test.o", "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Some cxxflags",
+        "c++",
+        "-f1 -f2    -f3 -f4-f5",
+        "",
+        "test.c",
+        "test.o",
+        false,
+        {
+            NULL
+        },
+        {
+            "c++", "-f1", "-f2", "-f3", "-f4-f5", "-o", "test.o",
+            "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Some cppflags",
+        "c++",
+        "",
+        "-f1 -f2    -f3 -f4-f5",
+        "test.c",
+        "test.o",
+        false,
+        {
+            NULL
+        },
+        {
+            "c++", "-f1", "-f2", "-f3", "-f4-f5", "-o", "test.o",
+            "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Some cxxflags and cppflags",
+        "c++",
+        "-f2",
+        "-f1",
+        "test.c",
+        "test.o",
+        false,
+        {
+            NULL
+        },
+        {
+            "c++", "-f1", "-f2", "-o", "test.o", "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Some optional arguments",
+        "c++",
+        "",
+        "",
+        "test.c",
+        "test.o",
+        true,
+        {
+            "-o1", "-o2", NULL
+        },
+        {
+            "c++", "-o1", "-o2", "-o", "test.o", "-c", "test.c", NULL
+        },
+    },
+
+    {
+        "Some cxxflags, cppflags and optional arguments",
+        "c++",
+        "-f2",
+        "-f1",
+        "test.c",
+        "test.o",
+        true,
+        {
+            "-o1", "-o2", NULL
+        },
+        {
+            "c++", "-f1", "-f2", "-o1", "-o2", "-o", "test.o",
+            "-c", "test.c", NULL
+        },
+    },
+
+    {
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        false,
+        { NULL },
+        { NULL },
+    },
+};

Added: vendor/atf/dist/atf-c/macros.h
===================================================================
--- vendor/atf/dist/atf-c/macros.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/macros.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,212 @@
+/* Copyright (c) 2008 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_C_MACROS_H)
+#define ATF_C_MACROS_H
+
+#include <string.h>
+
+#include <atf-c/defs.h>
+#include <atf-c/error.h>
+#include <atf-c/tc.h>
+#include <atf-c/tp.h>
+#include <atf-c/utils.h>
+
+#define ATF_TC_NAME(tc) \
+    (atfu_ ## tc ## _tc)
+
+#define ATF_TC_PACK_NAME(tc) \
+    (atfu_ ## tc ## _tc_pack)
+
+#define ATF_TC_WITHOUT_HEAD(tc) \
+    static void atfu_ ## tc ## _body(const atf_tc_t *); \
+    static atf_tc_t atfu_ ## tc ## _tc; \
+    static atf_tc_pack_t atfu_ ## tc ## _tc_pack = { \
+        .m_ident = #tc, \
+        .m_head = NULL, \
+        .m_body = atfu_ ## tc ## _body, \
+        .m_cleanup = NULL, \
+    }
+
+#define ATF_TC(tc) \
+    static void atfu_ ## tc ## _head(atf_tc_t *); \
+    static void atfu_ ## tc ## _body(const atf_tc_t *); \
+    static atf_tc_t atfu_ ## tc ## _tc; \
+    static atf_tc_pack_t atfu_ ## tc ## _tc_pack = { \
+        .m_ident = #tc, \
+        .m_head = atfu_ ## tc ## _head, \
+        .m_body = atfu_ ## tc ## _body, \
+        .m_cleanup = NULL, \
+    }
+
+#define ATF_TC_WITH_CLEANUP(tc) \
+    static void atfu_ ## tc ## _head(atf_tc_t *); \
+    static void atfu_ ## tc ## _body(const atf_tc_t *); \
+    static void atfu_ ## tc ## _cleanup(const atf_tc_t *); \
+    static atf_tc_t atfu_ ## tc ## _tc; \
+    static atf_tc_pack_t atfu_ ## tc ## _tc_pack = { \
+        .m_ident = #tc, \
+        .m_head = atfu_ ## tc ## _head, \
+        .m_body = atfu_ ## tc ## _body, \
+        .m_cleanup = atfu_ ## tc ## _cleanup, \
+    }
+
+#define ATF_TC_HEAD(tc, tcptr) \
+    static \
+    void \
+    atfu_ ## tc ## _head(atf_tc_t *tcptr ATF_DEFS_ATTRIBUTE_UNUSED)
+
+#define ATF_TC_HEAD_NAME(tc) \
+    (atfu_ ## tc ## _head)
+
+#define ATF_TC_BODY(tc, tcptr) \
+    static \
+    void \
+    atfu_ ## tc ## _body(const atf_tc_t *tcptr ATF_DEFS_ATTRIBUTE_UNUSED)
+
+#define ATF_TC_BODY_NAME(tc) \
+    (atfu_ ## tc ## _body)
+
+#define ATF_TC_CLEANUP(tc, tcptr) \
+    static \
+    void \
+    atfu_ ## tc ## _cleanup(const atf_tc_t *tcptr ATF_DEFS_ATTRIBUTE_UNUSED)
+
+#define ATF_TC_CLEANUP_NAME(tc) \
+    (atfu_ ## tc ## _cleanup)
+
+#define ATF_TP_ADD_TCS(tps) \
+    static atf_error_t atfu_tp_add_tcs(atf_tp_t *); \
+    int atf_tp_main(int, char **, atf_error_t (*)(atf_tp_t *)); \
+    \
+    int \
+    main(int argc, char **argv) \
+    { \
+        return atf_tp_main(argc, argv, atfu_tp_add_tcs); \
+    } \
+    static \
+    atf_error_t \
+    atfu_tp_add_tcs(atf_tp_t *tps)
+
+#define ATF_TP_ADD_TC(tp, tc) \
+    do { \
+        atf_error_t atfu_err; \
+        char **atfu_config = atf_tp_get_config(tp); \
+        if (atfu_config == NULL) \
+            return atf_no_memory_error(); \
+        atfu_err = atf_tc_init_pack(&atfu_ ## tc ## _tc, \
+                                    &atfu_ ## tc ## _tc_pack, \
+                                    (const char *const *)atfu_config); \
+        atf_utils_free_charpp(atfu_config); \
+        if (atf_is_error(atfu_err)) \
+            return atfu_err; \
+        atfu_err = atf_tp_add_tc(tp, &atfu_ ## tc ## _tc); \
+        if (atf_is_error(atfu_err)) \
+            return atfu_err; \
+    } while (0)
+
+#define ATF_REQUIRE_MSG(expression, fmt, ...) \
+    do { \
+        if (!(expression)) \
+            atf_tc_fail_requirement(__FILE__, __LINE__, fmt, ##__VA_ARGS__); \
+    } while(0)
+
+#define ATF_CHECK_MSG(expression, fmt, ...) \
+    do { \
+        if (!(expression)) \
+            atf_tc_fail_check(__FILE__, __LINE__, fmt, ##__VA_ARGS__); \
+    } while(0)
+
+#define ATF_REQUIRE(expression) \
+    do { \
+        if (!(expression)) \
+            atf_tc_fail_requirement(__FILE__, __LINE__, "%s", \
+                                    #expression " not met"); \
+    } while(0)
+
+#define ATF_CHECK(expression) \
+    do { \
+        if (!(expression)) \
+            atf_tc_fail_check(__FILE__, __LINE__, "%s", \
+                              #expression " not met"); \
+    } while(0)
+
+#define ATF_REQUIRE_EQ(expected, actual) \
+    ATF_REQUIRE_MSG((expected) == (actual), "%s != %s", #expected, #actual)
+
+#define ATF_CHECK_EQ(expected, actual) \
+    ATF_CHECK_MSG((expected) == (actual), "%s != %s", #expected, #actual)
+
+#define ATF_REQUIRE_EQ_MSG(expected, actual, fmt, ...) \
+    ATF_REQUIRE_MSG((expected) == (actual), "%s != %s: " fmt, \
+                    #expected, #actual, ##__VA_ARGS__)
+
+#define ATF_CHECK_EQ_MSG(expected, actual, fmt, ...) \
+    ATF_CHECK_MSG((expected) == (actual), "%s != %s: " fmt, \
+                  #expected, #actual, ##__VA_ARGS__)
+
+#define ATF_REQUIRE_STREQ(expected, actual) \
+    ATF_REQUIRE_MSG(strcmp(expected, actual) == 0, "%s != %s (%s != %s)", \
+                    #expected, #actual, expected, actual)
+
+#define ATF_CHECK_STREQ(expected, actual) \
+    ATF_CHECK_MSG(strcmp(expected, actual) == 0, "%s != %s (%s != %s)", \
+                  #expected, #actual, expected, actual)
+
+#define ATF_REQUIRE_STREQ_MSG(expected, actual, fmt, ...) \
+    ATF_REQUIRE_MSG(strcmp(expected, actual) == 0, \
+                    "%s != %s (%s != %s): " fmt, \
+                    #expected, #actual, expected, actual, ##__VA_ARGS__)
+
+#define ATF_CHECK_STREQ_MSG(expected, actual, fmt, ...) \
+    ATF_CHECK_MSG(strcmp(expected, actual) == 0, \
+                  "%s != %s (%s != %s): " fmt, \
+                  #expected, #actual, expected, actual, ##__VA_ARGS__)
+
+#define ATF_REQUIRE_MATCH(regexp, string) \
+    ATF_REQUIRE_MSG(atf_utils_grep_string("%s", string, regexp), \
+                    "'%s' not matched in '%s'", regexp, string);
+
+#define ATF_CHECK_MATCH(regexp, string) \
+    ATF_CHECK_MSG(atf_utils_grep_string("%s", string, regexp), \
+                  "'%s' not matched in '%s'", regexp, string);
+
+#define ATF_REQUIRE_MATCH_MSG(regexp, string, fmt, ...) \
+    ATF_REQUIRE_MSG(atf_utils_grep_string("%s", string, regexp), \
+                    "'%s' not matched in '%s': " fmt, regexp, string, \
+                    ##__VA_ARGS__);
+
+#define ATF_CHECK_MATCH_MSG(regexp, string, fmt, ...) \
+    ATF_CHECK_MSG(atf_utils_grep_string("%s", string, regexp), \
+                  "'%s' not matched in '%s': " fmt, regexp, string, \
+                  ##__VA_ARGS__);
+
+#define ATF_CHECK_ERRNO(exp_errno, bool_expr) \
+    atf_tc_check_errno(__FILE__, __LINE__, exp_errno, #bool_expr, bool_expr)
+
+#define ATF_REQUIRE_ERRNO(exp_errno, bool_expr) \
+    atf_tc_require_errno(__FILE__, __LINE__, exp_errno, #bool_expr, bool_expr)
+
+#endif /* !defined(ATF_C_MACROS_H) */

Added: vendor/atf/dist/atf-c/macros_h_test.c
===================================================================
--- vendor/atf/dist/atf-c/macros_h_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/macros_h_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,102 @@
+/* Copyright (c) 2008 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/macros.h>
+
+void atf_require_inside_if(void);
+void atf_require_equal_inside_if(void);
+void atf_check_errno_semicolons(void);
+void atf_require_errno_semicolons(void);
+
+void
+atf_require_inside_if(void)
+{
+    /* Make sure that ATF_REQUIRE can be used inside an if statement that
+     * does not have braces.  Earlier versions of it generated an error
+     * if there was an else clause because they confused the compiler
+     * by defining an unprotected nested if. */
+    if (true)
+        ATF_REQUIRE(true);
+    else
+        ATF_REQUIRE(true);
+}
+
+void
+atf_require_equal_inside_if(void)
+{
+    /* Make sure that ATF_REQUIRE_EQUAL can be used inside an if statement
+     * that does not have braces.  Earlier versions of it generated an
+     * error if there was an else clause because they confused the
+     * compiler by defining an unprotected nested if. */
+    if (true)
+        ATF_REQUIRE_EQ(true, true);
+    else
+        ATF_REQUIRE_EQ(true, true);
+}
+
+void
+atf_check_errno_semicolons(void)
+{
+    /* Check that ATF_CHECK_ERRNO does not contain a semicolon that would
+     * cause an empty-statement that confuses some compilers. */
+    ATF_CHECK_ERRNO(1, 1 == 1);
+    ATF_CHECK_ERRNO(2, 2 == 2);
+}
+
+void
+atf_require_errno_semicolons(void)
+{
+    /* Check that ATF_REQUIRE_ERRNO does not contain a semicolon that would
+     * cause an empty-statement that confuses some compilers. */
+    ATF_REQUIRE_ERRNO(1, 1 == 1);
+    ATF_REQUIRE_ERRNO(2, 2 == 2);
+}
+
+/* Test case names should not be expanded during instatiation so that they
+ * can have the exact same name as macros. */
+#define TEST_MACRO_1 invalid + name
+#define TEST_MACRO_2 invalid + name
+#define TEST_MACRO_3 invalid + name
+ATF_TC(TEST_MACRO_1);
+ATF_TC_HEAD(TEST_MACRO_1, tc) { if (tc != NULL) {} }
+ATF_TC_BODY(TEST_MACRO_1, tc) { if (tc != NULL) {} }
+atf_tc_t *test_name_1 = &ATF_TC_NAME(TEST_MACRO_1);
+atf_tc_pack_t *test_pack_1 = &ATF_TC_PACK_NAME(TEST_MACRO_1);
+void (*head_1)(atf_tc_t *) = ATF_TC_HEAD_NAME(TEST_MACRO_1);
+void (*body_1)(const atf_tc_t *) = ATF_TC_BODY_NAME(TEST_MACRO_1);
+ATF_TC_WITH_CLEANUP(TEST_MACRO_2);
+ATF_TC_HEAD(TEST_MACRO_2, tc) { if (tc != NULL) {} }
+ATF_TC_BODY(TEST_MACRO_2, tc) { if (tc != NULL) {} }
+ATF_TC_CLEANUP(TEST_MACRO_2, tc) { if (tc != NULL) {} }
+atf_tc_t *test_name_2 = &ATF_TC_NAME(TEST_MACRO_2);
+atf_tc_pack_t *test_pack_2 = &ATF_TC_PACK_NAME(TEST_MACRO_2);
+void (*head_2)(atf_tc_t *) = ATF_TC_HEAD_NAME(TEST_MACRO_2);
+void (*body_2)(const atf_tc_t *) = ATF_TC_BODY_NAME(TEST_MACRO_2);
+void (*cleanup_2)(const atf_tc_t *) = ATF_TC_CLEANUP_NAME(TEST_MACRO_2);
+ATF_TC_WITHOUT_HEAD(TEST_MACRO_3);
+ATF_TC_BODY(TEST_MACRO_3, tc) { if (tc != NULL) {} }
+atf_tc_t *test_name_3 = &ATF_TC_NAME(TEST_MACRO_3);
+atf_tc_pack_t *test_pack_3 = &ATF_TC_PACK_NAME(TEST_MACRO_3);
+void (*body_3)(const atf_tc_t *) = ATF_TC_BODY_NAME(TEST_MACRO_3);

Added: vendor/atf/dist/atf-c/macros_test.c
===================================================================
--- vendor/atf/dist/atf-c/macros_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/macros_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,893 @@
+/* Copyright (c) 2008 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/macros.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/fs.h"
+#include "atf-c/detail/process.h"
+#include "atf-c/detail/test_helpers.h"
+#include "atf-c/detail/text.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+create_ctl_file(const char *name)
+{
+    atf_fs_path_t p;
+
+    RE(atf_fs_path_init_fmt(&p, "%s", name));
+    ATF_REQUIRE(open(atf_fs_path_cstring(&p),
+                   O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1);
+    atf_fs_path_fini(&p);
+}
+
+static
+bool
+exists(const char *p)
+{
+    bool b;
+    atf_fs_path_t pp;
+
+    RE(atf_fs_path_init_fmt(&pp, "%s", p));
+    RE(atf_fs_exists(&pp, &b));
+    atf_fs_path_fini(&pp);
+
+    return b;
+}
+
+static
+void
+init_and_run_h_tc(const char *name, void (*head)(atf_tc_t *),
+                  void (*body)(const atf_tc_t *))
+{
+    atf_tc_t tc;
+    const char *const config[] = { NULL };
+
+    RE(atf_tc_init(&tc, name, head, body, NULL, config));
+    run_h_tc(&tc, "output", "error", "result");
+    atf_tc_fini(&tc);
+}
+
+/* ---------------------------------------------------------------------
+ * Helper test cases.
+ * --------------------------------------------------------------------- */
+
+#define H_DEF(id, macro) \
+    ATF_TC_HEAD(h_ ## id, tc) \
+    { \
+        atf_tc_set_md_var(tc, "descr", "Helper test case"); \
+    } \
+    ATF_TC_BODY(h_ ## id, tc) \
+    { \
+        create_ctl_file("before"); \
+        macro; \
+        create_ctl_file("after"); \
+    }
+
+#define H_CHECK_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_ ## id)
+#define H_CHECK_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_ ## id)
+#define H_CHECK(id, condition) \
+    H_DEF(check_ ## id, ATF_CHECK(condition))
+
+#define H_CHECK_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_msg_ ## id)
+#define H_CHECK_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_msg_ ## id)
+#define H_CHECK_MSG(id, condition, msg) \
+    H_DEF(check_msg_ ## id, ATF_CHECK_MSG(condition, msg))
+
+#define H_CHECK_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_eq_ ## id)
+#define H_CHECK_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_eq_ ## id)
+#define H_CHECK_EQ(id, v1, v2) \
+    H_DEF(check_eq_ ## id, ATF_CHECK_EQ(v1, v2))
+
+#define H_CHECK_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_streq_ ## id)
+#define H_CHECK_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_streq_ ## id)
+#define H_CHECK_STREQ(id, v1, v2) \
+    H_DEF(check_streq_ ## id, ATF_CHECK_STREQ(v1, v2))
+
+#define H_CHECK_MATCH_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_match_ ## id)
+#define H_CHECK_MATCH_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_match_ ## id)
+#define H_CHECK_MATCH(id, v1, v2) \
+    H_DEF(check_match_ ## id, ATF_CHECK_MATCH(v1, v2))
+
+#define H_CHECK_EQ_MSG_HEAD_NAME(id) \
+    ATF_TC_HEAD_NAME(h_check_eq_msg_ ## id)
+#define H_CHECK_EQ_MSG_BODY_NAME(id) \
+    ATF_TC_BODY_NAME(h_check_eq_msg_ ## id)
+#define H_CHECK_EQ_MSG(id, v1, v2, msg) \
+    H_DEF(check_eq_msg_ ## id, ATF_CHECK_EQ_MSG(v1, v2, msg))
+
+#define H_CHECK_STREQ_MSG_HEAD_NAME(id) \
+    ATF_TC_HEAD_NAME(h_check_streq_msg_ ## id)
+#define H_CHECK_STREQ_MSG_BODY_NAME(id) \
+    ATF_TC_BODY_NAME(h_check_streq_msg_ ## id)
+#define H_CHECK_STREQ_MSG(id, v1, v2, msg) \
+    H_DEF(check_streq_msg_ ## id, ATF_CHECK_STREQ_MSG(v1, v2, msg))
+
+#define H_CHECK_MATCH_MSG_HEAD_NAME(id) \
+    ATF_TC_HEAD_NAME(h_check_match_msg_ ## id)
+#define H_CHECK_MATCH_MSG_BODY_NAME(id) \
+    ATF_TC_BODY_NAME(h_check_match_msg_ ## id)
+#define H_CHECK_MATCH_MSG(id, v1, v2, msg) \
+    H_DEF(check_match_msg_ ## id, ATF_CHECK_MATCH_MSG(v1, v2, msg))
+
+#define H_CHECK_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_errno_ ## id)
+#define H_CHECK_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_errno_ ## id)
+#define H_CHECK_ERRNO(id, exp_errno, bool_expr) \
+    H_DEF(check_errno_ ## id, ATF_CHECK_ERRNO(exp_errno, bool_expr))
+
+#define H_REQUIRE_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_ ## id)
+#define H_REQUIRE_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_ ## id)
+#define H_REQUIRE(id, condition) \
+    H_DEF(require_ ## id, ATF_REQUIRE(condition))
+
+#define H_REQUIRE_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_msg_ ## id)
+#define H_REQUIRE_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_msg_ ## id)
+#define H_REQUIRE_MSG(id, condition, msg) \
+    H_DEF(require_msg_ ## id, ATF_REQUIRE_MSG(condition, msg))
+
+#define H_REQUIRE_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_eq_ ## id)
+#define H_REQUIRE_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_eq_ ## id)
+#define H_REQUIRE_EQ(id, v1, v2) \
+    H_DEF(require_eq_ ## id, ATF_REQUIRE_EQ(v1, v2))
+
+#define H_REQUIRE_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_streq_ ## id)
+#define H_REQUIRE_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_streq_ ## id)
+#define H_REQUIRE_STREQ(id, v1, v2) \
+    H_DEF(require_streq_ ## id, ATF_REQUIRE_STREQ(v1, v2))
+
+#define H_REQUIRE_MATCH_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_match_ ## id)
+#define H_REQUIRE_MATCH_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_match_ ## id)
+#define H_REQUIRE_MATCH(id, v1, v2) \
+    H_DEF(require_match_ ## id, ATF_REQUIRE_MATCH(v1, v2))
+
+#define H_REQUIRE_EQ_MSG_HEAD_NAME(id) \
+    ATF_TC_HEAD_NAME(h_require_eq_msg_ ## id)
+#define H_REQUIRE_EQ_MSG_BODY_NAME(id) \
+    ATF_TC_BODY_NAME(h_require_eq_msg_ ## id)
+#define H_REQUIRE_EQ_MSG(id, v1, v2, msg) \
+    H_DEF(require_eq_msg_ ## id, ATF_REQUIRE_EQ_MSG(v1, v2, msg))
+
+#define H_REQUIRE_STREQ_MSG_HEAD_NAME(id) \
+    ATF_TC_HEAD_NAME(h_require_streq_msg_ ## id)
+#define H_REQUIRE_STREQ_MSG_BODY_NAME(id) \
+    ATF_TC_BODY_NAME(h_require_streq_msg_ ## id)
+#define H_REQUIRE_STREQ_MSG(id, v1, v2, msg) \
+    H_DEF(require_streq_msg_ ## id, ATF_REQUIRE_STREQ_MSG(v1, v2, msg))
+
+#define H_REQUIRE_MATCH_MSG_HEAD_NAME(id) \
+    ATF_TC_HEAD_NAME(h_require_match_msg_ ## id)
+#define H_REQUIRE_MATCH_MSG_BODY_NAME(id) \
+    ATF_TC_BODY_NAME(h_require_match_msg_ ## id)
+#define H_REQUIRE_MATCH_MSG(id, v1, v2, msg) \
+    H_DEF(require_match_msg_ ## id, ATF_REQUIRE_MATCH_MSG(v1, v2, msg))
+
+#define H_REQUIRE_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_errno_ ## id)
+#define H_REQUIRE_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_errno_ ## id)
+#define H_REQUIRE_ERRNO(id, exp_errno, bool_expr) \
+    H_DEF(require_errno_ ## id, ATF_REQUIRE_ERRNO(exp_errno, bool_expr))
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_{CHECK,REQUIRE}_ERRNO macros.
+ * --------------------------------------------------------------------- */
+
+static int
+errno_fail_stub(const int raised_errno)
+{
+    errno = raised_errno;
+    return -1;
+}
+
+static int
+errno_ok_stub(void)
+{
+    return 0;
+}
+
+H_CHECK_ERRNO(no_error, -1, errno_ok_stub() == -1);
+H_CHECK_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1);
+H_CHECK_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1);
+
+H_REQUIRE_ERRNO(no_error, -1, errno_ok_stub() == -1);
+H_REQUIRE_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1);
+H_REQUIRE_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1);
+
+ATF_TC(check_errno);
+ATF_TC_HEAD(check_errno, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_ERRNO macro");
+}
+ATF_TC_BODY(check_errno, tc)
+{
+    struct test {
+        void (*head)(atf_tc_t *);
+        void (*body)(const atf_tc_t *);
+        bool ok;
+        const char *exp_regex;
+    } *t, tests[] = {
+        { H_CHECK_ERRNO_HEAD_NAME(no_error),
+          H_CHECK_ERRNO_BODY_NAME(no_error),
+          false, "Expected true value in errno_ok_stub\\(\\) == -1" },
+        { H_CHECK_ERRNO_HEAD_NAME(errno_ok),
+          H_CHECK_ERRNO_BODY_NAME(errno_ok),
+          true, NULL },
+        { H_CHECK_ERRNO_HEAD_NAME(errno_fail),
+          H_CHECK_ERRNO_BODY_NAME(errno_fail),
+          false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
+        { NULL, NULL, false, NULL }
+    };
+
+    for (t = &tests[0]; t->head != NULL; t++) {
+        init_and_run_h_tc("h_check_errno", t->head, t->body);
+
+        ATF_REQUIRE(exists("before"));
+        ATF_REQUIRE(exists("after"));
+
+        if (t->ok) {
+            ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
+        } else {
+            ATF_REQUIRE(atf_utils_grep_file("^failed", "result"));
+            ATF_REQUIRE(atf_utils_grep_file(
+                "macros_test.c:[0-9]+: %s$", "error", t->exp_regex));
+        }
+
+        ATF_REQUIRE(unlink("before") != -1);
+        ATF_REQUIRE(unlink("after") != -1);
+    }
+}
+
+ATF_TC(require_errno);
+ATF_TC_HEAD(require_errno, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_ERRNO macro");
+}
+ATF_TC_BODY(require_errno, tc)
+{
+    struct test {
+        void (*head)(atf_tc_t *);
+        void (*body)(const atf_tc_t *);
+        bool ok;
+        const char *exp_regex;
+    } *t, tests[] = {
+        { H_REQUIRE_ERRNO_HEAD_NAME(no_error),
+          H_REQUIRE_ERRNO_BODY_NAME(no_error),
+          false, "Expected true value in errno_ok_stub\\(\\) == -1" },
+        { H_REQUIRE_ERRNO_HEAD_NAME(errno_ok),
+          H_REQUIRE_ERRNO_BODY_NAME(errno_ok),
+          true, NULL },
+        { H_REQUIRE_ERRNO_HEAD_NAME(errno_fail),
+          H_REQUIRE_ERRNO_BODY_NAME(errno_fail),
+          false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
+        { NULL, NULL, false, NULL }
+    };
+
+    for (t = &tests[0]; t->head != NULL; t++) {
+        init_and_run_h_tc("h_require_errno", t->head, t->body);
+
+        ATF_REQUIRE(exists("before"));
+        if (t->ok) {
+            ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
+            ATF_REQUIRE(exists("after"));
+        } else {
+            ATF_REQUIRE(atf_utils_grep_file(
+                "^failed: .*macros_test.c:[0-9]+: %s$", "result",
+                t->exp_regex));
+            ATF_REQUIRE(!exists("after"));
+        }
+
+        ATF_REQUIRE(unlink("before") != -1);
+        if (t->ok)
+            ATF_REQUIRE(unlink("after") != -1);
+    }
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_CHECK and ATF_CHECK_MSG macros.
+ * --------------------------------------------------------------------- */
+
+H_CHECK(0, 0);
+H_CHECK(1, 1);
+H_CHECK_MSG(0, 0, "expected a false value");
+H_CHECK_MSG(1, 1, "expected a true value");
+
+ATF_TC(check);
+ATF_TC_HEAD(check, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK and "
+                      "ATF_CHECK_MSG macros");
+}
+ATF_TC_BODY(check, tc)
+{
+    struct test {
+        void (*head)(atf_tc_t *);
+        void (*body)(const atf_tc_t *);
+        bool value;
+        const char *msg;
+        bool ok;
+    } *t, tests[] = {
+        { H_CHECK_HEAD_NAME(0), H_CHECK_BODY_NAME(0), 0,
+          "0 not met", false },
+        { H_CHECK_HEAD_NAME(1), H_CHECK_BODY_NAME(1), 1,
+          "1 not met", true },
+        { H_CHECK_MSG_HEAD_NAME(0), H_CHECK_MSG_BODY_NAME(0), 0,
+          "expected a false value", false },
+        { H_CHECK_MSG_HEAD_NAME(1), H_CHECK_MSG_BODY_NAME(1), 1,
+          "expected a true value", true },
+        { NULL, NULL, false, NULL, false }
+    };
+
+    for (t = &tests[0]; t->head != NULL; t++) {
+        printf("Checking with a %d value\n", t->value);
+
+        init_and_run_h_tc("h_check", t->head, t->body);
+
+        ATF_REQUIRE(exists("before"));
+        ATF_REQUIRE(exists("after"));
+
+        if (t->ok) {
+            ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
+        } else {
+            ATF_REQUIRE(atf_utils_grep_file("^failed", "result"));
+            ATF_REQUIRE(atf_utils_grep_file("Check failed: .*"
+                "macros_test.c:[0-9]+: %s$", "error", t->msg));
+        }
+
+        ATF_REQUIRE(unlink("before") != -1);
+        ATF_REQUIRE(unlink("after") != -1);
+    }
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_CHECK_*EQ_ macros.
+ * --------------------------------------------------------------------- */
+
+struct check_eq_test {
+    void (*head)(atf_tc_t *);
+    void (*body)(const atf_tc_t *);
+    const char *v1;
+    const char *v2;
+    const char *msg;
+    bool ok;
+};
+
+static
+void
+do_check_eq_tests(const struct check_eq_test *tests)
+{
+    const struct check_eq_test *t;
+
+    for (t = &tests[0]; t->head != NULL; t++) {
+        printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2,
+               t->ok ? "true" : "false");
+
+        init_and_run_h_tc("h_check", t->head, t->body);
+
+        ATF_CHECK(exists("before"));
+        ATF_CHECK(exists("after"));
+
+        if (t->ok) {
+            ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
+        } else {
+            ATF_REQUIRE(atf_utils_grep_file("^failed", "result"));
+            ATF_CHECK(atf_utils_grep_file("Check failed: .*"
+                "macros_test.c:[0-9]+: %s$", "error", t->msg));
+        }
+
+        ATF_CHECK(unlink("before") != -1);
+        ATF_CHECK(unlink("after") != -1);
+    }
+}
+
+H_CHECK_EQ(1_1, 1, 1);
+H_CHECK_EQ(1_2, 1, 2);
+H_CHECK_EQ(2_1, 2, 1);
+H_CHECK_EQ(2_2, 2, 2);
+H_CHECK_EQ_MSG(1_1, 1, 1, "1 does not match 1");
+H_CHECK_EQ_MSG(1_2, 1, 2, "1 does not match 2");
+H_CHECK_EQ_MSG(2_1, 2, 1, "2 does not match 1");
+H_CHECK_EQ_MSG(2_2, 2, 2, "2 does not match 2");
+
+ATF_TC(check_eq);
+ATF_TC_HEAD(check_eq, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_EQ and "
+                      "ATF_CHECK_EQ_MSG macros");
+}
+ATF_TC_BODY(check_eq, tc)
+{
+    struct check_eq_test tests[] = {
+        { H_CHECK_EQ_HEAD_NAME(1_1), H_CHECK_EQ_BODY_NAME(1_1),
+          "1", "1", "1 != 1", true },
+        { H_CHECK_EQ_HEAD_NAME(1_2), H_CHECK_EQ_BODY_NAME(1_2),
+          "1", "2", "1 != 2", false },
+        { H_CHECK_EQ_HEAD_NAME(2_1), H_CHECK_EQ_BODY_NAME(2_1),
+          "2", "1", "2 != 1", false },
+        { H_CHECK_EQ_HEAD_NAME(2_2), H_CHECK_EQ_BODY_NAME(2_2),
+          "2", "2", "2 != 2", true },
+        { H_CHECK_EQ_MSG_HEAD_NAME(1_1), H_CHECK_EQ_MSG_BODY_NAME(1_1),
+          "1", "1", "1 != 1: 1 does not match 1", true },
+        { H_CHECK_EQ_MSG_HEAD_NAME(1_2), H_CHECK_EQ_MSG_BODY_NAME(1_2),
+          "1", "2", "1 != 2: 1 does not match 2", false },
+        { H_CHECK_EQ_MSG_HEAD_NAME(2_1), H_CHECK_EQ_MSG_BODY_NAME(2_1),
+          "2", "1", "2 != 1: 2 does not match 1", false },
+        { H_CHECK_EQ_MSG_HEAD_NAME(2_2), H_CHECK_EQ_MSG_BODY_NAME(2_2),
+          "2", "2", "2 != 2: 2 does not match 2", true },
+        { NULL, NULL, 0, 0, "", false }
+    };
+    do_check_eq_tests(tests);
+}
+
+H_CHECK_STREQ(1_1, "1", "1");
+H_CHECK_STREQ(1_2, "1", "2");
+H_CHECK_STREQ(2_1, "2", "1");
+H_CHECK_STREQ(2_2, "2", "2");
+H_CHECK_STREQ_MSG(1_1, "1", "1", "1 does not match 1");
+H_CHECK_STREQ_MSG(1_2, "1", "2", "1 does not match 2");
+H_CHECK_STREQ_MSG(2_1, "2", "1", "2 does not match 1");
+H_CHECK_STREQ_MSG(2_2, "2", "2", "2 does not match 2");
+#define CHECK_STREQ_VAR1 "5"
+#define CHECK_STREQ_VAR2 "9"
+const char *check_streq_var1 = CHECK_STREQ_VAR1;
+const char *check_streq_var2 = CHECK_STREQ_VAR2;
+H_CHECK_STREQ(vars, check_streq_var1, check_streq_var2);
+
+ATF_TC(check_streq);
+ATF_TC_HEAD(check_streq, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_STREQ and "
+                      "ATF_CHECK_STREQ_MSG macros");
+}
+ATF_TC_BODY(check_streq, tc)
+{
+    struct check_eq_test tests[] = {
+        { H_CHECK_STREQ_HEAD_NAME(1_1), H_CHECK_STREQ_BODY_NAME(1_1),
+          "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true },
+        { H_CHECK_STREQ_HEAD_NAME(1_2), H_CHECK_STREQ_BODY_NAME(1_2),
+          "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false },
+        { H_CHECK_STREQ_HEAD_NAME(2_1), H_CHECK_STREQ_BODY_NAME(2_1),
+          "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false },
+        { H_CHECK_STREQ_HEAD_NAME(2_2), H_CHECK_STREQ_BODY_NAME(2_2),
+          "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true },
+        { H_CHECK_STREQ_MSG_HEAD_NAME(1_1),
+          H_CHECK_STREQ_MSG_BODY_NAME(1_1),
+          "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true },
+        { H_CHECK_STREQ_MSG_HEAD_NAME(1_2),
+          H_CHECK_STREQ_MSG_BODY_NAME(1_2),
+          "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false },
+        { H_CHECK_STREQ_MSG_HEAD_NAME(2_1),
+          H_CHECK_STREQ_MSG_BODY_NAME(2_1),
+          "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false },
+        { H_CHECK_STREQ_MSG_HEAD_NAME(2_2),
+          H_CHECK_STREQ_MSG_BODY_NAME(2_2),
+          "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true },
+        { H_CHECK_STREQ_HEAD_NAME(vars), H_CHECK_STREQ_BODY_NAME(vars),
+          check_streq_var1, check_streq_var2,
+          "check_streq_var1 != check_streq_var2 \\("
+          CHECK_STREQ_VAR1 " != " CHECK_STREQ_VAR2 "\\)", false },
+        { NULL, NULL, 0, 0, "", false }
+    };
+    do_check_eq_tests(tests);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_CHECK_MATCH and ATF_CHECK_MATCH_MSG macros.
+ * --------------------------------------------------------------------- */
+
+H_CHECK_MATCH(yes, "hello [a-z]+", "abc hello world");
+H_CHECK_MATCH(no, "hello [a-z]+", "abc hello WORLD");
+H_CHECK_MATCH_MSG(yes, "hello [a-z]+", "abc hello world", "lowercase");
+H_CHECK_MATCH_MSG(no, "hello [a-z]+", "abc hello WORLD", "uppercase");
+
+ATF_TC(check_match);
+ATF_TC_HEAD(check_match, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_MATCH and "
+                      "ATF_CHECK_MATCH_MSG macros");
+}
+ATF_TC_BODY(check_match, tc)
+{
+    struct check_eq_test tests[] = {
+        { H_CHECK_MATCH_HEAD_NAME(yes), H_CHECK_MATCH_BODY_NAME(yes),
+          "hello [a-z]+", "abc hello world", "", true },
+        { H_CHECK_MATCH_HEAD_NAME(no), H_CHECK_MATCH_BODY_NAME(no),
+          "hello [a-z]+", "abc hello WORLD",
+          "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD'", false },
+        { H_CHECK_MATCH_MSG_HEAD_NAME(yes), H_CHECK_MATCH_MSG_BODY_NAME(yes),
+          "hello [a-z]+", "abc hello world", "", true },
+        { H_CHECK_MATCH_MSG_HEAD_NAME(no), H_CHECK_MATCH_MSG_BODY_NAME(no),
+          "hello [a-z]+", "abc hello WORLD",
+          "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD': uppercase",
+          false },
+        { NULL, NULL, 0, 0, "", false }
+    };
+    do_check_eq_tests(tests);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_REQUIRE and ATF_REQUIRE_MSG macros.
+ * --------------------------------------------------------------------- */
+
+H_REQUIRE(0, 0);
+H_REQUIRE(1, 1);
+H_REQUIRE_MSG(0, 0, "expected a false value");
+H_REQUIRE_MSG(1, 1, "expected a true value");
+
+ATF_TC(require);
+ATF_TC_HEAD(require, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE and "
+                      "ATF_REQUIRE_MSG macros");
+}
+ATF_TC_BODY(require, tc)
+{
+    struct test {
+        void (*head)(atf_tc_t *);
+        void (*body)(const atf_tc_t *);
+        bool value;
+        const char *msg;
+        bool ok;
+    } *t, tests[] = {
+        { H_REQUIRE_HEAD_NAME(0), H_REQUIRE_BODY_NAME(0), 0,
+          "0 not met", false },
+        { H_REQUIRE_HEAD_NAME(1), H_REQUIRE_BODY_NAME(1), 1,
+          "1 not met", true },
+        { H_REQUIRE_MSG_HEAD_NAME(0), H_REQUIRE_MSG_BODY_NAME(0), 0,
+          "expected a false value", false },
+        { H_REQUIRE_MSG_HEAD_NAME(1), H_REQUIRE_MSG_BODY_NAME(1), 1,
+          "expected a true value", true },
+        { NULL, NULL, false, NULL, false }
+    };
+
+    for (t = &tests[0]; t->head != NULL; t++) {
+        printf("Checking with a %d value\n", t->value);
+
+        init_and_run_h_tc("h_require", t->head, t->body);
+
+        ATF_REQUIRE(exists("before"));
+        if (t->ok) {
+            ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
+            ATF_REQUIRE(exists("after"));
+        } else {
+            ATF_REQUIRE(atf_utils_grep_file(
+                "^failed: .*macros_test.c:[0-9]+: %s$", "result", t->msg));
+            ATF_REQUIRE(!exists("after"));
+        }
+
+        ATF_REQUIRE(unlink("before") != -1);
+        if (t->ok)
+            ATF_REQUIRE(unlink("after") != -1);
+    }
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_REQUIRE_*EQ_ macros.
+ * --------------------------------------------------------------------- */
+
+struct require_eq_test {
+    void (*head)(atf_tc_t *);
+    void (*body)(const atf_tc_t *);
+    const char *v1;
+    const char *v2;
+    const char *msg;
+    bool ok;
+};
+
+static
+void
+do_require_eq_tests(const struct require_eq_test *tests)
+{
+    const struct require_eq_test *t;
+
+    for (t = &tests[0]; t->head != NULL; t++) {
+        printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2,
+               t->ok ? "true" : "false");
+
+        init_and_run_h_tc("h_require", t->head, t->body);
+
+        ATF_REQUIRE(exists("before"));
+        if (t->ok) {
+            ATF_REQUIRE(atf_utils_grep_file("^passed", "result"));
+            ATF_REQUIRE(exists("after"));
+        } else {
+            ATF_REQUIRE(atf_utils_grep_file("^failed: .*macros_test.c"
+                ":[0-9]+: %s$", "result", t->msg));
+            ATF_REQUIRE(!exists("after"));
+        }
+
+        ATF_REQUIRE(unlink("before") != -1);
+        if (t->ok)
+            ATF_REQUIRE(unlink("after") != -1);
+    }
+}
+
+H_REQUIRE_EQ(1_1, 1, 1);
+H_REQUIRE_EQ(1_2, 1, 2);
+H_REQUIRE_EQ(2_1, 2, 1);
+H_REQUIRE_EQ(2_2, 2, 2);
+H_REQUIRE_EQ_MSG(1_1, 1, 1, "1 does not match 1");
+H_REQUIRE_EQ_MSG(1_2, 1, 2, "1 does not match 2");
+H_REQUIRE_EQ_MSG(2_1, 2, 1, "2 does not match 1");
+H_REQUIRE_EQ_MSG(2_2, 2, 2, "2 does not match 2");
+
+ATF_TC(require_eq);
+ATF_TC_HEAD(require_eq, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_EQ and "
+                      "ATF_REQUIRE_EQ_MSG macros");
+}
+ATF_TC_BODY(require_eq, tc)
+{
+    struct require_eq_test tests[] = {
+        { H_REQUIRE_EQ_HEAD_NAME(1_1), H_REQUIRE_EQ_BODY_NAME(1_1),
+          "1", "1", "1 != 1", true },
+        { H_REQUIRE_EQ_HEAD_NAME(1_2), H_REQUIRE_EQ_BODY_NAME(1_2),
+          "1", "2", "1 != 2", false },
+        { H_REQUIRE_EQ_HEAD_NAME(2_1), H_REQUIRE_EQ_BODY_NAME(2_1),
+          "2", "1", "2 != 1", false },
+        { H_REQUIRE_EQ_HEAD_NAME(2_2), H_REQUIRE_EQ_BODY_NAME(2_2),
+          "2", "2", "2 != 2", true },
+        { H_REQUIRE_EQ_MSG_HEAD_NAME(1_1), H_REQUIRE_EQ_MSG_BODY_NAME(1_1),
+          "1", "1", "1 != 1: 1 does not match 1", true },
+        { H_REQUIRE_EQ_MSG_HEAD_NAME(1_2), H_REQUIRE_EQ_MSG_BODY_NAME(1_2),
+          "1", "2", "1 != 2: 1 does not match 2", false },
+        { H_REQUIRE_EQ_MSG_HEAD_NAME(2_1), H_REQUIRE_EQ_MSG_BODY_NAME(2_1),
+          "2", "1", "2 != 1: 2 does not match 1", false },
+        { H_REQUIRE_EQ_MSG_HEAD_NAME(2_2), H_REQUIRE_EQ_MSG_BODY_NAME(2_2),
+          "2", "2", "2 != 2: 2 does not match 2", true },
+        { NULL, NULL, 0, 0, "", false }
+    };
+    do_require_eq_tests(tests);
+}
+
+H_REQUIRE_STREQ(1_1, "1", "1");
+H_REQUIRE_STREQ(1_2, "1", "2");
+H_REQUIRE_STREQ(2_1, "2", "1");
+H_REQUIRE_STREQ(2_2, "2", "2");
+H_REQUIRE_STREQ_MSG(1_1, "1", "1", "1 does not match 1");
+H_REQUIRE_STREQ_MSG(1_2, "1", "2", "1 does not match 2");
+H_REQUIRE_STREQ_MSG(2_1, "2", "1", "2 does not match 1");
+H_REQUIRE_STREQ_MSG(2_2, "2", "2", "2 does not match 2");
+#define REQUIRE_STREQ_VAR1 "5"
+#define REQUIRE_STREQ_VAR2 "9"
+const char *require_streq_var1 = REQUIRE_STREQ_VAR1;
+const char *require_streq_var2 = REQUIRE_STREQ_VAR2;
+H_REQUIRE_STREQ(vars, require_streq_var1, require_streq_var2);
+
+ATF_TC(require_streq);
+ATF_TC_HEAD(require_streq, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_STREQ and "
+                      "ATF_REQUIRE_STREQ_MSG macros");
+}
+ATF_TC_BODY(require_streq, tc)
+{
+    struct require_eq_test tests[] = {
+        { H_REQUIRE_STREQ_HEAD_NAME(1_1), H_REQUIRE_STREQ_BODY_NAME(1_1),
+          "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true },
+        { H_REQUIRE_STREQ_HEAD_NAME(1_2), H_REQUIRE_STREQ_BODY_NAME(1_2),
+          "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false },
+        { H_REQUIRE_STREQ_HEAD_NAME(2_1), H_REQUIRE_STREQ_BODY_NAME(2_1),
+          "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false },
+        { H_REQUIRE_STREQ_HEAD_NAME(2_2), H_REQUIRE_STREQ_BODY_NAME(2_2),
+          "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true },
+        { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_1),
+          H_REQUIRE_STREQ_MSG_BODY_NAME(1_1),
+          "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true },
+        { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_2),
+          H_REQUIRE_STREQ_MSG_BODY_NAME(1_2),
+          "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false },
+        { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_1),
+          H_REQUIRE_STREQ_MSG_BODY_NAME(2_1),
+          "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false },
+        { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_2),
+          H_REQUIRE_STREQ_MSG_BODY_NAME(2_2),
+          "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true },
+        { H_REQUIRE_STREQ_HEAD_NAME(vars), H_REQUIRE_STREQ_BODY_NAME(vars),
+          require_streq_var1, require_streq_var2,
+          "require_streq_var1 != require_streq_var2 \\("
+          REQUIRE_STREQ_VAR1 " != " REQUIRE_STREQ_VAR2 "\\)", false },
+        { NULL, NULL, 0, 0, "", false }
+    };
+    do_require_eq_tests(tests);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the ATF_REQUIRE_MATCH and ATF_REQUIRE_MATCH_MSG macros.
+ * --------------------------------------------------------------------- */
+
+H_REQUIRE_MATCH(yes, "hello [a-z]+", "abc hello world");
+H_REQUIRE_MATCH(no, "hello [a-z]+", "abc hello WORLD");
+H_REQUIRE_MATCH_MSG(yes, "hello [a-z]+", "abc hello world", "lowercase");
+H_REQUIRE_MATCH_MSG(no, "hello [a-z]+", "abc hello WORLD", "uppercase");
+
+ATF_TC(require_match);
+ATF_TC_HEAD(require_match, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_MATCH and "
+                      "ATF_REQUIRE_MATCH_MSG macros");
+}
+ATF_TC_BODY(require_match, tc)
+{
+    struct require_eq_test tests[] = {
+        { H_REQUIRE_MATCH_HEAD_NAME(yes), H_REQUIRE_MATCH_BODY_NAME(yes),
+          "hello [a-z]+", "abc hello world", "", true },
+        { H_REQUIRE_MATCH_HEAD_NAME(no), H_REQUIRE_MATCH_BODY_NAME(no),
+          "hello [a-z]+", "abc hello WORLD",
+          "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD'", false },
+        { H_REQUIRE_MATCH_MSG_HEAD_NAME(yes),
+          H_REQUIRE_MATCH_MSG_BODY_NAME(yes),
+          "hello [a-z]+", "abc hello world", "", true },
+        { H_REQUIRE_MATCH_MSG_HEAD_NAME(no), H_REQUIRE_MATCH_MSG_BODY_NAME(no),
+          "hello [a-z]+", "abc hello WORLD",
+          "'hello \\[a-z\\]\\+' not matched in 'abc hello WORLD': uppercase",
+          false },
+        { NULL, NULL, 0, 0, "", false }
+    };
+    do_require_eq_tests(tests);
+}
+
+/* ---------------------------------------------------------------------
+ * Miscellaneous test cases covering several macros.
+ * --------------------------------------------------------------------- */
+
+static
+bool
+aux_bool(const char *fmt ATF_DEFS_ATTRIBUTE_UNUSED)
+{
+    return false;
+}
+
+static
+const char *
+aux_str(const char *fmt ATF_DEFS_ATTRIBUTE_UNUSED)
+{
+    return "foo";
+}
+
+H_CHECK(msg, aux_bool("%d"));
+H_REQUIRE(msg, aux_bool("%d"));
+H_CHECK_STREQ(msg, aux_str("%d"), "");
+H_REQUIRE_STREQ(msg, aux_str("%d"), "");
+
+ATF_TC(msg_embedded_fmt);
+ATF_TC_HEAD(msg_embedded_fmt, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests that format strings passed "
+                      "as part of the automatically-generated messages "
+                      "do not get expanded");
+}
+ATF_TC_BODY(msg_embedded_fmt, tc)
+{
+    struct test {
+        void (*head)(atf_tc_t *);
+        void (*body)(const atf_tc_t *);
+        bool fatal;
+        const char *msg;
+    } *t, tests[] = {
+       {  H_CHECK_HEAD_NAME(msg), H_CHECK_BODY_NAME(msg), false,
+          "aux_bool\\(\"%d\"\\) not met" },
+       {  H_REQUIRE_HEAD_NAME(msg), H_REQUIRE_BODY_NAME(msg), true,
+          "aux_bool\\(\"%d\"\\) not met" },
+       {  H_CHECK_STREQ_HEAD_NAME(msg), H_CHECK_STREQ_BODY_NAME(msg), false,
+          "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" },
+       {  H_REQUIRE_STREQ_HEAD_NAME(msg), H_REQUIRE_STREQ_BODY_NAME(msg), true,
+          "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" },
+       { NULL, NULL, false, NULL }
+    };
+
+    for (t = &tests[0]; t->head != NULL; t++) {
+        printf("Checking with an expected '%s' message\n", t->msg);
+
+        init_and_run_h_tc("h_check", t->head, t->body);
+
+        if (t->fatal) {
+            bool matched =
+                atf_utils_grep_file(
+                    "^failed: .*macros_test.c:[0-9]+: %s$", "result", t->msg);
+            ATF_CHECK_MSG(matched, "couldn't find error string in result");
+        } else {
+            bool matched = atf_utils_grep_file("Check failed: .*"
+                "macros_test.c:[0-9]+: %s$", "error", t->msg);
+            ATF_CHECK_MSG(matched, "couldn't find error string in output");
+        }
+    }
+}
+
+/* ---------------------------------------------------------------------
+ * Tests cases for the header file.
+ * --------------------------------------------------------------------- */
+
+BUILD_TC(use, "macros_h_test.c",
+         "Tests that the macros provided by the atf-c/macros.h file "
+         "do not cause syntax errors when used",
+         "Build of macros_h_test.c failed; some macros in atf-c/macros.h "
+         "are broken");
+
+ATF_TC(detect_unused_tests);
+ATF_TC_HEAD(detect_unused_tests, tc)
+{
+    atf_tc_set_md_var(tc, "descr",
+                      "Tests that defining an unused test case raises a "
+                      "warning (and thus an error)");
+}
+ATF_TC_BODY(detect_unused_tests, tc)
+{
+    const char* validate_compiler =
+        "struct test_struct { int dummy; };\n"
+        "#define define_unused static struct test_struct unused\n"
+        "define_unused;\n";
+
+    atf_utils_create_file("compiler_test.c", "%s", validate_compiler);
+    if (build_check_c_o("compiler_test.c"))
+        atf_tc_expect_fail("Compiler does not raise a warning on an unused "
+                           "static global variable declared by a macro");
+
+    if (build_check_c_o_srcdir(tc, "unused_test.c"))
+        atf_tc_fail("Build of unused_test.c passed; unused test cases are "
+                    "not properly detected");
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    ATF_TP_ADD_TC(tp, check);
+    ATF_TP_ADD_TC(tp, check_eq);
+    ATF_TP_ADD_TC(tp, check_streq);
+    ATF_TP_ADD_TC(tp, check_errno);
+    ATF_TP_ADD_TC(tp, check_match);
+
+    ATF_TP_ADD_TC(tp, require);
+    ATF_TP_ADD_TC(tp, require_eq);
+    ATF_TP_ADD_TC(tp, require_streq);
+    ATF_TP_ADD_TC(tp, require_errno);
+    ATF_TP_ADD_TC(tp, require_match);
+
+    ATF_TP_ADD_TC(tp, msg_embedded_fmt);
+
+    /* Add the test cases for the header file. */
+    ATF_TP_ADD_TC(tp, use);
+    ATF_TP_ADD_TC(tp, detect_unused_tests);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/pkg_config_test.sh
===================================================================
--- vendor/atf/dist/atf-c/pkg_config_test.sh	                        (rev 0)
+++ vendor/atf/dist/atf-c/pkg_config_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,143 @@
+# Copyright (c) 2008 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.
+
+# The following tests assume that the atf-c.pc file is installed in a
+# directory that is known by pkg-config.  Otherwise they will fail,
+# and you will be required to adjust PKG_CONFIG_PATH accordingly.
+#
+# It would be possible to bypass this requirement by setting the path
+# explicitly during the tests, but then this would not do a real check
+# to ensure that the installation is working.
+
+require_pc()
+{
+    pkg-config ${1} || atf_fail "pkg-config could not locate ${1}.pc;" \
+                                "maybe need to set PKG_CONFIG_PATH?"
+}
+
+check_version()
+{
+    ver1=$($(atf_get_srcdir)/detail/version_helper)
+    echo "Version reported by builtin PACKAGE_VERSION: ${ver1}"
+
+    atf_check -s eq:0 -o save:stdout -e empty pkg-config --modversion "${1}"
+    ver2=$(cat stdout)
+    echo "Version reported by pkg-config: ${ver2}"
+
+    atf_check_equal ${ver1} ${ver2}
+}
+
+atf_test_case version
+version_head()
+{
+    atf_set "descr" "Checks that the version in atf-c is correct"
+    atf_set "require.progs" "pkg-config"
+}
+version_body()
+{
+    require_pc "atf-c"
+
+    check_version "atf-c"
+}
+
+atf_test_case build
+build_head()
+{
+    atf_set "descr" "Checks that a test program can be built against" \
+                    "the C library based on the pkg-config information"
+    atf_set "require.progs" "pkg-config"
+}
+build_body()
+{
+    require_pc "atf-c"
+
+    atf_check -s eq:0 -o save:stdout -e empty pkg-config --variable=cc atf-c
+    cc=$(cat stdout)
+    echo "Compiler is: ${cxx}"
+    atf_require_prog ${cxx}
+
+    cat >tp.c <<EOF
+#include <stdio.h>
+
+#include <atf-c.h>
+
+ATF_TC(tc);
+ATF_TC_HEAD(tc, tc) {
+    atf_tc_set_md_var(tc, "descr", "A test case");
+}
+ATF_TC_BODY(tc, tc) {
+    printf("Running\n");
+}
+
+ATF_TP_ADD_TCS(tp) {
+    ATF_TP_ADD_TC(tp, tc);
+
+    return atf_no_error();
+}
+EOF
+
+    atf_check -s eq:0 -o save:stdout -e empty pkg-config --cflags atf-c
+    cflags=$(cat stdout)
+    echo "CFLAGS are: ${cflags}"
+
+    atf_check -s eq:0 -o save:stdout -e empty \
+        pkg-config --libs-only-L --libs-only-other atf-c
+    ldflags=$(cat stdout)
+    atf_check -s eq:0 -o save:stdout -e empty pkg-config --libs-only-l atf-c
+    libs=$(cat stdout)
+    echo "LDFLAGS are: ${ldflags}"
+    echo "LIBS are: ${libs}"
+
+    atf_check -s eq:0 -o empty -e empty ${cc} ${cflags} -o tp.o -c tp.c
+    atf_check -s eq:0 -o empty -e empty ${cc} ${ldflags} -o tp tp.o ${libs}
+
+    libpath=
+    for f in ${ldflags}; do
+        case ${f} in
+            -L*)
+                dir=$(echo ${f} | sed -e 's,^-L,,')
+                if [ -z "${libpath}" ]; then
+                    libpath="${dir}"
+                else
+                    libpath="${libpath}:${dir}"
+                fi
+                ;;
+            *)
+                ;;
+        esac
+    done
+
+    atf_check -s eq:0 -o empty -e empty test -x tp
+    atf_check -s eq:0 -o match:'Running' -e empty -x \
+              "LD_LIBRARY_PATH=${libpath} ./tp tc"
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case version
+    atf_add_test_case build
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/atf-c/tc.c
===================================================================
--- vendor/atf/dist/atf-c/tc.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/tc.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,1217 @@
+/* Copyright (c) 2008 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/tc.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "atf-c/defs.h"
+#include "atf-c/detail/env.h"
+#include "atf-c/detail/fs.h"
+#include "atf-c/detail/map.h"
+#include "atf-c/detail/sanity.h"
+#include "atf-c/detail/text.h"
+#include "atf-c/error.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+enum expect_type {
+    EXPECT_PASS,
+    EXPECT_FAIL,
+    EXPECT_EXIT,
+    EXPECT_SIGNAL,
+    EXPECT_DEATH,
+    EXPECT_TIMEOUT,
+};
+
+struct context {
+    const atf_tc_t *tc;
+    const char *resfile;
+    size_t fail_count;
+
+    enum expect_type expect;
+    atf_dynstr_t expect_reason;
+    size_t expect_previous_fail_count;
+    size_t expect_fail_count;
+    int expect_exitcode;
+    int expect_signo;
+};
+
+static void context_init(struct context *, const atf_tc_t *, const char *);
+static void check_fatal_error(atf_error_t);
+static void report_fatal_error(const char *, ...)
+    ATF_DEFS_ATTRIBUTE_NORETURN;
+static atf_error_t write_resfile(const int, const char *, const int,
+                                 const atf_dynstr_t *);
+static void create_resfile(const char *, const char *, const int,
+                           atf_dynstr_t *);
+static void error_in_expect(struct context *, const char *, ...)
+    ATF_DEFS_ATTRIBUTE_NORETURN;
+static void validate_expect(struct context *);
+static void expected_failure(struct context *, atf_dynstr_t *)
+    ATF_DEFS_ATTRIBUTE_NORETURN;
+static void fail_requirement(struct context *, atf_dynstr_t *)
+    ATF_DEFS_ATTRIBUTE_NORETURN;
+static void fail_check(struct context *, atf_dynstr_t *);
+static void pass(struct context *)
+    ATF_DEFS_ATTRIBUTE_NORETURN;
+static void skip(struct context *, atf_dynstr_t *)
+    ATF_DEFS_ATTRIBUTE_NORETURN;
+static void format_reason_ap(atf_dynstr_t *, const char *, const size_t,
+                             const char *, va_list);
+static void format_reason_fmt(atf_dynstr_t *, const char *, const size_t,
+                              const char *, ...);
+static void errno_test(struct context *, const char *, const size_t,
+                       const int, const char *, const bool,
+                       void (*)(struct context *, atf_dynstr_t *));
+static atf_error_t check_prog_in_dir(const char *, void *);
+static atf_error_t check_prog(struct context *, const char *);
+
+static void
+context_init(struct context *ctx, const atf_tc_t *tc, const char *resfile)
+{
+    ctx->tc = tc;
+    ctx->resfile = resfile;
+    ctx->fail_count = 0;
+    ctx->expect = EXPECT_PASS;
+    check_fatal_error(atf_dynstr_init(&ctx->expect_reason));
+    ctx->expect_previous_fail_count = 0;
+    ctx->expect_fail_count = 0;
+    ctx->expect_exitcode = 0;
+    ctx->expect_signo = 0;
+}
+
+static void
+check_fatal_error(atf_error_t err)
+{
+    if (atf_is_error(err)) {
+        char buf[1024];
+        atf_error_format(err, buf, sizeof(buf));
+        fprintf(stderr, "FATAL ERROR: %s\n", buf);
+        atf_error_free(err);
+        abort();
+    }
+}
+
+static void
+report_fatal_error(const char *msg, ...)
+{
+    va_list ap;
+    fprintf(stderr, "FATAL ERROR: ");
+
+    va_start(ap, msg);
+    vfprintf(stderr, msg, ap);
+    va_end(ap);
+
+    fprintf(stderr, "\n");
+    abort();
+}
+
+/** Writes to a results file.
+ *
+ * The results file is supposed to be already open.
+ *
+ * This function returns an error code instead of exiting in case of error
+ * because the caller needs to clean up the reason object before terminating.
+ */
+static atf_error_t
+write_resfile(const int fd, const char *result, const int arg,
+              const atf_dynstr_t *reason)
+{
+    static char NL[] = "\n", CS[] = ": ";
+    char buf[64];
+    const char *r;
+    struct iovec iov[5];
+    ssize_t ret;
+    int count = 0;
+
+    INV(arg == -1 || reason != NULL);
+
+#define UNCONST(a) ((void *)(unsigned long)(const void *)(a))
+    iov[count].iov_base = UNCONST(result);
+    iov[count++].iov_len = strlen(result);
+
+    if (reason != NULL) {
+        if (arg != -1) {
+            iov[count].iov_base = buf;
+            iov[count++].iov_len = snprintf(buf, sizeof(buf), "(%d)", arg);
+        }
+
+        iov[count].iov_base = CS;
+        iov[count++].iov_len = sizeof(CS) - 1;
+
+        r = atf_dynstr_cstring(reason);
+        iov[count].iov_base = UNCONST(r);
+        iov[count++].iov_len = strlen(r);
+    }
+#undef UNCONST
+
+    iov[count].iov_base = NL;
+    iov[count++].iov_len = sizeof(NL) - 1;
+
+    while ((ret = writev(fd, iov, count)) == -1 && errno == EINTR)
+        continue; /* Retry. */
+    if (ret != -1)
+        return atf_no_error();
+
+    return atf_libc_error(
+        errno, "Failed to write results file; result %s, reason %s", result,
+        reason == NULL ? "null" : atf_dynstr_cstring(reason));
+}
+
+/** Creates a results file.
+ *
+ * The input reason is released in all cases.
+ *
+ * An error in this function is considered to be fatal, hence why it does
+ * not return any error code.
+ */
+static void
+create_resfile(const char *resfile, const char *result, const int arg,
+               atf_dynstr_t *reason)
+{
+    atf_error_t err;
+
+    if (strcmp("/dev/stdout", resfile) == 0) {
+        err = write_resfile(STDOUT_FILENO, result, arg, reason);
+    } else if (strcmp("/dev/stderr", resfile) == 0) {
+        err = write_resfile(STDERR_FILENO, result, arg, reason);
+    } else {
+        const int fd = open(resfile, O_WRONLY | O_CREAT | O_TRUNC,
+            S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+        if (fd == -1) {
+            err = atf_libc_error(errno, "Cannot create results file '%s'",
+                                 resfile);
+        } else {
+            err = write_resfile(fd, result, arg, reason);
+            close(fd);
+        }
+    }
+
+    if (reason != NULL)
+        atf_dynstr_fini(reason);
+
+    check_fatal_error(err);
+}
+
+/** Fails a test case if validate_expect fails. */
+static void
+error_in_expect(struct context *ctx, const char *fmt, ...)
+{
+    atf_dynstr_t reason;
+    va_list ap;
+
+    va_start(ap, fmt);
+    format_reason_ap(&reason, NULL, 0, fmt, ap);
+    va_end(ap);
+
+    ctx->expect = EXPECT_PASS;  /* Ensure fail_requirement really fails. */
+    fail_requirement(ctx, &reason);
+}
+
+/** Ensures that the "expect" state is correct.
+ *
+ * Call this function before modifying the current value of expect.
+ */
+static void
+validate_expect(struct context *ctx)
+{
+    if (ctx->expect == EXPECT_DEATH) {
+        error_in_expect(ctx, "Test case was expected to terminate abruptly "
+            "but it continued execution");
+    } else if (ctx->expect == EXPECT_EXIT) {
+        error_in_expect(ctx, "Test case was expected to exit cleanly but it "
+            "continued execution");
+    } else if (ctx->expect == EXPECT_FAIL) {
+        if (ctx->expect_fail_count == ctx->expect_previous_fail_count)
+            error_in_expect(ctx, "Test case was expecting a failure but none "
+                "were raised");
+        else
+            INV(ctx->expect_fail_count > ctx->expect_previous_fail_count);
+    } else if (ctx->expect == EXPECT_PASS) {
+        /* Nothing to validate. */
+    } else if (ctx->expect == EXPECT_SIGNAL) {
+        error_in_expect(ctx, "Test case was expected to receive a termination "
+            "signal but it continued execution");
+    } else if (ctx->expect == EXPECT_TIMEOUT) {
+        error_in_expect(ctx, "Test case was expected to hang but it continued "
+            "execution");
+    } else
+        UNREACHABLE;
+}
+
+static void
+expected_failure(struct context *ctx, atf_dynstr_t *reason)
+{
+    check_fatal_error(atf_dynstr_prepend_fmt(reason, "%s: ",
+        atf_dynstr_cstring(&ctx->expect_reason)));
+    create_resfile(ctx->resfile, "expected_failure", -1, reason);
+    exit(EXIT_SUCCESS);
+}
+
+static void
+fail_requirement(struct context *ctx, atf_dynstr_t *reason)
+{
+    if (ctx->expect == EXPECT_FAIL) {
+        expected_failure(ctx, reason);
+    } else if (ctx->expect == EXPECT_PASS) {
+        create_resfile(ctx->resfile, "failed", -1, reason);
+        exit(EXIT_FAILURE);
+    } else {
+        error_in_expect(ctx, "Test case raised a failure but was not "
+            "expecting one; reason was %s", atf_dynstr_cstring(reason));
+    }
+    UNREACHABLE;
+}
+
+static void
+fail_check(struct context *ctx, atf_dynstr_t *reason)
+{
+    if (ctx->expect == EXPECT_FAIL) {
+        fprintf(stderr, "*** Expected check failure: %s: %s\n",
+            atf_dynstr_cstring(&ctx->expect_reason),
+            atf_dynstr_cstring(reason));
+        ctx->expect_fail_count++;
+    } else if (ctx->expect == EXPECT_PASS) {
+        fprintf(stderr, "*** Check failed: %s\n", atf_dynstr_cstring(reason));
+        ctx->fail_count++;
+    } else {
+        error_in_expect(ctx, "Test case raised a failure but was not "
+            "expecting one; reason was %s", atf_dynstr_cstring(reason));
+    }
+
+    atf_dynstr_fini(reason);
+}
+
+static void
+pass(struct context *ctx)
+{
+    if (ctx->expect == EXPECT_FAIL) {
+        error_in_expect(ctx, "Test case was expecting a failure but got "
+            "a pass instead");
+    } else if (ctx->expect == EXPECT_PASS) {
+        create_resfile(ctx->resfile, "passed", -1, NULL);
+        exit(EXIT_SUCCESS);
+    } else {
+        error_in_expect(ctx, "Test case asked to explicitly pass but was "
+            "not expecting such condition");
+    }
+    UNREACHABLE;
+}
+
+static void
+skip(struct context *ctx, atf_dynstr_t *reason)
+{
+    if (ctx->expect == EXPECT_PASS) {
+        create_resfile(ctx->resfile, "skipped", -1, reason);
+        exit(EXIT_SUCCESS);
+    } else {
+        error_in_expect(ctx, "Can only skip a test case when running in "
+            "expect pass mode");
+    }
+    UNREACHABLE;
+}
+
+/** Formats a failure/skip reason message.
+ *
+ * The formatted reason is stored in out_reason.  out_reason is initialized
+ * in this function and is supposed to be released by the caller.  In general,
+ * the reason will eventually be fed to create_resfile, which will release
+ * it.
+ *
+ * Errors in this function are fatal.  Rationale being: reasons are used to
+ * create results files; if we can't format the reason correctly, the result
+ * of the test program will be bogus.  So it's better to just exit with a
+ * fatal error.
+ */
+static void
+format_reason_ap(atf_dynstr_t *out_reason,
+                 const char *source_file, const size_t source_line,
+                 const char *reason, va_list ap)
+{
+    atf_error_t err;
+
+    if (source_file != NULL) {
+        err = atf_dynstr_init_fmt(out_reason, "%s:%zd: ", source_file,
+                                  source_line);
+    } else {
+        PRE(source_line == 0);
+        err = atf_dynstr_init(out_reason);
+    }
+
+    if (!atf_is_error(err)) {
+        va_list ap2;
+        va_copy(ap2, ap);
+        err = atf_dynstr_append_ap(out_reason, reason, ap2);
+        va_end(ap2);
+    }
+
+    check_fatal_error(err);
+}
+
+static void
+format_reason_fmt(atf_dynstr_t *out_reason,
+                  const char *source_file, const size_t source_line,
+                  const char *reason, ...)
+{
+    va_list ap;
+
+    va_start(ap, reason);
+    format_reason_ap(out_reason, source_file, source_line, reason, ap);
+    va_end(ap);
+}
+
+static void
+errno_test(struct context *ctx, const char *file, const size_t line,
+           const int exp_errno, const char *expr_str,
+           const bool expr_result,
+           void (*fail_func)(struct context *, atf_dynstr_t *))
+{
+    const int actual_errno = errno;
+
+    if (expr_result) {
+        if (exp_errno != actual_errno) {
+            atf_dynstr_t reason;
+
+            format_reason_fmt(&reason, file, line, "Expected errno %d, got %d, "
+                "in %s", exp_errno, actual_errno, expr_str);
+            fail_func(ctx, &reason);
+        }
+    } else {
+        atf_dynstr_t reason;
+
+        format_reason_fmt(&reason, file, line, "Expected true value in %s",
+            expr_str);
+        fail_func(ctx, &reason);
+    }
+}
+
+struct prog_found_pair {
+    const char *prog;
+    bool found;
+};
+
+static atf_error_t
+check_prog_in_dir(const char *dir, void *data)
+{
+    struct prog_found_pair *pf = data;
+    atf_error_t err;
+
+    if (pf->found)
+        err = atf_no_error();
+    else {
+        atf_fs_path_t p;
+
+        err = atf_fs_path_init_fmt(&p, "%s/%s", dir, pf->prog);
+        if (atf_is_error(err))
+            goto out_p;
+
+        err = atf_fs_eaccess(&p, atf_fs_access_x);
+        if (!atf_is_error(err))
+            pf->found = true;
+        else {
+            atf_error_free(err);
+            INV(!pf->found);
+            err = atf_no_error();
+        }
+
+out_p:
+        atf_fs_path_fini(&p);
+    }
+
+    return err;
+}
+
+static atf_error_t
+check_prog(struct context *ctx, const char *prog)
+{
+    atf_error_t err;
+    atf_fs_path_t p;
+
+    err = atf_fs_path_init_fmt(&p, "%s", prog);
+    if (atf_is_error(err))
+        goto out;
+
+    if (atf_fs_path_is_absolute(&p)) {
+        err = atf_fs_eaccess(&p, atf_fs_access_x);
+        if (atf_is_error(err)) {
+            atf_dynstr_t reason;
+
+            atf_error_free(err);
+            atf_fs_path_fini(&p);
+            format_reason_fmt(&reason, NULL, 0, "The required program %s could "
+                "not be found", prog);
+            skip(ctx, &reason);
+        }
+    } else {
+        const char *path = atf_env_get("PATH");
+        struct prog_found_pair pf;
+        atf_fs_path_t bp;
+
+        err = atf_fs_path_branch_path(&p, &bp);
+        if (atf_is_error(err))
+            goto out_p;
+
+        if (strcmp(atf_fs_path_cstring(&bp), ".") != 0) {
+            atf_fs_path_fini(&bp);
+            atf_fs_path_fini(&p);
+
+            report_fatal_error("Relative paths are not allowed when searching "
+                "for a program (%s)", prog);
+            UNREACHABLE;
+        }
+
+        pf.prog = prog;
+        pf.found = false;
+        err = atf_text_for_each_word(path, ":", check_prog_in_dir, &pf);
+        if (atf_is_error(err))
+            goto out_bp;
+
+        if (!pf.found) {
+            atf_dynstr_t reason;
+
+            atf_fs_path_fini(&bp);
+            atf_fs_path_fini(&p);
+            format_reason_fmt(&reason, NULL, 0, "The required program %s could "
+                "not be found in the PATH", prog);
+            fail_requirement(ctx, &reason);
+        }
+
+out_bp:
+        atf_fs_path_fini(&bp);
+    }
+
+out_p:
+    atf_fs_path_fini(&p);
+out:
+    return err;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_tc" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_tc_impl {
+    const char *m_ident;
+
+    atf_map_t m_vars;
+    atf_map_t m_config;
+
+    atf_tc_head_t m_head;
+    atf_tc_body_t m_body;
+    atf_tc_cleanup_t m_cleanup;
+};
+
+/*
+ * Constructors/destructors.
+ */
+
+atf_error_t
+atf_tc_init(atf_tc_t *tc, const char *ident, atf_tc_head_t head,
+            atf_tc_body_t body, atf_tc_cleanup_t cleanup,
+            const char *const *config)
+{
+    atf_error_t err;
+
+    tc->pimpl = malloc(sizeof(struct atf_tc_impl));
+    if (tc->pimpl == NULL) {
+        err = atf_no_memory_error();
+        goto err;
+    }
+
+    tc->pimpl->m_ident = ident;
+    tc->pimpl->m_head = head;
+    tc->pimpl->m_body = body;
+    tc->pimpl->m_cleanup = cleanup;
+
+    err = atf_map_init_charpp(&tc->pimpl->m_config, config);
+    if (atf_is_error(err))
+        goto err;
+
+    err = atf_map_init(&tc->pimpl->m_vars);
+    if (atf_is_error(err))
+        goto err_vars;
+
+    err = atf_tc_set_md_var(tc, "ident", ident);
+    if (atf_is_error(err))
+        goto err_map;
+
+    if (cleanup != NULL) {
+        err = atf_tc_set_md_var(tc, "has.cleanup", "true");
+        if (atf_is_error(err))
+            goto err_map;
+    }
+
+    /* XXX Should the head be able to return error codes? */
+    if (tc->pimpl->m_head != NULL)
+        tc->pimpl->m_head(tc);
+
+    if (strcmp(atf_tc_get_md_var(tc, "ident"), ident) != 0) {
+        report_fatal_error("Test case head modified the read-only 'ident' "
+            "property");
+        UNREACHABLE;
+    }
+
+    INV(!atf_is_error(err));
+    return err;
+
+err_map:
+    atf_map_fini(&tc->pimpl->m_vars);
+err_vars:
+    atf_map_fini(&tc->pimpl->m_config);
+err:
+    return err;
+}
+
+atf_error_t
+atf_tc_init_pack(atf_tc_t *tc, const atf_tc_pack_t *pack,
+                 const char *const *config)
+{
+    return atf_tc_init(tc, pack->m_ident, pack->m_head, pack->m_body,
+                       pack->m_cleanup, config);
+}
+
+void
+atf_tc_fini(atf_tc_t *tc)
+{
+    atf_map_fini(&tc->pimpl->m_vars);
+    free(tc->pimpl);
+}
+
+/*
+ * Getters.
+ */
+
+const char *
+atf_tc_get_ident(const atf_tc_t *tc)
+{
+    return tc->pimpl->m_ident;
+}
+
+const char *
+atf_tc_get_config_var(const atf_tc_t *tc, const char *name)
+{
+    const char *val;
+    atf_map_citer_t iter;
+
+    PRE(atf_tc_has_config_var(tc, name));
+    iter = atf_map_find_c(&tc->pimpl->m_config, name);
+    val = atf_map_citer_data(iter);
+    INV(val != NULL);
+
+    return val;
+}
+
+const char *
+atf_tc_get_config_var_wd(const atf_tc_t *tc, const char *name,
+                         const char *defval)
+{
+    const char *val;
+
+    if (!atf_tc_has_config_var(tc, name))
+        val = defval;
+    else
+        val = atf_tc_get_config_var(tc, name);
+
+    return val;
+}
+
+bool
+atf_tc_get_config_var_as_bool(const atf_tc_t *tc, const char *name)
+{
+    bool val;
+    const char *strval;
+    atf_error_t err;
+
+    strval = atf_tc_get_config_var(tc, name);
+    err = atf_text_to_bool(strval, &val);
+    if (atf_is_error(err)) {
+        atf_error_free(err);
+        atf_tc_fail("Configuration variable %s does not have a valid "
+                    "boolean value; found %s", name, strval);
+    }
+
+    return val;
+}
+
+bool
+atf_tc_get_config_var_as_bool_wd(const atf_tc_t *tc, const char *name,
+                                 const bool defval)
+{
+    bool val;
+
+    if (!atf_tc_has_config_var(tc, name))
+        val = defval;
+    else
+        val = atf_tc_get_config_var_as_bool(tc, name);
+
+    return val;
+}
+
+long
+atf_tc_get_config_var_as_long(const atf_tc_t *tc, const char *name)
+{
+    long val;
+    const char *strval;
+    atf_error_t err;
+
+    strval = atf_tc_get_config_var(tc, name);
+    err = atf_text_to_long(strval, &val);
+    if (atf_is_error(err)) {
+        atf_error_free(err);
+        atf_tc_fail("Configuration variable %s does not have a valid "
+                    "long value; found %s", name, strval);
+    }
+
+    return val;
+}
+
+long
+atf_tc_get_config_var_as_long_wd(const atf_tc_t *tc, const char *name,
+                                 const long defval)
+{
+    long val;
+
+    if (!atf_tc_has_config_var(tc, name))
+        val = defval;
+    else
+        val = atf_tc_get_config_var_as_long(tc, name);
+
+    return val;
+}
+
+const char *
+atf_tc_get_md_var(const atf_tc_t *tc, const char *name)
+{
+    const char *val;
+    atf_map_citer_t iter;
+
+    PRE(atf_tc_has_md_var(tc, name));
+    iter = atf_map_find_c(&tc->pimpl->m_vars, name);
+    val = atf_map_citer_data(iter);
+    INV(val != NULL);
+
+    return val;
+}
+
+char **
+atf_tc_get_md_vars(const atf_tc_t *tc)
+{
+    return atf_map_to_charpp(&tc->pimpl->m_vars);
+}
+
+bool
+atf_tc_has_config_var(const atf_tc_t *tc, const char *name)
+{
+    atf_map_citer_t end, iter;
+
+    iter = atf_map_find_c(&tc->pimpl->m_config, name);
+    end = atf_map_end_c(&tc->pimpl->m_config);
+    return !atf_equal_map_citer_map_citer(iter, end);
+}
+
+bool
+atf_tc_has_md_var(const atf_tc_t *tc, const char *name)
+{
+    atf_map_citer_t end, iter;
+
+    iter = atf_map_find_c(&tc->pimpl->m_vars, name);
+    end = atf_map_end_c(&tc->pimpl->m_vars);
+    return !atf_equal_map_citer_map_citer(iter, end);
+}
+
+/*
+ * Modifiers.
+ */
+
+atf_error_t
+atf_tc_set_md_var(atf_tc_t *tc, const char *name, const char *fmt, ...)
+{
+    atf_error_t err;
+    char *value;
+    va_list ap;
+
+    va_start(ap, fmt);
+    err = atf_text_format_ap(&value, fmt, ap);
+    va_end(ap);
+
+    if (!atf_is_error(err))
+        err = atf_map_insert(&tc->pimpl->m_vars, name, value, true);
+    else
+        free(value);
+
+    return err;
+}
+
+/* ---------------------------------------------------------------------
+ * Free functions, as they should be publicly but they can't.
+ * --------------------------------------------------------------------- */
+
+static void _atf_tc_fail(struct context *, const char *, va_list)
+    ATF_DEFS_ATTRIBUTE_NORETURN;
+static void _atf_tc_fail_nonfatal(struct context *, const char *, va_list);
+static void _atf_tc_fail_check(struct context *, const char *, const size_t,
+    const char *, va_list);
+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;
+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;
+static void _atf_tc_check_errno(struct context *, const char *, const size_t,
+    const int, const char *, const bool);
+static void _atf_tc_require_errno(struct context *, const char *, const size_t,
+    const int, const char *, const bool);
+static void _atf_tc_expect_pass(struct context *);
+static void _atf_tc_expect_fail(struct context *, const char *, va_list);
+static void _atf_tc_expect_exit(struct context *, const int, const char *,
+    va_list);
+static void _atf_tc_expect_signal(struct context *, const int, const char *,
+    va_list);
+static void _atf_tc_expect_death(struct context *, const char *,
+    va_list);
+
+static void
+_atf_tc_fail(struct context *ctx, const char *fmt, va_list ap)
+{
+    va_list ap2;
+    atf_dynstr_t reason;
+
+    va_copy(ap2, ap);
+    format_reason_ap(&reason, NULL, 0, fmt, ap2);
+    va_end(ap2);
+
+    fail_requirement(ctx, &reason);
+    UNREACHABLE;
+}
+
+static void
+_atf_tc_fail_nonfatal(struct context *ctx, const char *fmt, va_list ap)
+{
+    va_list ap2;
+    atf_dynstr_t reason;
+
+    va_copy(ap2, ap);
+    format_reason_ap(&reason, NULL, 0, fmt, ap2);
+    va_end(ap2);
+
+    fail_check(ctx, &reason);
+}
+
+static void
+_atf_tc_fail_check(struct context *ctx, const char *file, const size_t line,
+                   const char *fmt, va_list ap)
+{
+    va_list ap2;
+    atf_dynstr_t reason;
+
+    va_copy(ap2, ap);
+    format_reason_ap(&reason, file, line, fmt, ap2);
+    va_end(ap2);
+
+    fail_check(ctx, &reason);
+}
+
+static void
+_atf_tc_fail_requirement(struct context *ctx, const char *file,
+                         const size_t line, const char *fmt, va_list ap)
+{
+    va_list ap2;
+    atf_dynstr_t reason;
+
+    va_copy(ap2, ap);
+    format_reason_ap(&reason, file, line, fmt, ap2);
+    va_end(ap2);
+
+    fail_requirement(ctx, &reason);
+    UNREACHABLE;
+}
+
+static void
+_atf_tc_pass(struct context *ctx)
+{
+    pass(ctx);
+    UNREACHABLE;
+}
+
+static void
+_atf_tc_require_prog(struct context *ctx, const char *prog)
+{
+    check_fatal_error(check_prog(ctx, prog));
+}
+
+static void
+_atf_tc_skip(struct context *ctx, const char *fmt, va_list ap)
+{
+    atf_dynstr_t reason;
+    va_list ap2;
+
+    va_copy(ap2, ap);
+    format_reason_ap(&reason, NULL, 0, fmt, ap2);
+    va_end(ap2);
+
+    skip(ctx, &reason);
+}
+
+static void
+_atf_tc_check_errno(struct context *ctx, const char *file, const size_t line,
+                    const int exp_errno, const char *expr_str,
+                    const bool expr_result)
+{
+    errno_test(ctx, file, line, exp_errno, expr_str, expr_result, fail_check);
+}
+
+static void
+_atf_tc_require_errno(struct context *ctx, const char *file, const size_t line,
+                      const int exp_errno, const char *expr_str,
+                      const bool expr_result)
+{
+    errno_test(ctx, file, line, exp_errno, expr_str, expr_result,
+        fail_requirement);
+}
+
+static void
+_atf_tc_expect_pass(struct context *ctx)
+{
+    validate_expect(ctx);
+
+    ctx->expect = EXPECT_PASS;
+}
+
+static void
+_atf_tc_expect_fail(struct context *ctx, const char *reason, va_list ap)
+{
+    va_list ap2;
+
+    validate_expect(ctx);
+
+    ctx->expect = EXPECT_FAIL;
+    atf_dynstr_fini(&ctx->expect_reason);
+    va_copy(ap2, ap);
+    check_fatal_error(atf_dynstr_init_ap(&ctx->expect_reason, reason, ap2));
+    va_end(ap2);
+    ctx->expect_previous_fail_count = ctx->expect_fail_count;
+}
+
+static void
+_atf_tc_expect_exit(struct context *ctx, const int exitcode, const char *reason,
+                    va_list ap)
+{
+    va_list ap2;
+    atf_dynstr_t formatted;
+
+    validate_expect(ctx);
+
+    ctx->expect = EXPECT_EXIT;
+    va_copy(ap2, ap);
+    check_fatal_error(atf_dynstr_init_ap(&formatted, reason, ap2));
+    va_end(ap2);
+
+    create_resfile(ctx->resfile, "expected_exit", exitcode, &formatted);
+}
+
+static void
+_atf_tc_expect_signal(struct context *ctx, const int signo, const char *reason,
+                      va_list ap)
+{
+    va_list ap2;
+    atf_dynstr_t formatted;
+
+    validate_expect(ctx);
+
+    ctx->expect = EXPECT_SIGNAL;
+    va_copy(ap2, ap);
+    check_fatal_error(atf_dynstr_init_ap(&formatted, reason, ap2));
+    va_end(ap2);
+
+    create_resfile(ctx->resfile, "expected_signal", signo, &formatted);
+}
+
+static void
+_atf_tc_expect_death(struct context *ctx, const char *reason, va_list ap)
+{
+    va_list ap2;
+    atf_dynstr_t formatted;
+
+    validate_expect(ctx);
+
+    ctx->expect = EXPECT_DEATH;
+    va_copy(ap2, ap);
+    check_fatal_error(atf_dynstr_init_ap(&formatted, reason, ap2));
+    va_end(ap2);
+
+    create_resfile(ctx->resfile, "expected_death", -1, &formatted);
+}
+
+static void
+_atf_tc_expect_timeout(struct context *ctx, const char *reason, va_list ap)
+{
+    va_list ap2;
+    atf_dynstr_t formatted;
+
+    validate_expect(ctx);
+
+    ctx->expect = EXPECT_TIMEOUT;
+    va_copy(ap2, ap);
+    check_fatal_error(atf_dynstr_init_ap(&formatted, reason, ap2));
+    va_end(ap2);
+
+    create_resfile(ctx->resfile, "expected_timeout", -1, &formatted);
+}
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+static struct context Current;
+
+atf_error_t
+atf_tc_run(const atf_tc_t *tc, const char *resfile)
+{
+    context_init(&Current, tc, resfile);
+
+    tc->pimpl->m_body(tc);
+
+    validate_expect(&Current);
+
+    if (Current.fail_count > 0) {
+        atf_dynstr_t reason;
+
+        format_reason_fmt(&reason, NULL, 0, "%d checks failed; see output for "
+            "more details", Current.fail_count);
+        fail_requirement(&Current, &reason);
+    } else if (Current.expect_fail_count > 0) {
+        atf_dynstr_t reason;
+
+        format_reason_fmt(&reason, NULL, 0, "%d checks failed as expected; "
+            "see output for more details", Current.expect_fail_count);
+        expected_failure(&Current, &reason);
+    } else {
+        pass(&Current);
+    }
+    UNREACHABLE;
+    return atf_no_error();
+}
+
+atf_error_t
+atf_tc_cleanup(const atf_tc_t *tc)
+{
+    if (tc->pimpl->m_cleanup != NULL)
+        tc->pimpl->m_cleanup(tc);
+    return atf_no_error(); /* XXX */
+}
+
+/* ---------------------------------------------------------------------
+ * Free functions that depend on Current.
+ * --------------------------------------------------------------------- */
+
+/*
+ * All the functions below provide delegates to other internal functions
+ * (prefixed by _) that take the current test case as an argument to
+ * prevent them from accessing global state.  This is to keep the side-
+ * effects of the internal functions clearer and easier to understand.
+ *
+ * The public API should never have hid the fact that it needs access to
+ * the current test case (other than maybe in the macros), but changing it
+ * is hard.  TODO: Revisit in the future.
+ */
+
+void
+atf_tc_fail(const char *fmt, ...)
+{
+    va_list ap;
+
+    PRE(Current.tc != NULL);
+
+    va_start(ap, fmt);
+    _atf_tc_fail(&Current, fmt, ap);
+    va_end(ap);
+}
+
+void
+atf_tc_fail_nonfatal(const char *fmt, ...)
+{
+    va_list ap;
+
+    PRE(Current.tc != NULL);
+
+    va_start(ap, fmt);
+    _atf_tc_fail_nonfatal(&Current, fmt, ap);
+    va_end(ap);
+}
+
+void
+atf_tc_fail_check(const char *file, const size_t line, const char *fmt, ...)
+{
+    va_list ap;
+
+    PRE(Current.tc != NULL);
+
+    va_start(ap, fmt);
+    _atf_tc_fail_check(&Current, file, line, fmt, ap);
+    va_end(ap);
+}
+
+void
+atf_tc_fail_requirement(const char *file, const size_t line,
+                        const char *fmt, ...)
+{
+    va_list ap;
+
+    PRE(Current.tc != NULL);
+
+    va_start(ap, fmt);
+    _atf_tc_fail_requirement(&Current, file, line, fmt, ap);
+    va_end(ap);
+}
+
+void
+atf_tc_pass(void)
+{
+    PRE(Current.tc != NULL);
+
+    _atf_tc_pass(&Current);
+}
+
+void
+atf_tc_require_prog(const char *prog)
+{
+    PRE(Current.tc != NULL);
+
+    _atf_tc_require_prog(&Current, prog);
+}
+
+void
+atf_tc_skip(const char *fmt, ...)
+{
+    va_list ap;
+
+    PRE(Current.tc != NULL);
+
+    va_start(ap, fmt);
+    _atf_tc_skip(&Current, fmt, ap);
+    va_end(ap);
+}
+
+void
+atf_tc_check_errno(const char *file, const size_t line, const int exp_errno,
+                   const char *expr_str, const bool expr_result)
+{
+    PRE(Current.tc != NULL);
+
+    _atf_tc_check_errno(&Current, file, line, exp_errno, expr_str,
+                        expr_result);
+}
+
+void
+atf_tc_require_errno(const char *file, const size_t line, const int exp_errno,
+                     const char *expr_str, const bool expr_result)
+{
+    PRE(Current.tc != NULL);
+
+    _atf_tc_require_errno(&Current, file, line, exp_errno, expr_str,
+                          expr_result);
+}
+
+void
+atf_tc_expect_pass(void)
+{
+    PRE(Current.tc != NULL);
+
+    _atf_tc_expect_pass(&Current);
+}
+
+void
+atf_tc_expect_fail(const char *reason, ...)
+{
+    va_list ap;
+
+    PRE(Current.tc != NULL);
+
+    va_start(ap, reason);
+    _atf_tc_expect_fail(&Current, reason, ap);
+    va_end(ap);
+}
+
+void
+atf_tc_expect_exit(const int exitcode, const char *reason, ...)
+{
+    va_list ap;
+
+    PRE(Current.tc != NULL);
+
+    va_start(ap, reason);
+    _atf_tc_expect_exit(&Current, exitcode, reason, ap);
+    va_end(ap);
+}
+
+void
+atf_tc_expect_signal(const int signo, const char *reason, ...)
+{
+    va_list ap;
+
+    PRE(Current.tc != NULL);
+
+    va_start(ap, reason);
+    _atf_tc_expect_signal(&Current, signo, reason, ap);
+    va_end(ap);
+}
+
+void
+atf_tc_expect_death(const char *reason, ...)
+{
+    va_list ap;
+
+    PRE(Current.tc != NULL);
+
+    va_start(ap, reason);
+    _atf_tc_expect_death(&Current, reason, ap);
+    va_end(ap);
+}
+
+void
+atf_tc_expect_timeout(const char *reason, ...)
+{
+    va_list ap;
+
+    PRE(Current.tc != NULL);
+
+    va_start(ap, reason);
+    _atf_tc_expect_timeout(&Current, reason, ap);
+    va_end(ap);
+}

Added: vendor/atf/dist/atf-c/tc.h
===================================================================
--- vendor/atf/dist/atf-c/tc.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/tc.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,136 @@
+/* Copyright (c) 2008 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_C_TC_H)
+#define ATF_C_TC_H
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#include <atf-c/defs.h>
+#include <atf-c/error_fwd.h>
+
+struct atf_tc;
+
+typedef void (*atf_tc_head_t)(struct atf_tc *);
+typedef void (*atf_tc_body_t)(const struct atf_tc *);
+typedef void (*atf_tc_cleanup_t)(const struct atf_tc *);
+
+/* ---------------------------------------------------------------------
+ * The "atf_tc_pack" type.
+ * --------------------------------------------------------------------- */
+
+/* For static initialization only. */
+struct atf_tc_pack {
+    const char *m_ident;
+
+    const char *const *m_config;
+
+    atf_tc_head_t m_head;
+    atf_tc_body_t m_body;
+    atf_tc_cleanup_t m_cleanup;
+};
+typedef const struct atf_tc_pack atf_tc_pack_t;
+
+/* ---------------------------------------------------------------------
+ * The "atf_tc" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_tc_impl;
+struct atf_tc {
+    struct atf_tc_impl *pimpl;
+};
+typedef struct atf_tc atf_tc_t;
+
+/* Constructors/destructors. */
+atf_error_t atf_tc_init(atf_tc_t *, const char *, atf_tc_head_t,
+                        atf_tc_body_t, atf_tc_cleanup_t,
+                        const char *const *);
+atf_error_t atf_tc_init_pack(atf_tc_t *, atf_tc_pack_t *,
+                             const char *const *);
+void atf_tc_fini(atf_tc_t *);
+
+/* Getters. */
+const char *atf_tc_get_ident(const atf_tc_t *);
+const char *atf_tc_get_config_var(const atf_tc_t *, const char *);
+const char *atf_tc_get_config_var_wd(const atf_tc_t *, const char *,
+                                     const char *);
+bool atf_tc_get_config_var_as_bool(const atf_tc_t *, const char *);
+bool atf_tc_get_config_var_as_bool_wd(const atf_tc_t *, const char *,
+                                      const bool);
+long atf_tc_get_config_var_as_long(const atf_tc_t *, const char *);
+long atf_tc_get_config_var_as_long_wd(const atf_tc_t *, const char *,
+                                      const long);
+const char *atf_tc_get_md_var(const atf_tc_t *, const char *);
+char **atf_tc_get_md_vars(const atf_tc_t *);
+bool atf_tc_has_config_var(const atf_tc_t *, const char *);
+bool atf_tc_has_md_var(const atf_tc_t *, const char *);
+
+/* Modifiers. */
+atf_error_t atf_tc_set_md_var(atf_tc_t *, const char *, const char *, ...);
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+atf_error_t atf_tc_run(const atf_tc_t *, const char *);
+atf_error_t atf_tc_cleanup(const atf_tc_t *);
+
+/* To be run from test case bodies only. */
+void atf_tc_fail(const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 2)
+    ATF_DEFS_ATTRIBUTE_NORETURN;
+void atf_tc_fail_nonfatal(const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 2);
+void atf_tc_pass(void)
+    ATF_DEFS_ATTRIBUTE_NORETURN;
+void atf_tc_require_prog(const char *);
+void atf_tc_skip(const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 2)
+    ATF_DEFS_ATTRIBUTE_NORETURN;
+void atf_tc_expect_pass(void);
+void atf_tc_expect_fail(const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 2);
+void atf_tc_expect_exit(const int, const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+void atf_tc_expect_signal(const int, const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+void atf_tc_expect_death(const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 2);
+void atf_tc_expect_timeout(const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 2);
+
+/* To be run from test case bodies only; internal to macros.h. */
+void atf_tc_fail_check(const char *, const size_t, const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(3, 4);
+void atf_tc_fail_requirement(const char *, const size_t, const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(3, 4)
+    ATF_DEFS_ATTRIBUTE_NORETURN;
+void atf_tc_check_errno(const char *, const size_t, const int,
+                        const char *, const bool);
+void atf_tc_require_errno(const char *, const size_t, const int,
+                          const char *, const bool);
+
+#endif /* !defined(ATF_C_TC_H) */

Added: vendor/atf/dist/atf-c/tc_test.c
===================================================================
--- vendor/atf/dist/atf-c/tc_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/tc_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,183 @@
+/* Copyright (c) 2008 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/tc.h"
+
+#include <stdbool.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/test_helpers.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary test cases.
+ * --------------------------------------------------------------------- */
+
+ATF_TC_HEAD(empty, tc)
+{
+    if (tc != NULL) {}
+}
+ATF_TC_BODY(empty, tc)
+{
+}
+
+ATF_TC_HEAD(test_var, tc)
+{
+    atf_tc_set_md_var(tc, "test-var", "Test text");
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the "atf_tc_t" type.
+ * --------------------------------------------------------------------- */
+
+ATF_TC(init);
+ATF_TC_HEAD(init, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_tc_init function");
+}
+ATF_TC_BODY(init, tcin)
+{
+    atf_tc_t tc;
+
+    RE(atf_tc_init(&tc, "test1", ATF_TC_HEAD_NAME(empty),
+                   ATF_TC_BODY_NAME(empty), NULL, NULL));
+    ATF_REQUIRE(strcmp(atf_tc_get_ident(&tc), "test1") == 0);
+    ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var"));
+    atf_tc_fini(&tc);
+
+    RE(atf_tc_init(&tc, "test2", ATF_TC_HEAD_NAME(test_var),
+                   ATF_TC_BODY_NAME(empty), NULL, NULL));
+    ATF_REQUIRE(strcmp(atf_tc_get_ident(&tc), "test2") == 0);
+    ATF_REQUIRE(atf_tc_has_md_var(&tc, "test-var"));
+    atf_tc_fini(&tc);
+}
+
+ATF_TC(init_pack);
+ATF_TC_HEAD(init_pack, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_tc_init_pack function");
+}
+ATF_TC_BODY(init_pack, tcin)
+{
+    atf_tc_t tc;
+    atf_tc_pack_t tcp1 = {
+        .m_ident = "test1",
+        .m_head = ATF_TC_HEAD_NAME(empty),
+        .m_body = ATF_TC_BODY_NAME(empty),
+        .m_cleanup = NULL,
+    };
+    atf_tc_pack_t tcp2 = {
+        .m_ident = "test2",
+        .m_head = ATF_TC_HEAD_NAME(test_var),
+        .m_body = ATF_TC_BODY_NAME(empty),
+        .m_cleanup = NULL,
+    };
+
+    RE(atf_tc_init_pack(&tc, &tcp1, NULL));
+    ATF_REQUIRE(strcmp(atf_tc_get_ident(&tc), "test1") == 0);
+    ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var"));
+    atf_tc_fini(&tc);
+
+    RE(atf_tc_init_pack(&tc, &tcp2, NULL));
+    ATF_REQUIRE(strcmp(atf_tc_get_ident(&tc), "test2") == 0);
+    ATF_REQUIRE(atf_tc_has_md_var(&tc, "test-var"));
+    atf_tc_fini(&tc);
+}
+
+ATF_TC(vars);
+ATF_TC_HEAD(vars, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_tc_get_md_var, "
+                      "atf_tc_has_md_var and atf_tc_set_md_var functions");
+}
+ATF_TC_BODY(vars, tcin)
+{
+    atf_tc_t tc;
+
+    RE(atf_tc_init(&tc, "test1", ATF_TC_HEAD_NAME(empty),
+                   ATF_TC_BODY_NAME(empty), NULL, NULL));
+    ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var"));
+    RE(atf_tc_set_md_var(&tc, "test-var", "Test value"));
+    ATF_REQUIRE(atf_tc_has_md_var(&tc, "test-var"));
+    ATF_REQUIRE(strcmp(atf_tc_get_md_var(&tc, "test-var"), "Test value") == 0);
+    atf_tc_fini(&tc);
+}
+
+ATF_TC(config);
+ATF_TC_HEAD(config, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Tests the atf_tc_get_config_var, "
+                      "atf_tc_get_config_var_wd and atf_tc_has_config_var "
+                      "functions");
+}
+ATF_TC_BODY(config, tcin)
+{
+    atf_tc_t tc;
+    const char *const config[] = { "test-var", "test-value", NULL };
+
+    RE(atf_tc_init(&tc, "test1", ATF_TC_HEAD_NAME(empty),
+                   ATF_TC_BODY_NAME(empty), NULL, NULL));
+    ATF_REQUIRE(!atf_tc_has_config_var(&tc, "test-var"));
+    ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var"));
+    atf_tc_fini(&tc);
+
+    RE(atf_tc_init(&tc, "test1", ATF_TC_HEAD_NAME(empty),
+                   ATF_TC_BODY_NAME(empty), NULL, config));
+    ATF_REQUIRE(atf_tc_has_config_var(&tc, "test-var"));
+    ATF_REQUIRE(strcmp(atf_tc_get_config_var(&tc, "test-var"),
+                     "test-value") == 0);
+    ATF_REQUIRE(!atf_tc_has_md_var(&tc, "test-var"));
+    ATF_REQUIRE(!atf_tc_has_config_var(&tc, "test-var2"));
+    ATF_REQUIRE(strcmp(atf_tc_get_config_var_wd(&tc, "test-var2", "def-value"),
+                     "def-value") == 0);
+    atf_tc_fini(&tc);
+}
+
+/* ---------------------------------------------------------------------
+ * Test cases for the free functions.
+ * --------------------------------------------------------------------- */
+
+/* TODO: Add test cases for atf_tc_run.  This is going to be very tough,
+ * but good tests here could allow us to avoid much of the indirect
+ * testing done later on. */
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    /* Add the test cases for the "atf_tcr_t" type. */
+    ATF_TP_ADD_TC(tp, init);
+    ATF_TP_ADD_TC(tp, init_pack);
+    ATF_TP_ADD_TC(tp, vars);
+    ATF_TP_ADD_TC(tp, config);
+
+    /* Add the test cases for the free functions. */
+    /* TODO */
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/tp.c
===================================================================
--- vendor/atf/dist/atf-c/tp.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/tp.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,213 @@
+/* Copyright (c) 2008 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/tp.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "atf-c/detail/fs.h"
+#include "atf-c/detail/map.h"
+#include "atf-c/detail/sanity.h"
+#include "atf-c/error.h"
+#include "atf-c/tc.h"
+
+struct atf_tp_impl {
+    atf_list_t m_tcs;
+    atf_map_t m_config;
+};
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+const atf_tc_t *
+find_tc(const atf_tp_t *tp, const char *ident)
+{
+    const atf_tc_t *tc;
+    atf_list_citer_t iter;
+
+    tc = NULL;
+    atf_list_for_each_c(iter, &tp->pimpl->m_tcs) {
+        const atf_tc_t *tc2;
+        tc2 = atf_list_citer_data(iter);
+        if (strcmp(atf_tc_get_ident(tc2), ident) == 0) {
+            tc = tc2;
+            break;
+        }
+    }
+    return tc;
+}
+
+/* ---------------------------------------------------------------------
+ * The "atf_tp" type.
+ * --------------------------------------------------------------------- */
+
+/*
+ * Constructors/destructors.
+ */
+
+atf_error_t
+atf_tp_init(atf_tp_t *tp, const char *const *config)
+{
+    atf_error_t err;
+
+    PRE(config != NULL);
+
+    tp->pimpl = malloc(sizeof(struct atf_tp_impl));
+    if (tp->pimpl == NULL)
+        return atf_no_memory_error();
+
+    err = atf_list_init(&tp->pimpl->m_tcs);
+    if (atf_is_error(err))
+        goto out;
+
+    err = atf_map_init_charpp(&tp->pimpl->m_config, config);
+    if (atf_is_error(err)) {
+        atf_list_fini(&tp->pimpl->m_tcs);
+        goto out;
+    }
+
+    INV(!atf_is_error(err));
+out:
+    return err;
+}
+
+void
+atf_tp_fini(atf_tp_t *tp)
+{
+    atf_list_iter_t iter;
+
+    atf_map_fini(&tp->pimpl->m_config);
+
+    atf_list_for_each(iter, &tp->pimpl->m_tcs) {
+        atf_tc_t *tc = atf_list_iter_data(iter);
+        atf_tc_fini(tc);
+    }
+    atf_list_fini(&tp->pimpl->m_tcs);
+
+    free(tp->pimpl);
+}
+
+/*
+ * Getters.
+ */
+
+char **
+atf_tp_get_config(const atf_tp_t *tp)
+{
+    return atf_map_to_charpp(&tp->pimpl->m_config);
+}
+
+bool
+atf_tp_has_tc(const atf_tp_t *tp, const char *id)
+{
+    const atf_tc_t *tc = find_tc(tp, id);
+    return tc != NULL;
+}
+
+const atf_tc_t *
+atf_tp_get_tc(const atf_tp_t *tp, const char *id)
+{
+    const atf_tc_t *tc = find_tc(tp, id);
+    PRE(tc != NULL);
+    return tc;
+}
+
+const atf_tc_t *const *
+atf_tp_get_tcs(const atf_tp_t *tp)
+{
+    const atf_tc_t **array;
+    atf_list_citer_t iter;
+    size_t i;
+
+    array = malloc(sizeof(atf_tc_t *) *
+                   (atf_list_size(&tp->pimpl->m_tcs) + 1));
+    if (array == NULL)
+        goto out;
+
+    i = 0;
+    atf_list_for_each_c(iter, &tp->pimpl->m_tcs) {
+        array[i] = atf_list_citer_data(iter);
+        if (array[i] == NULL) {
+            free(array);
+            array = NULL;
+            goto out;
+        }
+
+        i++;
+    }
+    array[i] = NULL;
+
+out:
+    return array;
+}
+
+/*
+ * Modifiers.
+ */
+
+atf_error_t
+atf_tp_add_tc(atf_tp_t *tp, atf_tc_t *tc)
+{
+    atf_error_t err;
+
+    PRE(find_tc(tp, atf_tc_get_ident(tc)) == NULL);
+
+    err = atf_list_append(&tp->pimpl->m_tcs, tc, false);
+
+    POST(find_tc(tp, atf_tc_get_ident(tc)) != NULL);
+
+    return err;
+}
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+atf_error_t
+atf_tp_run(const atf_tp_t *tp, const char *tcname, const char *resfile)
+{
+    const atf_tc_t *tc;
+
+    tc = find_tc(tp, tcname);
+    PRE(tc != NULL);
+
+    return atf_tc_run(tc, resfile);
+}
+
+atf_error_t
+atf_tp_cleanup(const atf_tp_t *tp, const char *tcname)
+{
+    const atf_tc_t *tc;
+
+    tc = find_tc(tp, tcname);
+    PRE(tc != NULL);
+
+    return atf_tc_cleanup(tc);
+}

Added: vendor/atf/dist/atf-c/tp.h
===================================================================
--- vendor/atf/dist/atf-c/tp.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/tp.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,65 @@
+/* Copyright (c) 2008 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_C_TP_H)
+#define ATF_C_TP_H
+
+#include <stdbool.h>
+
+#include <atf-c/error_fwd.h>
+
+struct atf_tc;
+
+/* ---------------------------------------------------------------------
+ * The "atf_tp" type.
+ * --------------------------------------------------------------------- */
+
+struct atf_tp_impl;
+struct atf_tp {
+    struct atf_tp_impl *pimpl;
+};
+typedef struct atf_tp atf_tp_t;
+
+/* Constructors/destructors. */
+atf_error_t atf_tp_init(atf_tp_t *, const char *const *);
+void atf_tp_fini(atf_tp_t *);
+
+/* Getters. */
+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 *);
+
+/* Modifiers. */
+atf_error_t atf_tp_add_tc(atf_tp_t *, struct atf_tc *);
+
+/* ---------------------------------------------------------------------
+ * Free functions.
+ * --------------------------------------------------------------------- */
+
+atf_error_t atf_tp_run(const atf_tp_t *, const char *, const char *);
+atf_error_t atf_tp_cleanup(const atf_tp_t *, const char *);
+
+#endif /* !defined(ATF_C_TP_H) */

Added: vendor/atf/dist/atf-c/tp_test.c
===================================================================
--- vendor/atf/dist/atf-c/tp_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/tp_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,88 @@
+/* Copyright (c) 2010 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/tp.h"
+
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+ATF_TC(getopt);
+ATF_TC_HEAD(getopt, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Checks if getopt(3) global state is "
+        "reset by the test program driver so that test cases can use "
+        "getopt(3) again");
+}
+ATF_TC_BODY(getopt, tc)
+{
+    /* Provide an option that is unknown to the test program driver and
+     * one that is, together with an argument that would be swallowed by
+     * the test program option if it were recognized. */
+    int argc = 4;
+    char arg1[] = "progname";
+    char arg2[] = "-Z";
+    char arg3[] = "-s";
+    char arg4[] = "foo";
+    char *const argv[] = { arg1, arg2, arg3, arg4, NULL };
+
+    int ch;
+    bool zflag;
+
+    /* Given that this obviously is a test program, and that we used the
+     * same driver to start, we can test getopt(3) right here without doing
+     * any fancy stuff. */
+    zflag = false;
+    while ((ch = getopt(argc, argv, ":Z")) != -1) {
+        switch (ch) {
+        case 'Z':
+            zflag = true;
+            break;
+
+        case '?':
+        default:
+            if (optopt != 's')
+                atf_tc_fail("Unexpected unknown option -%c found", optopt);
+        }
+    }
+
+    ATF_REQUIRE(zflag);
+    ATF_REQUIRE_EQ_MSG(1, argc - optind, "Invalid number of arguments left "
+        "after the call to getopt(3)");
+    ATF_CHECK_STREQ_MSG("foo", argv[optind], "The non-option argument is "
+        "invalid");
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    ATF_TP_ADD_TC(tp, getopt);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/unused_test.c
===================================================================
--- vendor/atf/dist/atf-c/unused_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/unused_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,52 @@
+/* Copyright (c) 2012 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.h>
+
+ATF_TC(this_is_used);
+ATF_TC_HEAD(this_is_used, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "A test case that is not referenced");
+}
+ATF_TC_BODY(this_is_used, tc)
+{
+}
+
+ATF_TC(this_is_unused);
+ATF_TC_HEAD(this_is_unused, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "A test case that is referenced");
+}
+ATF_TC_BODY(this_is_unused, tc)
+{
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+    ATF_TP_ADD_TC(tp, this_is_used);
+    /* ATF_TP_ADD_TC(tp, this_is_unused); */
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c/utils.c
===================================================================
--- vendor/atf/dist/atf-c/utils.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/utils.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,456 @@
+/* Copyright (c) 2010 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/utils.h"
+
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/dynstr.h"
+
+/** Allocate a filename to be used by atf_utils_{fork,wait}.
+ *
+ * In case of a failure, marks the calling test as failed when in_parent is
+ * true, else terminates execution.
+ *
+ * \param [out] name String to contain the generated file.
+ * \param pid PID of the process that will write to the file.
+ * \param suffix Either "out" or "err".
+ * \param in_parent If true, fail with atf_tc_fail; else use err(3). */
+static void
+init_out_filename(atf_dynstr_t *name, const pid_t pid, const char *suffix,
+                  const bool in_parent)
+{
+    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);
+        }
+    }
+}
+
+/** Searches for a regexp in a string.
+ *
+ * \param regex The regexp to look for.
+ * \param str The string in which to look for the expression.
+ *
+ * \return True if there is a match; false otherwise. */
+static
+bool
+grep_string(const char *regex, const char *str)
+{
+    int res;
+    regex_t preg;
+
+    printf("Looking for '%s' in '%s'\n", regex, str);
+    ATF_REQUIRE(regcomp(&preg, regex, REG_EXTENDED) == 0);
+
+    res = regexec(&preg, str, 0, NULL, 0);
+    ATF_REQUIRE(res == 0 || res == REG_NOMATCH);
+
+    regfree(&preg);
+
+    return res == 0;
+}
+
+/** Prints the contents of a file to stdout.
+ *
+ * \param name The name of the file to be printed.
+ * \param prefix An string to be prepended to every line of the printed
+ *     file. */
+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);
+
+    char buffer[1024];
+    ssize_t count;
+    bool continued = false;
+    while ((count = read(fd, buffer, sizeof(buffer) - 1)) > 0) {
+        buffer[count] = '\0';
+
+        if (!continued)
+            printf("%s", prefix);
+
+        char *iter = buffer;
+        char *end;
+        while ((end = strchr(iter, '\n')) != NULL) {
+            *end = '\0';
+            printf("%s\n", iter);
+
+            iter = end + 1;
+            if (iter != buffer + count)
+                printf("%s", prefix);
+            else
+                continued = false;
+        }
+        if (iter < buffer + count) {
+            printf("%s", iter);
+            continued = true;
+        }
+    }
+    ATF_REQUIRE(count == 0);
+}
+
+/** Compares a file against the given golden contents.
+ *
+ * \param name Name of the file to be compared.
+ * \param contents Expected contents of the file.
+ *
+ * \return True if the file matches the contents; false otherwise. */
+bool
+atf_utils_compare_file(const char *name, const char *contents)
+{
+    const int fd = open(name, O_RDONLY);
+    ATF_REQUIRE_MSG(fd != -1, "Cannot open %s", name);
+
+    const char *pos = contents;
+    ssize_t remaining = strlen(contents);
+
+    char buffer[1024];
+    ssize_t count;
+    while ((count = read(fd, buffer, sizeof(buffer))) > 0 &&
+           count <= remaining) {
+        if (memcmp(pos, buffer, count) != 0) {
+            close(fd);
+            return false;
+        }
+        remaining -= count;
+        pos += count;
+    }
+    close(fd);
+    return count == 0 && remaining == 0;
+}
+
+/** Copies a file.
+ *
+ * \param source Path to the source file.
+ * \param destination Path to the destination file. */
+void
+atf_utils_copy_file(const char *source, const char *destination)
+{
+    const int input = open(source, O_RDONLY);
+    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);
+    ATF_REQUIRE_MSG(output != -1, "Failed to open destination file during "
+                    "copy (%s)", destination);
+
+    char buffer[1024];
+    ssize_t length;
+    while ((length = read(input, buffer, sizeof(buffer))) > 0)
+        ATF_REQUIRE_MSG(write(output, buffer, length) == length,
+                        "Failed to write to %s during copy", destination);
+    ATF_REQUIRE_MSG(length != -1, "Failed to read from %s during copy", source);
+
+    struct stat sb;
+    ATF_REQUIRE_MSG(fstat(input, &sb) != -1,
+                    "Failed to stat source file %s during copy", source);
+    ATF_REQUIRE_MSG(fchmod(output, sb.st_mode) != -1,
+                    "Failed to chmod destination file %s during copy",
+                    destination);
+
+    close(output);
+    close(input);
+}
+
+/** Creates a file.
+ *
+ * \param name Name of the file to create.
+ * \param contents Text to write into the created file.
+ * \param ... Positional parameters to the contents. */
+void
+atf_utils_create_file(const char *name, const char *contents, ...)
+{
+    va_list ap;
+    atf_dynstr_t formatted;
+    atf_error_t error;
+
+    va_start(ap, contents);
+    error = atf_dynstr_init_ap(&formatted, contents, ap);
+    va_end(ap);
+    ATF_REQUIRE(!atf_is_error(error));
+
+    const int fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+    ATF_REQUIRE_MSG(fd != -1, "Cannot create file %s", name);
+    ATF_REQUIRE(write(fd, atf_dynstr_cstring(&formatted),
+                      atf_dynstr_length(&formatted)) != -1);
+    close(fd);
+
+    atf_dynstr_fini(&formatted);
+}
+
+/** Checks if a file exists.
+ *
+ * \param path Location of the file to check for.
+ *
+ * \return True if the file exists, false otherwise. */
+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
+        return true;
+}
+
+/** Spawns a subprocess and redirects its output to files.
+ *
+ * Use the atf_utils_wait() function to wait for the completion of the spawned
+ * subprocess and validate its exit conditions.
+ *
+ * \return 0 in the new child; the PID of the new child in the parent.  Does
+ * not return in error conditions. */
+pid_t
+atf_utils_fork(void)
+{
+    const pid_t pid = fork();
+    if (pid == -1)
+        atf_tc_fail("fork failed");
+
+    if (pid == 0) {
+        atf_dynstr_t out_name;
+        init_out_filename(&out_name, getpid(), "out", false);
+
+        atf_dynstr_t err_name;
+        init_out_filename(&err_name, getpid(), "err", false);
+
+        atf_utils_redirect(STDOUT_FILENO, atf_dynstr_cstring(&out_name));
+        atf_utils_redirect(STDERR_FILENO, atf_dynstr_cstring(&err_name));
+
+        atf_dynstr_fini(&err_name);
+        atf_dynstr_fini(&out_name);
+    }
+    return pid;
+}
+
+/** Frees an dynamically-allocated "argv" array.
+ *
+ * \param argv A dynamically-allocated array of dynamically-allocated
+ *     strings. */
+void
+atf_utils_free_charpp(char **argv)
+{
+    char **ptr;
+
+    for (ptr = argv; *ptr != NULL; ptr++)
+        free(*ptr);
+
+    free(argv);
+}
+
+/** Searches for a regexp in a file.
+ *
+ * \param regex The regexp to look for.
+ * \param file The file in which to look for the expression.
+ * \param ... Positional parameters to the regex.
+ *
+ * \return True if there is a match; false otherwise. */
+bool
+atf_utils_grep_file(const char *regex, const char *file, ...)
+{
+    int fd;
+    va_list ap;
+    atf_dynstr_t formatted;
+    atf_error_t error;
+
+    va_start(ap, file);
+    error = atf_dynstr_init_ap(&formatted, regex, ap);
+    va_end(ap);
+    ATF_REQUIRE(!atf_is_error(error));
+
+    ATF_REQUIRE((fd = open(file, O_RDONLY)) != -1);
+    bool found = false;
+    char *line = NULL;
+    while (!found && (line = atf_utils_readline(fd)) != NULL) {
+        found = grep_string(atf_dynstr_cstring(&formatted), line);
+        free(line);
+    }
+    close(fd);
+
+    atf_dynstr_fini(&formatted);
+
+    return found;
+}
+
+/** Searches for a regexp in a string.
+ *
+ * \param regex The regexp to look for.
+ * \param str The string in which to look for the expression.
+ * \param ... Positional parameters to the regex.
+ *
+ * \return True if there is a match; false otherwise. */
+bool
+atf_utils_grep_string(const char *regex, const char *str, ...)
+{
+    bool res;
+    va_list ap;
+    atf_dynstr_t formatted;
+    atf_error_t error;
+
+    va_start(ap, str);
+    error = atf_dynstr_init_ap(&formatted, regex, ap);
+    va_end(ap);
+    ATF_REQUIRE(!atf_is_error(error));
+
+    res = grep_string(atf_dynstr_cstring(&formatted), str);
+
+    atf_dynstr_fini(&formatted);
+
+    return res;
+}
+
+/** Reads a line of arbitrary length.
+ *
+ * \param fd The descriptor from which to read the line.
+ *
+ * \return A pointer to the read line, which must be released with free(), or
+ * NULL if there was nothing to read from the file. */
+char *
+atf_utils_readline(const int fd)
+{
+    char ch;
+    ssize_t cnt;
+    atf_dynstr_t temp;
+    atf_error_t error;
+
+    error = atf_dynstr_init(&temp);
+    ATF_REQUIRE(!atf_is_error(error));
+
+    while ((cnt = read(fd, &ch, sizeof(ch))) == sizeof(ch) &&
+           ch != '\n') {
+        error = atf_dynstr_append_fmt(&temp, "%c", ch);
+        ATF_REQUIRE(!atf_is_error(error));
+    }
+    ATF_REQUIRE(cnt != -1);
+
+    if (cnt == 0 && atf_dynstr_length(&temp) == 0) {
+        atf_dynstr_fini(&temp);
+        return NULL;
+    } else
+        return atf_dynstr_fini_disown(&temp);
+}
+
+/** Redirects a file descriptor to a file.
+ *
+ * \param target_fd The file descriptor to be replaced.
+ * \param name The name of the file to direct the descriptor to.
+ *
+ * \pre Should only be called from the process spawned by fork_for_testing
+ * because this exits uncontrolledly.
+ * \post Terminates execution if the redirection fails. */
+void
+atf_utils_redirect(const int target_fd, const char *name)
+{
+    if (target_fd == STDOUT_FILENO)
+        fflush(stdout);
+    else if (target_fd == STDERR_FILENO)
+        fflush(stderr);
+
+    const int new_fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+    if (new_fd == -1)
+        err(EXIT_FAILURE, "Cannot create %s", name);
+    if (new_fd != target_fd) {
+        if (dup2(new_fd, target_fd) == -1)
+            err(EXIT_FAILURE, "Cannot redirect to fd %d", target_fd);
+    }
+    close(new_fd);
+}
+
+/** Waits for a subprocess and validates its exit condition.
+ *
+ * \param pid The process to be waited for.  Must have been started by
+ *     testutils_fork().
+ * \param exitstatus Expected exit status.
+ * \param expout Expected contents of stdout.
+ * \param experr Expected contents of stderr. */
+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);
+
+    atf_dynstr_t out_name;
+    init_out_filename(&out_name, pid, "out", true);
+
+    atf_dynstr_t err_name;
+    init_out_filename(&err_name, pid, "err", true);
+
+    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));
+
+    const char *save_prefix = "save:";
+    const size_t save_prefix_length = strlen(save_prefix);
+
+    if (strlen(expout) > save_prefix_length &&
+        strncmp(expout, save_prefix, save_prefix_length) == 0) {
+        atf_utils_copy_file(atf_dynstr_cstring(&out_name),
+                            expout + save_prefix_length);
+    } else {
+        ATF_REQUIRE(atf_utils_compare_file(atf_dynstr_cstring(&out_name),
+                                           expout));
+    }
+
+    if (strlen(experr) > save_prefix_length &&
+        strncmp(experr, save_prefix, save_prefix_length) == 0) {
+        atf_utils_copy_file(atf_dynstr_cstring(&err_name),
+                            experr + save_prefix_length);
+    } else {
+        ATF_REQUIRE(atf_utils_compare_file(atf_dynstr_cstring(&err_name),
+                                           experr));
+    }
+
+    ATF_REQUIRE(unlink(atf_dynstr_cstring(&out_name)) != -1);
+    ATF_REQUIRE(unlink(atf_dynstr_cstring(&err_name)) != -1);
+}

Added: vendor/atf/dist/atf-c/utils.h
===================================================================
--- vendor/atf/dist/atf-c/utils.h	                        (rev 0)
+++ vendor/atf/dist/atf-c/utils.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,50 @@
+/* Copyright (c) 2010 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_C_UTILS_H)
+#define ATF_C_UTILS_H
+
+#include <stdbool.h>
+#include <unistd.h>
+
+#include <atf-c/defs.h>
+
+void atf_utils_cat_file(const char *, const char *);
+bool atf_utils_compare_file(const char *, const char *);
+void atf_utils_copy_file(const char *, const char *);
+void atf_utils_create_file(const char *, const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+bool atf_utils_file_exists(const char *);
+pid_t atf_utils_fork(void);
+void atf_utils_free_charpp(char **);
+bool atf_utils_grep_file(const char *, const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 3);
+bool atf_utils_grep_string(const char *, const char *, ...)
+    ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(1, 3);
+char *atf_utils_readline(int);
+void atf_utils_redirect(const int, const char *);
+void atf_utils_wait(const pid_t, const int, const char *, const char *);
+
+#endif /* !defined(ATF_C_UTILS_H) */

Added: vendor/atf/dist/atf-c/utils_test.c
===================================================================
--- vendor/atf/dist/atf-c/utils_test.c	                        (rev 0)
+++ vendor/atf/dist/atf-c/utils_test.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,570 @@
+/* Copyright (c) 2010 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/utils.h"
+
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/dynstr.h"
+#include "atf-c/detail/test_helpers.h"
+
+/** Reads the contents of a file into a buffer.
+ *
+ * Up to buflen-1 characters are read into buffer.  If this function returns,
+ * the contents read into the buffer are guaranteed to be nul-terminated.
+ * Note, however, that if the file contains any nul characters itself,
+ * comparing it "as a string" will not work.
+ *
+ * \param path The file to be read, which must exist.
+ * \param buffer Buffer into which to store the file contents.
+ * \param buflen Size of the target buffer.
+ *
+ * \return The count of bytes read. */
+static ssize_t
+read_file(const char *path, void *const buffer, const size_t buflen)
+{
+    const int fd = open(path, O_RDONLY);
+    ATF_REQUIRE_MSG(fd != -1, "Cannot open %s", path);
+    const ssize_t length = read(fd, buffer, buflen - 1);
+    close(fd);
+    ATF_REQUIRE(length != -1);
+    ((char *)buffer)[length] = '\0';
+    return length;
+}
+
+ATF_TC_WITHOUT_HEAD(cat_file__empty);
+ATF_TC_BODY(cat_file__empty, tc)
+{
+    atf_utils_create_file("file.txt", "%s", "");
+    atf_utils_redirect(STDOUT_FILENO, "captured.txt");
+    atf_utils_cat_file("file.txt", "PREFIX");
+    fflush(stdout);
+    close(STDOUT_FILENO);
+
+    char buffer[1024];
+    read_file("captured.txt", buffer, sizeof(buffer));
+    ATF_REQUIRE_STREQ("", buffer);
+}
+
+ATF_TC_WITHOUT_HEAD(cat_file__one_line);
+ATF_TC_BODY(cat_file__one_line, tc)
+{
+    atf_utils_create_file("file.txt", "This is a single line\n");
+    atf_utils_redirect(STDOUT_FILENO, "captured.txt");
+    atf_utils_cat_file("file.txt", "PREFIX");
+    fflush(stdout);
+    close(STDOUT_FILENO);
+
+    char buffer[1024];
+    read_file("captured.txt", buffer, sizeof(buffer));
+    ATF_REQUIRE_STREQ("PREFIXThis is a single line\n", buffer);
+}
+
+ATF_TC_WITHOUT_HEAD(cat_file__several_lines);
+ATF_TC_BODY(cat_file__several_lines, tc)
+{
+    atf_utils_create_file("file.txt", "First\nSecond line\nAnd third\n");
+    atf_utils_redirect(STDOUT_FILENO, "captured.txt");
+    atf_utils_cat_file("file.txt", ">");
+    fflush(stdout);
+    close(STDOUT_FILENO);
+
+    char buffer[1024];
+    read_file("captured.txt", buffer, sizeof(buffer));
+    ATF_REQUIRE_STREQ(">First\n>Second line\n>And third\n", buffer);
+}
+
+ATF_TC_WITHOUT_HEAD(cat_file__no_newline_eof);
+ATF_TC_BODY(cat_file__no_newline_eof, tc)
+{
+    atf_utils_create_file("file.txt", "Foo\n bar baz");
+    atf_utils_redirect(STDOUT_FILENO, "captured.txt");
+    atf_utils_cat_file("file.txt", "PREFIX");
+    fflush(stdout);
+    close(STDOUT_FILENO);
+
+    char buffer[1024];
+    read_file("captured.txt", buffer, sizeof(buffer));
+    ATF_REQUIRE_STREQ("PREFIXFoo\nPREFIX bar baz", buffer);
+}
+
+ATF_TC_WITHOUT_HEAD(compare_file__empty__match);
+ATF_TC_BODY(compare_file__empty__match, tc)
+{
+    atf_utils_create_file("test.txt", "%s", "");
+    ATF_REQUIRE(atf_utils_compare_file("test.txt", ""));
+}
+
+ATF_TC_WITHOUT_HEAD(compare_file__empty__not_match);
+ATF_TC_BODY(compare_file__empty__not_match, tc)
+{
+    atf_utils_create_file("test.txt", "%s", "");
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n"));
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", "foo"));
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", " "));
+}
+
+ATF_TC_WITHOUT_HEAD(compare_file__short__match);
+ATF_TC_BODY(compare_file__short__match, tc)
+{
+    atf_utils_create_file("test.txt", "this is a short file");
+    ATF_REQUIRE(atf_utils_compare_file("test.txt", "this is a short file"));
+}
+
+ATF_TC_WITHOUT_HEAD(compare_file__short__not_match);
+ATF_TC_BODY(compare_file__short__not_match, tc)
+{
+    atf_utils_create_file("test.txt", "this is a short file");
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", ""));
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n"));
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a Short file"));
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a short fil"));
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", "this is a short file "));
+}
+
+ATF_TC_WITHOUT_HEAD(compare_file__long__match);
+ATF_TC_BODY(compare_file__long__match, tc)
+{
+    char long_contents[3456];
+    size_t i = 0;
+    for (; i < sizeof(long_contents) - 1; i++)
+        long_contents[i] = '0' + (i % 10);
+    long_contents[i] = '\0';
+    atf_utils_create_file("test.txt", "%s", long_contents);
+
+    ATF_REQUIRE(atf_utils_compare_file("test.txt", long_contents));
+}
+
+ATF_TC_WITHOUT_HEAD(compare_file__long__not_match);
+ATF_TC_BODY(compare_file__long__not_match, tc)
+{
+    char long_contents[3456];
+    size_t i = 0;
+    for (; i < sizeof(long_contents) - 1; i++)
+        long_contents[i] = '0' + (i % 10);
+    long_contents[i] = '\0';
+    atf_utils_create_file("test.txt", "%s", long_contents);
+
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", ""));
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", "\n"));
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", "0123456789"));
+    long_contents[i - 1] = 'Z';
+    ATF_REQUIRE(!atf_utils_compare_file("test.txt", long_contents));
+}
+
+ATF_TC_WITHOUT_HEAD(copy_file__empty);
+ATF_TC_BODY(copy_file__empty, tc)
+{
+    atf_utils_create_file("src.txt", "%s", "");
+    ATF_REQUIRE(chmod("src.txt", 0520) != -1);
+
+    atf_utils_copy_file("src.txt", "dest.txt");
+    ATF_REQUIRE(atf_utils_compare_file("dest.txt", ""));
+    struct stat sb;
+    ATF_REQUIRE(stat("dest.txt", &sb) != -1);
+    ATF_REQUIRE_EQ(0520, sb.st_mode & 0xfff);
+}
+
+ATF_TC_WITHOUT_HEAD(copy_file__some_contents);
+ATF_TC_BODY(copy_file__some_contents, tc)
+{
+    atf_utils_create_file("src.txt", "This is a\ntest file\n");
+    atf_utils_copy_file("src.txt", "dest.txt");
+    ATF_REQUIRE(atf_utils_compare_file("dest.txt", "This is a\ntest file\n"));
+}
+
+ATF_TC_WITHOUT_HEAD(create_file);
+ATF_TC_BODY(create_file, tc)
+{
+    atf_utils_create_file("test.txt", "This is a test with %d", 12345);
+
+    char buffer[128];
+    read_file("test.txt", buffer, sizeof(buffer));
+    ATF_REQUIRE_STREQ("This is a test with 12345", buffer);
+}
+
+ATF_TC_WITHOUT_HEAD(file_exists);
+ATF_TC_BODY(file_exists, tc)
+{
+    atf_utils_create_file("test.txt", "foo");
+
+    ATF_REQUIRE( atf_utils_file_exists("test.txt"));
+    ATF_REQUIRE( atf_utils_file_exists("./test.txt"));
+    ATF_REQUIRE(!atf_utils_file_exists("./test.tx"));
+    ATF_REQUIRE(!atf_utils_file_exists("test.txt2"));
+}
+
+ATF_TC_WITHOUT_HEAD(fork);
+ATF_TC_BODY(fork, tc)
+{
+    fprintf(stdout, "Should not get into child\n");
+    fprintf(stderr, "Should not get into child\n");
+    pid_t pid = atf_utils_fork();
+    if (pid == 0) {
+        fprintf(stdout, "Child stdout\n");
+        fprintf(stderr, "Child stderr\n");
+        exit(EXIT_SUCCESS);
+    }
+
+    int status;
+    ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
+    ATF_REQUIRE(WIFEXITED(status));
+    ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+    atf_dynstr_t out_name;
+    RE(atf_dynstr_init_fmt(&out_name, "atf_utils_fork_%d_out.txt", (int)pid));
+    atf_dynstr_t err_name;
+    RE(atf_dynstr_init_fmt(&err_name, "atf_utils_fork_%d_err.txt", (int)pid));
+
+    char buffer[1024];
+    read_file(atf_dynstr_cstring(&out_name), buffer, sizeof(buffer));
+    ATF_REQUIRE_STREQ("Child stdout\n", buffer);
+    read_file(atf_dynstr_cstring(&err_name), buffer, sizeof(buffer));
+    ATF_REQUIRE_STREQ("Child stderr\n", buffer);
+
+    atf_dynstr_fini(&err_name);
+    atf_dynstr_fini(&out_name);
+}
+
+ATF_TC_WITHOUT_HEAD(free_charpp__empty);
+ATF_TC_BODY(free_charpp__empty, tc)
+{
+    char **array = malloc(sizeof(char *) * 1);
+    array[0] = NULL;
+
+    atf_utils_free_charpp(array);
+}
+
+ATF_TC_WITHOUT_HEAD(free_charpp__some);
+ATF_TC_BODY(free_charpp__some, tc)
+{
+    char **array = malloc(sizeof(char *) * 4);
+    array[0] = strdup("first");
+    array[1] = strdup("second");
+    array[2] = strdup("third");
+    array[3] = NULL;
+
+    atf_utils_free_charpp(array);
+}
+
+ATF_TC_WITHOUT_HEAD(grep_file);
+ATF_TC_BODY(grep_file, tc)
+{
+    atf_utils_create_file("test.txt", "line1\nthe second line\naaaabbbb\n");
+
+    ATF_CHECK(atf_utils_grep_file("line1", "test.txt"));
+    ATF_CHECK(atf_utils_grep_file("line%d", "test.txt", 1));
+    ATF_CHECK(atf_utils_grep_file("second line", "test.txt"));
+    ATF_CHECK(atf_utils_grep_file("aa.*bb", "test.txt"));
+    ATF_CHECK(!atf_utils_grep_file("foo", "test.txt"));
+    ATF_CHECK(!atf_utils_grep_file("bar", "test.txt"));
+    ATF_CHECK(!atf_utils_grep_file("aaaaa", "test.txt"));
+}
+
+ATF_TC_WITHOUT_HEAD(grep_string);
+ATF_TC_BODY(grep_string, tc)
+{
+    const char *str = "a string - aaaabbbb";
+    ATF_CHECK(atf_utils_grep_string("a string", str));
+    ATF_CHECK(atf_utils_grep_string("^a string", str));
+    ATF_CHECK(atf_utils_grep_string("aaaabbbb$", str));
+    ATF_CHECK(atf_utils_grep_string("a%s*bb", str, "a."));
+    ATF_CHECK(!atf_utils_grep_string("foo", str));
+    ATF_CHECK(!atf_utils_grep_string("bar", str));
+    ATF_CHECK(!atf_utils_grep_string("aaaaa", str));
+}
+
+ATF_TC_WITHOUT_HEAD(readline__none);
+ATF_TC_BODY(readline__none, tc)
+{
+    atf_utils_create_file("empty.txt", "%s", "");
+
+    const int fd = open("empty.txt", O_RDONLY);
+    ATF_REQUIRE(fd != -1);
+    ATF_REQUIRE(atf_utils_readline(fd) == NULL);
+    close(fd);
+}
+
+ATF_TC_WITHOUT_HEAD(readline__some);
+ATF_TC_BODY(readline__some, tc)
+{
+    const char *l1 = "First line with % formatting % characters %";
+    const char *l2 = "Second line; much longer than the first one";
+    const char *l3 = "Last line, without terminator";
+
+    atf_utils_create_file("test.txt", "%s\n%s\n%s", l1, l2, l3);
+
+    const int fd = open("test.txt", O_RDONLY);
+    ATF_REQUIRE(fd != -1);
+
+    char *line;
+
+    line = atf_utils_readline(fd);
+    ATF_REQUIRE_STREQ(l1, line);
+    free(line);
+
+    line = atf_utils_readline(fd);
+    ATF_REQUIRE_STREQ(l2, line);
+    free(line);
+
+    line = atf_utils_readline(fd);
+    ATF_REQUIRE_STREQ(l3, line);
+    free(line);
+
+    close(fd);
+}
+
+ATF_TC_WITHOUT_HEAD(redirect__stdout);
+ATF_TC_BODY(redirect__stdout, tc)
+{
+    printf("Buffer this");
+    atf_utils_redirect(STDOUT_FILENO, "captured.txt");
+    printf("The printed message");
+    fflush(stdout);
+
+    char buffer[1024];
+    read_file("captured.txt", buffer, sizeof(buffer));
+    ATF_REQUIRE_STREQ("The printed message", buffer);
+}
+
+ATF_TC_WITHOUT_HEAD(redirect__stderr);
+ATF_TC_BODY(redirect__stderr, tc)
+{
+    fprintf(stderr, "Buffer this");
+    atf_utils_redirect(STDERR_FILENO, "captured.txt");
+    fprintf(stderr, "The printed message");
+    fflush(stderr);
+
+    char buffer[1024];
+    read_file("captured.txt", buffer, sizeof(buffer));
+    ATF_REQUIRE_STREQ("The printed message", buffer);
+}
+
+ATF_TC_WITHOUT_HEAD(redirect__other);
+ATF_TC_BODY(redirect__other, tc)
+{
+    const char *message = "Foo bar\nbaz\n";
+    atf_utils_redirect(15, "captured.txt");
+    ATF_REQUIRE(write(15, message, strlen(message)) != -1);
+    close(15);
+
+    char buffer[1024];
+    read_file("captured.txt", buffer, sizeof(buffer));
+    ATF_REQUIRE_STREQ(message, buffer);
+}
+
+static void
+fork_and_wait(const int exitstatus, const char* expout, const char* experr)
+{
+    const pid_t pid = atf_utils_fork();
+    ATF_REQUIRE(pid != -1);
+    if (pid == 0) {
+        fprintf(stdout, "Some output\n");
+        fprintf(stderr, "Some error\n");
+        exit(123);
+    }
+    atf_utils_wait(pid, exitstatus, expout, experr);
+    exit(EXIT_SUCCESS);
+}
+
+ATF_TC_WITHOUT_HEAD(wait__ok);
+ATF_TC_BODY(wait__ok, tc)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(123, "Some output\n", "Some error\n");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+    }
+}
+
+ATF_TC_WITHOUT_HEAD(wait__ok_nested);
+ATF_TC_BODY(wait__ok_nested, tc)
+{
+    const pid_t parent = atf_utils_fork();
+    ATF_REQUIRE(parent != -1);
+    if (parent == 0) {
+        const pid_t child = atf_utils_fork();
+        ATF_REQUIRE(child != -1);
+        if (child == 0) {
+            fflush(stderr);
+            fprintf(stdout, "Child output\n");
+            fflush(stdout);
+            fprintf(stderr, "Child error\n");
+            exit(50);
+        } else {
+            fprintf(stdout, "Parent output\n");
+            fprintf(stderr, "Parent error\n");
+            atf_utils_wait(child, 50, "Child output\n", "Child error\n");
+            exit(40);
+        }
+    } else {
+        atf_utils_wait(parent, 40,
+                       "Parent output\n"
+                       "subprocess stdout: Child output\n"
+                       "subprocess stderr: Child error\n",
+                       "Parent error\n");
+    }
+}
+
+ATF_TC_WITHOUT_HEAD(wait__invalid_exitstatus);
+ATF_TC_BODY(wait__invalid_exitstatus, tc)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(120, "Some output\n", "Some error\n");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
+    }
+}
+
+ATF_TC_WITHOUT_HEAD(wait__invalid_stdout);
+ATF_TC_BODY(wait__invalid_stdout, tc)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(123, "Some output foo\n", "Some error\n");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
+    }
+}
+
+ATF_TC_WITHOUT_HEAD(wait__invalid_stderr);
+ATF_TC_BODY(wait__invalid_stderr, tc)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(123, "Some output\n", "Some error foo\n");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
+    }
+}
+
+ATF_TC_WITHOUT_HEAD(wait__save_stdout);
+ATF_TC_BODY(wait__save_stdout, tc)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(123, "save:my-output.txt", "Some error\n");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+        ATF_REQUIRE(atf_utils_compare_file("my-output.txt", "Some output\n"));
+    }
+}
+
+ATF_TC_WITHOUT_HEAD(wait__save_stderr);
+ATF_TC_BODY(wait__save_stderr, tc)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(123, "Some output\n", "save:my-output.txt");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+        ATF_REQUIRE(atf_utils_compare_file("my-output.txt", "Some error\n"));
+    }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+    ATF_TP_ADD_TC(tp, cat_file__empty);
+    ATF_TP_ADD_TC(tp, cat_file__one_line);
+    ATF_TP_ADD_TC(tp, cat_file__several_lines);
+    ATF_TP_ADD_TC(tp, cat_file__no_newline_eof);
+
+    ATF_TP_ADD_TC(tp, compare_file__empty__match);
+    ATF_TP_ADD_TC(tp, compare_file__empty__not_match);
+    ATF_TP_ADD_TC(tp, compare_file__short__match);
+    ATF_TP_ADD_TC(tp, compare_file__short__not_match);
+    ATF_TP_ADD_TC(tp, compare_file__long__match);
+    ATF_TP_ADD_TC(tp, compare_file__long__not_match);
+
+    ATF_TP_ADD_TC(tp, copy_file__empty);
+    ATF_TP_ADD_TC(tp, copy_file__some_contents);
+
+    ATF_TP_ADD_TC(tp, create_file);
+
+    ATF_TP_ADD_TC(tp, file_exists);
+
+    ATF_TP_ADD_TC(tp, fork);
+
+    ATF_TP_ADD_TC(tp, free_charpp__empty);
+    ATF_TP_ADD_TC(tp, free_charpp__some);
+
+    ATF_TP_ADD_TC(tp, grep_file);
+    ATF_TP_ADD_TC(tp, grep_string);
+
+    ATF_TP_ADD_TC(tp, readline__none);
+    ATF_TP_ADD_TC(tp, readline__some);
+
+    ATF_TP_ADD_TC(tp, redirect__stdout);
+    ATF_TP_ADD_TC(tp, redirect__stderr);
+    ATF_TP_ADD_TC(tp, redirect__other);
+
+    ATF_TP_ADD_TC(tp, wait__ok);
+    ATF_TP_ADD_TC(tp, wait__ok_nested);
+    ATF_TP_ADD_TC(tp, wait__save_stdout);
+    ATF_TP_ADD_TC(tp, wait__save_stderr);
+    ATF_TP_ADD_TC(tp, wait__invalid_exitstatus);
+    ATF_TP_ADD_TC(tp, wait__invalid_stdout);
+    ATF_TP_ADD_TC(tp, wait__invalid_stderr);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/atf-c++/Kyuafile
===================================================================
--- vendor/atf/dist/atf-c++/Kyuafile	                        (rev 0)
+++ vendor/atf/dist/atf-c++/Kyuafile	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,13 @@
+syntax("kyuafile", 1)
+
+test_suite("atf")
+
+atf_test_program{name="atf_c++_test"}
+atf_test_program{name="build_test"}
+atf_test_program{name="check_test"}
+atf_test_program{name="macros_test"}
+atf_test_program{name="pkg_config_test"}
+atf_test_program{name="tests_test"}
+atf_test_program{name="utils_test"}
+
+include("detail/Kyuafile")

Added: vendor/atf/dist/atf-c++/atf-c++.3
===================================================================
--- vendor/atf/dist/atf-c++/atf-c++.3	                        (rev 0)
+++ vendor/atf/dist/atf-c++/atf-c++.3	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,649 @@
+.\" Copyright (c) 2008 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.
+.Dd March 6, 2017
+.Dt ATF-C++ 3
+.Os
+.Sh NAME
+.Nm atf-c++ ,
+.Nm ATF_ADD_TEST_CASE ,
+.Nm ATF_CHECK_ERRNO ,
+.Nm ATF_FAIL ,
+.Nm ATF_INIT_TEST_CASES ,
+.Nm ATF_PASS ,
+.Nm ATF_REQUIRE ,
+.Nm ATF_REQUIRE_EQ ,
+.Nm ATF_REQUIRE_ERRNO ,
+.Nm ATF_REQUIRE_IN ,
+.Nm ATF_REQUIRE_MATCH ,
+.Nm ATF_REQUIRE_NOT_IN ,
+.Nm ATF_REQUIRE_THROW ,
+.Nm ATF_REQUIRE_THROW_RE ,
+.Nm ATF_SKIP ,
+.Nm ATF_TEST_CASE ,
+.Nm ATF_TEST_CASE_BODY ,
+.Nm ATF_TEST_CASE_CLEANUP ,
+.Nm ATF_TEST_CASE_HEAD ,
+.Nm ATF_TEST_CASE_NAME ,
+.Nm ATF_TEST_CASE_USE ,
+.Nm ATF_TEST_CASE_WITH_CLEANUP ,
+.Nm ATF_TEST_CASE_WITHOUT_HEAD ,
+.Nm atf::utils::cat_file ,
+.Nm atf::utils::compare_file ,
+.Nm atf::utils::copy_file ,
+.Nm atf::utils::create_file ,
+.Nm atf::utils::file_exists ,
+.Nm atf::utils::fork ,
+.Nm atf::utils::grep_collection ,
+.Nm atf::utils::grep_file ,
+.Nm atf::utils::grep_string ,
+.Nm atf::utils::redirect ,
+.Nm atf::utils::wait
+.Nd C++ API to write ATF-based test programs
+.Sh SYNOPSIS
+.In atf-c++.hpp
+.Fn ATF_ADD_TEST_CASE "tcs" "name"
+.Fn ATF_CHECK_ERRNO "expected_errno" "bool_expression"
+.Fn ATF_FAIL "reason"
+.Fn ATF_INIT_TEST_CASES "tcs"
+.Fn ATF_PASS
+.Fn ATF_REQUIRE "expression"
+.Fn ATF_REQUIRE_EQ "expected_expression" "actual_expression"
+.Fn ATF_REQUIRE_ERRNO "expected_errno" "bool_expression"
+.Fn ATF_REQUIRE_IN "element" "collection"
+.Fn ATF_REQUIRE_MATCH "regexp" "string_expression"
+.Fn ATF_REQUIRE_NOT_IN "element" "collection"
+.Fn ATF_REQUIRE_THROW "expected_exception" "statement"
+.Fn ATF_REQUIRE_THROW_RE "expected_exception" "regexp" "statement"
+.Fn ATF_SKIP "reason"
+.Fn ATF_TEST_CASE "name"
+.Fn ATF_TEST_CASE_BODY "name"
+.Fn ATF_TEST_CASE_CLEANUP "name"
+.Fn ATF_TEST_CASE_HEAD "name"
+.Fn ATF_TEST_CASE_NAME "name"
+.Fn ATF_TEST_CASE_USE "name"
+.Fn ATF_TEST_CASE_WITH_CLEANUP "name"
+.Fn ATF_TEST_CASE_WITHOUT_HEAD "name"
+.Ft void
+.Fo atf::utils::cat_file
+.Fa "const std::string& path"
+.Fa "const std::string& prefix"
+.Fc
+.Ft bool
+.Fo atf::utils::compare_file
+.Fa "const std::string& path"
+.Fa "const std::string& contents"
+.Fc
+.Ft void
+.Fo atf::utils::copy_file
+.Fa "const std::string& source"
+.Fa "const std::string& destination"
+.Fc
+.Ft void
+.Fo atf::utils::create_file
+.Fa "const std::string& path"
+.Fa "const std::string& contents"
+.Fc
+.Ft void
+.Fo atf::utils::file_exists
+.Fa "const std::string& path"
+.Fc
+.Ft pid_t
+.Fo atf::utils::fork
+.Fa "void"
+.Fc
+.Ft bool
+.Fo atf::utils::grep_collection
+.Fa "const std::string& regexp"
+.Fa "const Collection& collection"
+.Fc
+.Ft bool
+.Fo atf::utils::grep_file
+.Fa "const std::string& regexp"
+.Fa "const std::string& path"
+.Fc
+.Ft bool
+.Fo atf::utils::grep_string
+.Fa "const std::string& regexp"
+.Fa "const std::string& path"
+.Fc
+.Ft void
+.Fo atf::utils::redirect
+.Fa "const int fd"
+.Fa "const std::string& path"
+.Fc
+.Ft void
+.Fo atf::utils::wait
+.Fa "const pid_t pid"
+.Fa "const int expected_exit_status"
+.Fa "const std::string& expected_stdout"
+.Fa "const std::string& expected_stderr"
+.Fc
+.Sh DESCRIPTION
+ATF provides a C++ programming interface to implement test programs.
+C++-based test programs follow this template:
+.Bd -literal -offset indent
+extern "C" {
+\&... C-specific includes go here ...
+}
+
+\&... C++-specific includes go here ...
+
+#include <atf-c++.hpp>
+
+ATF_TEST_CASE(tc1);
+ATF_TEST_CASE_HEAD(tc1)
+{
+    ... first test case's header ...
+}
+ATF_TEST_CASE_BODY(tc1)
+{
+    ... first test case's body ...
+}
+
+ATF_TEST_CASE_WITH_CLEANUP(tc2);
+ATF_TEST_CASE_HEAD(tc2)
+{
+    ... second test case's header ...
+}
+ATF_TEST_CASE_BODY(tc2)
+{
+    ... second test case's body ...
+}
+ATF_TEST_CASE_CLEANUP(tc2)
+{
+    ... second test case's cleanup ...
+}
+
+ATF_TEST_CASE(tc3);
+ATF_TEST_CASE_BODY(tc3)
+{
+    ... third test case's body ...
+}
+
+\&... additional test cases ...
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    ATF_ADD_TEST_CASE(tcs, tc1);
+    ATF_ADD_TEST_CASE(tcs, tc2);
+    ATF_ADD_TEST_CASE(tcs, tc3);
+    ... add additional test cases ...
+}
+.Ed
+.Ss Definition of test cases
+Test cases have an identifier and are composed of three different parts:
+the header, the body and an optional cleanup routine, all of which are
+described in
+.Xr atf-test-case 4 .
+To define test cases, one can use the
+.Fn ATF_TEST_CASE ,
+.Fn ATF_TEST_CASE_WITH_CLEANUP
+or the
+.Fn ATF_TEST_CASE_WITHOUT_HEAD
+macros, which take a single parameter specifying the test case's
+name.
+.Fn ATF_TEST_CASE ,
+requires to define a head and a body for the test case,
+.Fn ATF_TEST_CASE_WITH_CLEANUP
+requires to define a head, a body and a cleanup for the test case and
+.Fn ATF_TEST_CASE_WITHOUT_HEAD
+requires only a body for the test case.
+It is important to note that these
+.Em do not
+set the test case up for execution when the program is run.
+In order to do so, a later registration is needed through the
+.Fn ATF_ADD_TEST_CASE
+macro detailed in
+.Sx Program initialization .
+.Pp
+Later on, one must define the three parts of the body by means of three
+functions.
+Their headers are given by the
+.Fn ATF_TEST_CASE_HEAD ,
+.Fn ATF_TEST_CASE_BODY
+and
+.Fn ATF_TEST_CASE_CLEANUP
+macros, all of which take the test case's name.
+Following each of these, a block of code is expected, surrounded by the
+opening and closing brackets.
+.Pp
+Additionally, the
+.Fn ATF_TEST_CASE_NAME
+macro can be used to obtain the name of the class corresponding to a
+particular test case, as the name is internally managed by the library to
+prevent clashes with other user identifiers.
+Similarly, the
+.Fn ATF_TEST_CASE_USE
+macro can be executed on a particular test case to mark it as "used" and
+thus prevent compiler warnings regarding unused symbols.
+Note that
+.Em you should never have to use these macros during regular operation.
+.Ss Program initialization
+The library provides a way to easily define the test program's
+.Fn main
+function.
+You should never define one on your own, but rely on the
+library to do it for you.
+This is done by using the
+.Fn ATF_INIT_TEST_CASES
+macro, which is passed the name of the list that will hold the test cases.
+This name can be whatever you want as long as it is a valid variable value.
+.Pp
+After the macro, you are supposed to provide the body of a function, which
+should only use the
+.Fn ATF_ADD_TEST_CASE
+macro to register the test cases the test program will execute.
+The first parameter of this macro matches the name you provided in the
+former call.
+.Ss Header definitions
+The test case's header can define the meta-data by using the
+.Fn set_md_var
+method, which takes two parameters: the first one specifies the
+meta-data variable to be set and the second one specifies its value.
+Both of them are strings.
+.Ss Configuration variables
+The test case has read-only access to the current configuration variables
+by means of the
+.Ft bool
+.Fn has_config_var
+and the
+.Ft std::string
+.Fn get_config_var
+methods, which can be called in any of the three parts of a test case.
+.Ss Access to the source directory
+It is possible to get the path to the test case's source directory from any
+of its three components by querying the
+.Sq srcdir
+configuration variable.
+.Ss Requiring programs
+Aside from the
+.Va require.progs
+meta-data variable available in the header only, one can also check for
+additional programs in the test case's body by using the
+.Fn require_prog
+function, which takes the base name or full path of a single binary.
+Relative paths are forbidden.
+If it is not found, the test case will be automatically skipped.
+.Ss Test case finalization
+The test case finalizes either when the body reaches its end, at which
+point the test is assumed to have
+.Em passed ,
+or at any explicit call to
+.Fn ATF_PASS ,
+.Fn ATF_FAIL
+or
+.Fn ATF_SKIP .
+These three macros terminate the execution of the test case immediately.
+The cleanup routine will be processed afterwards in a completely automated
+way, regardless of the test case's termination reason.
+.Pp
+.Fn ATF_PASS
+does not take any parameters.
+.Fn ATF_FAIL
+and
+.Fn ATF_SKIP
+take a single string that describes why the test case failed or
+was skipped, respectively.
+It is very important to provide a clear error message in both cases so that
+the user can quickly know why the test did not pass.
+.Ss Expectations
+Everything explained in the previous section changes when the test case
+expectations are redefined by the programmer.
+.Pp
+Each test case has an internal state called
+.Sq expect
+that describes what the test case expectations are at any point in time.
+The value of this property can change during execution by any of:
+.Bl -tag -width indent
+.It Fn expect_death "reason"
+Expects the test case to exit prematurely regardless of the nature of the
+exit.
+.It Fn expect_exit "exitcode" "reason"
+Expects the test case to exit cleanly.
+If
+.Va exitcode
+is not
+.Sq -1 ,
+the runtime engine will validate that the exit code of the test case
+matches the one provided in this call.
+Otherwise, the exact value will be ignored.
+.It Fn expect_fail "reason"
+Any failure (be it fatal or non-fatal) raised in this mode is recorded.
+However, such failures do not report the test case as failed; instead, the
+test case finalizes cleanly and is reported as
+.Sq expected failure ;
+this report includes the provided
+.Fa reason
+as part of it.
+If no error is raised while running in this mode, then the test case is
+reported as
+.Sq failed .
+.Pp
+This mode is useful to reproduce actual known bugs in tests.
+Whenever the developer fixes the bug later on, the test case will start
+reporting a failure, signaling the developer that the test case must be
+adjusted to the new conditions.
+In this situation, it is useful, for example, to set
+.Fa reason
+as the bug number for tracking purposes.
+.It Fn expect_pass
+This is the normal mode of execution.
+In this mode, any failure is reported as such to the user and the test case
+is marked as
+.Sq failed .
+.It Fn expect_race "reason"
+Any failure or timeout during the execution of the test case will be
+considered as if a race condition has been triggered and reported as such.
+If no problems arise, the test will continue execution as usual.
+.It Fn expect_signal "signo" "reason"
+Expects the test case to terminate due to the reception of a signal.
+If
+.Va signo
+is not
+.Sq -1 ,
+the runtime engine will validate that the signal that terminated the test
+case matches the one provided in this call.
+Otherwise, the exact value will be ignored.
+.It Fn expect_timeout "reason"
+Expects the test case to execute for longer than its timeout.
+.El
+.Ss Helper macros for common checks
+The library provides several macros that are very handy in multiple
+situations.
+These basically check some condition after executing a given statement or
+processing a given expression and, if the condition is not met, they
+automatically call
+.Fn ATF_FAIL
+with an appropriate error message.
+.Pp
+.Fn ATF_REQUIRE
+takes an expression and raises a failure if it evaluates to false.
+.Pp
+.Fn ATF_REQUIRE_EQ
+takes two expressions and raises a failure if the two do not evaluate to
+the same exact value.
+The common style is to put the expected value in the first parameter and the
+actual value in the second parameter.
+.Pp
+.Fn ATF_REQUIRE_IN
+takes an element and a collection and validates that the element is present in
+the collection.
+.Pp
+.Fn ATF_REQUIRE_MATCH
+takes a regular expression and a string and raises a failure if the regular
+expression does not match the string.
+.Pp
+.Fn ATF_REQUIRE_NOT_IN
+takes an element and a collection and validates that the element is not present
+in the collection.
+.Pp
+.Fn ATF_REQUIRE_THROW
+takes the name of an exception and a statement and raises a failure if
+the statement does not throw the specified exception.
+.Fn ATF_REQUIRE_THROW_RE
+takes the name of an exception, a regular expresion and a statement and raises a
+failure if the statement does not throw the specified exception and if the
+message of the exception does not match the regular expression.
+.Pp
+.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
+.Va errno
+has to be checked against the first value.
+.Ss Utility functions
+The following functions are provided as part of the
+.Nm
+API to simplify the creation of a variety of tests.
+In particular, these are useful to write tests for command-line interfaces.
+.Pp
+.Ft void
+.Fo atf::utils::cat_file
+.Fa "const std::string& path"
+.Fa "const std::string& prefix"
+.Fc
+.Bd -ragged -offset indent
+Prints the contents of
+.Fa path
+to the standard output, prefixing every line with the string in
+.Fa prefix .
+.Ed
+.Pp
+.Ft bool
+.Fo atf::utils::compare_file
+.Fa "const std::string& path"
+.Fa "const std::string& contents"
+.Fc
+.Bd -ragged -offset indent
+Returns true if the given
+.Fa path
+matches exactly the expected inlined
+.Fa contents .
+.Ed
+.Pp
+.Ft void
+.Fo atf::utils::copy_file
+.Fa "const std::string& source"
+.Fa "const std::string& destination"
+.Fc
+.Bd -ragged -offset indent
+Copies the file
+.Fa source
+to
+.Fa destination .
+The permissions of the file are preserved during the code.
+.Ed
+.Pp
+.Ft void
+.Fo atf::utils::create_file
+.Fa "const std::string& path"
+.Fa "const std::string& contents"
+.Fc
+.Bd -ragged -offset indent
+Creates
+.Fa file
+with the text given in
+.Fa contents .
+.Ed
+.Pp
+.Ft void
+.Fo atf::utils::file_exists
+.Fa "const std::string& path"
+.Fc
+.Bd -ragged -offset indent
+Checks if
+.Fa path
+exists.
+.Ed
+.Pp
+.Ft pid_t
+.Fo atf::utils::fork
+.Fa "void"
+.Fc
+.Bd -ragged -offset indent
+Forks a process and redirects the standard output and standard error of the
+child to files for later validation with
+.Fn atf::utils::wait .
+Fails the test case if the fork fails, so this does not return an error.
+.Ed
+.Pp
+.Ft bool
+.Fo atf::utils::grep_collection
+.Fa "const std::string& regexp"
+.Fa "const Collection& collection"
+.Fc
+.Bd -ragged -offset indent
+Searches for the regular expression
+.Fa regexp
+in any of the strings contained in the
+.Fa collection .
+This is a template that accepts any one-dimensional container of strings.
+.Ed
+.Pp
+.Ft bool
+.Fo atf::utils::grep_file
+.Fa "const std::string& regexp"
+.Fa "const std::string& path"
+.Fc
+.Bd -ragged -offset indent
+Searches for the regular expression
+.Fa regexp
+in the file
+.Fa path .
+The variable arguments are used to construct the regular expression.
+.Ed
+.Pp
+.Ft bool
+.Fo atf::utils::grep_string
+.Fa "const std::string& regexp"
+.Fa "const std::string& str"
+.Fc
+.Bd -ragged -offset indent
+Searches for the regular expression
+.Fa regexp
+in the string
+.Fa str .
+.Ed
+.Ft void
+.Fo atf::utils::redirect
+.Fa "const int fd"
+.Fa "const std::string& path"
+.Fc
+.Bd -ragged -offset indent
+Redirects the given file descriptor
+.Fa fd
+to the file
+.Fa path .
+This function exits the process in case of an error and does not properly mark
+the test case as failed.
+As a result, it should only be used in subprocesses of the test case; specially
+those spawned by
+.Fn atf::utils::fork .
+.Ed
+.Pp
+.Ft void
+.Fo atf::utils::wait
+.Fa "const pid_t pid"
+.Fa "const int expected_exit_status"
+.Fa "const std::string& expected_stdout"
+.Fa "const std::string& expected_stderr"
+.Fc
+.Bd -ragged -offset indent
+Waits and validates the result of a subprocess spawned with
+.Fn atf::utils::wait .
+The validation involves checking that the subprocess exited cleanly and returned
+the code specified in
+.Fa expected_exit_status
+and that its standard output and standard error match the strings given in
+.Fa expected_stdout
+and
+.Fa expected_stderr .
+.Pp
+If any of the
+.Fa expected_stdout
+or
+.Fa expected_stderr
+strings are prefixed with
+.Sq save: ,
+then they specify the name of the file into which to store the stdout or stderr
+of the subprocess, and no comparison is performed.
+.Ed
+.Sh ENVIRONMENT
+The following variables are recognized by
+.Nm
+but should not be overridden other than for testing purposes:
+.Pp
+.Bl -tag -width ATFXBUILDXCXXFLAGSXX -compact
+.It Va ATF_BUILD_CC
+Path to the C compiler.
+.It Va ATF_BUILD_CFLAGS
+C compiler flags.
+.It Va ATF_BUILD_CPP
+Path to the C/C++ preprocessor.
+.It Va ATF_BUILD_CPPFLAGS
+C/C++ preprocessor flags.
+.It Va ATF_BUILD_CXX
+Path to the C++ compiler.
+.It Va ATF_BUILD_CXXFLAGS
+C++ compiler flags.
+.El
+.Sh EXAMPLES
+The following shows a complete test program with a single test case that
+validates the addition operator:
+.Bd -literal -offset indent
+#include <atf-c++.hpp>
+
+ATF_TEST_CASE(addition);
+ATF_TEST_CASE_HEAD(addition)
+{
+    set_md_var("descr", "Sample tests for the addition operator");
+}
+ATF_TEST_CASE_BODY(addition)
+{
+    ATF_REQUIRE_EQ(0, 0 + 0);
+    ATF_REQUIRE_EQ(1, 0 + 1);
+    ATF_REQUIRE_EQ(1, 1 + 0);
+
+    ATF_REQUIRE_EQ(2, 1 + 1);
+
+    ATF_REQUIRE_EQ(300, 100 + 200);
+}
+
+ATF_TEST_CASE(open_failure);
+ATF_TEST_CASE_HEAD(open_failure)
+{
+    set_md_var("descr", "Sample tests for the open function");
+}
+ATF_TEST_CASE_BODY(open_failure)
+{
+    ATF_REQUIRE_ERRNO(ENOENT, open("non-existent", O_RDONLY) == -1);
+}
+
+ATF_TEST_CASE(known_bug);
+ATF_TEST_CASE_HEAD(known_bug)
+{
+    set_md_var("descr", "Reproduces a known bug");
+}
+ATF_TEST_CASE_BODY(known_bug)
+{
+    expect_fail("See bug number foo/bar");
+    ATF_REQUIRE_EQ(3, 1 + 1);
+    expect_pass();
+    ATF_REQUIRE_EQ(3, 1 + 2);
+}
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    ATF_ADD_TEST_CASE(tcs, addition);
+    ATF_ADD_TEST_CASE(tcs, open_failure);
+    ATF_ADD_TEST_CASE(tcs, known_bug);
+}
+.Ed
+.Sh SEE ALSO
+.Xr atf-test-program 1 ,
+.Xr atf-test-case 4

Added: vendor/atf/dist/atf-c++/atf_c++_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/atf_c++_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/atf_c++_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,44 @@
+// Copyright (c) 2009 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++.hpp>
+
+#include "atf-c++/detail/test_helpers.hpp"
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+HEADER_TC(include, "atf-c++.hpp");
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    // Add the test cases for the header file.
+    ATF_ADD_TEST_CASE(tcs, include);
+}

Added: vendor/atf/dist/atf-c++/build.cpp
===================================================================
--- vendor/atf/dist/atf-c++/build.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/build.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,115 @@
+// Copyright (c) 2009 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++/build.hpp"
+
+extern "C" {
+#include "atf-c/build.h"
+#include "atf-c/error.h"
+#include "atf-c/utils.h"
+}
+
+#include "atf-c++/detail/exceptions.hpp"
+#include "atf-c++/detail/process.hpp"
+
+namespace impl = atf::build;
+#define IMPL_NAME "atf::build"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+inline
+atf::process::argv_array
+cargv_to_argv(const atf_list_t* l)
+{
+    std::vector< const char* > aux;
+
+    atf_list_citer_t iter;
+    atf_list_for_each_c(iter, l)
+        aux.push_back(static_cast< const char* >(atf_list_citer_data(iter)));
+
+    return atf::process::argv_array(aux);
+}
+
+inline
+atf::process::argv_array
+cargv_to_argv_and_free(char** l)
+{
+    try {
+        atf::process::argv_array argv((const char* const*)l);
+        atf_utils_free_charpp(l);
+        return argv;
+    } catch (...) {
+        atf_utils_free_charpp(l);
+        throw;
+    }
+}
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+atf::process::argv_array
+impl::c_o(const std::string& sfile, const std::string& ofile,
+          const atf::process::argv_array& optargs)
+{
+    char** l;
+
+    atf_error_t err = atf_build_c_o(sfile.c_str(), ofile.c_str(),
+                                    optargs.exec_argv(), &l);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return cargv_to_argv_and_free(l);
+}
+
+atf::process::argv_array
+impl::cpp(const std::string& sfile, const std::string& ofile,
+          const atf::process::argv_array& optargs)
+{
+    char** l;
+
+    atf_error_t err = atf_build_cpp(sfile.c_str(), ofile.c_str(),
+                                    optargs.exec_argv(), &l);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return cargv_to_argv_and_free(l);
+}
+
+atf::process::argv_array
+impl::cxx_o(const std::string& sfile, const std::string& ofile,
+            const atf::process::argv_array& optargs)
+{
+    char** l;
+
+    atf_error_t err = atf_build_cxx_o(sfile.c_str(), ofile.c_str(),
+                                      optargs.exec_argv(), &l);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return cargv_to_argv_and_free(l);
+}

Added: vendor/atf/dist/atf-c++/build.hpp
===================================================================
--- vendor/atf/dist/atf-c++/build.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/build.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,53 @@
+// Copyright (c) 2009 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_BUILD_HPP)
+#define ATF_CXX_BUILD_HPP
+
+#include <string>
+
+namespace atf {
+
+namespace process {
+class argv_array;
+} // namespace process
+
+namespace build {
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+process::argv_array c_o(const std::string&, const std::string&,
+                        const process::argv_array&);
+process::argv_array cpp(const std::string&, const std::string&,
+                        const process::argv_array&);
+process::argv_array cxx_o(const std::string&, const std::string&,
+                          const process::argv_array&);
+
+} // namespace build
+} // namespace atf
+
+#endif // !defined(ATF_CXX_BUILD_HPP)

Added: vendor/atf/dist/atf-c++/build_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/build_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/build_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,226 @@
+// Copyright (c) 2009 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++/build.hpp"
+
+#include <cstring>
+#include <iostream>
+
+#include <atf-c++.hpp>
+
+extern "C" {
+#include "atf-c/h_build.h"
+}
+
+#include "atf-c++/detail/env.hpp"
+#include "atf-c++/detail/process.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+template< class C >
+void
+print_col(const char* prefix, const C& c)
+{
+    std::cout << prefix << ":";
+    for (typename C::const_iterator iter = c.begin(); iter != c.end();
+         iter++)
+        std::cout << " '" << *iter << "'";
+    std::cout << "\n";
+}
+
+static
+void
+print_array(const char* prefix, const char* const* a)
+{
+    std::cout << prefix << ":";
+    for (; *a != NULL; a++)
+        std::cout << " '" << *a << "'";
+    std::cout << "\n";
+}
+
+static
+void
+verbose_set_env(const char *var, const char *val)
+{
+    std::cout << "Setting " << var << " to '" << val << "'\n";
+    atf::env::set(var, val);
+}
+
+static
+bool
+equal_argvs(const atf::process::argv_array& aa, const char* const* array)
+{
+    bool equal = true;
+
+    atf::process::argv_array::size_type i = 0;
+    while (equal && (i < aa.size() && array[i] != NULL)) {
+        if (std::strcmp(aa[i], array[i]) != 0)
+            equal = false;
+        else
+            i++;
+    }
+
+    if (equal && (i < aa.size() || array[i] != NULL))
+        equal = false;
+
+    return equal;
+}
+
+static
+void
+check_equal_argvs(const atf::process::argv_array& aa, const char* const* array)
+{
+    print_array("Expected arguments", array);
+    print_col("Arguments returned", aa);
+
+    if (!equal_argvs(aa, array))
+        ATF_FAIL("The constructed argv differs from the expected values");
+}
+
+// ------------------------------------------------------------------------
+// Internal test cases.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(equal_argvs);
+ATF_TEST_CASE_HEAD(equal_argvs)
+{
+    set_md_var("descr", "Tests the test case internal equal_argvs function");
+}
+ATF_TEST_CASE_BODY(equal_argvs)
+{
+    {
+        const char* const array[] = { NULL };
+        const char* const argv[] = { NULL };
+
+        ATF_REQUIRE(equal_argvs(atf::process::argv_array(argv), array));
+    }
+
+    {
+        const char* const array[] = { NULL };
+        const char* const argv[] = { "foo", NULL };
+
+        ATF_REQUIRE(!equal_argvs(atf::process::argv_array(argv), array));
+    }
+
+    {
+        const char* const array[] = { "foo", NULL };
+        const char* const argv[] = { NULL };
+
+        ATF_REQUIRE(!equal_argvs(atf::process::argv_array(argv), array));
+    }
+
+    {
+        const char* const array[] = { "foo", NULL };
+        const char* const argv[] = { "foo", NULL };
+
+        ATF_REQUIRE(equal_argvs(atf::process::argv_array(argv), array));
+    }
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(c_o);
+ATF_TEST_CASE_HEAD(c_o)
+{
+    set_md_var("descr", "Tests the c_o function");
+}
+ATF_TEST_CASE_BODY(c_o)
+{
+    for (struct c_o_test* test = c_o_tests; test->expargv[0] != NULL;
+         test++) {
+        std::cout << "> Test: " << test->msg << "\n";
+
+        verbose_set_env("ATF_BUILD_CC", test->cc);
+        verbose_set_env("ATF_BUILD_CFLAGS", test->cflags);
+        verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+
+        atf::process::argv_array argv =
+            atf::build::c_o(test->sfile, test->ofile,
+                            atf::process::argv_array(test->optargs));
+        check_equal_argvs(argv, test->expargv);
+    }
+}
+
+ATF_TEST_CASE(cpp);
+ATF_TEST_CASE_HEAD(cpp)
+{
+    set_md_var("descr", "Tests the cpp function");
+}
+ATF_TEST_CASE_BODY(cpp)
+{
+    for (struct cpp_test* test = cpp_tests; test->expargv[0] != NULL;
+         test++) {
+        std::cout << "> Test: " << test->msg << "\n";
+
+        verbose_set_env("ATF_BUILD_CPP", test->cpp);
+        verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+
+        atf::process::argv_array argv =
+            atf::build::cpp(test->sfile, test->ofile,
+                            atf::process::argv_array(test->optargs));
+        check_equal_argvs(argv, test->expargv);
+    }
+}
+
+ATF_TEST_CASE(cxx_o);
+ATF_TEST_CASE_HEAD(cxx_o)
+{
+    set_md_var("descr", "Tests the cxx_o function");
+}
+ATF_TEST_CASE_BODY(cxx_o)
+{
+    for (struct cxx_o_test* test = cxx_o_tests; test->expargv[0] != NULL;
+         test++) {
+        std::cout << "> Test: " << test->msg << "\n";
+
+        verbose_set_env("ATF_BUILD_CXX", test->cxx);
+        verbose_set_env("ATF_BUILD_CXXFLAGS", test->cxxflags);
+        verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
+
+        atf::process::argv_array argv =
+            atf::build::cxx_o(test->sfile, test->ofile,
+                              atf::process::argv_array(test->optargs));
+        check_equal_argvs(argv, test->expargv);
+    }
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    // Add the internal test cases.
+    ATF_ADD_TEST_CASE(tcs, equal_argvs);
+
+    // Add the test cases for the free functions.
+    ATF_ADD_TEST_CASE(tcs, c_o);
+    ATF_ADD_TEST_CASE(tcs, cpp);
+    ATF_ADD_TEST_CASE(tcs, cxx_o);
+}

Added: vendor/atf/dist/atf-c++/check.cpp
===================================================================
--- vendor/atf/dist/atf-c++/check.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/check.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,154 @@
+// 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++/check.hpp"
+
+#include <cstring>
+
+extern "C" {
+#include "atf-c/build.h"
+#include "atf-c/error.h"
+}
+
+#include "atf-c++/detail/exceptions.hpp"
+#include "atf-c++/detail/process.hpp"
+#include "atf-c++/detail/sanity.hpp"
+
+namespace impl = atf::check;
+#define IMPL_NAME "atf::check"
+
+// ------------------------------------------------------------------------
+// The "check_result" class.
+// ------------------------------------------------------------------------
+
+impl::check_result::check_result(const atf_check_result_t* result)
+{
+    std::memcpy(&m_result, result, sizeof(m_result));
+}
+
+impl::check_result::~check_result(void)
+{
+    atf_check_result_fini(&m_result);
+}
+
+bool
+impl::check_result::exited(void)
+    const
+{
+    return atf_check_result_exited(&m_result);
+}
+
+int
+impl::check_result::exitcode(void)
+    const
+{
+    PRE(exited());
+    return atf_check_result_exitcode(&m_result);
+}
+
+bool
+impl::check_result::signaled(void)
+    const
+{
+    return atf_check_result_signaled(&m_result);
+}
+
+int
+impl::check_result::termsig(void)
+    const
+{
+    PRE(signaled());
+    return atf_check_result_termsig(&m_result);
+}
+
+const std::string
+impl::check_result::stdout_path(void) const
+{
+    return atf_check_result_stdout(&m_result);
+}
+
+const std::string
+impl::check_result::stderr_path(void) const
+{
+    return atf_check_result_stderr(&m_result);
+}
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+bool
+impl::build_c_o(const std::string& sfile, const std::string& ofile,
+                const atf::process::argv_array& optargs)
+{
+    bool success;
+
+    atf_error_t err = atf_check_build_c_o(sfile.c_str(), ofile.c_str(),
+                                          optargs.exec_argv(), &success);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return success;
+}
+
+bool
+impl::build_cpp(const std::string& sfile, const std::string& ofile,
+                const atf::process::argv_array& optargs)
+{
+    bool success;
+
+    atf_error_t err = atf_check_build_cpp(sfile.c_str(), ofile.c_str(),
+                                          optargs.exec_argv(), &success);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return success;
+}
+
+bool
+impl::build_cxx_o(const std::string& sfile, const std::string& ofile,
+                  const atf::process::argv_array& optargs)
+{
+    bool success;
+
+    atf_error_t err = atf_check_build_cxx_o(sfile.c_str(), ofile.c_str(),
+                                            optargs.exec_argv(), &success);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return success;
+}
+
+std::auto_ptr< impl::check_result >
+impl::exec(const atf::process::argv_array& argva)
+{
+    atf_check_result_t result;
+
+    atf_error_t err = atf_check_exec_array(argva.exec_argv(), &result);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return std::auto_ptr< impl::check_result >(new impl::check_result(&result));
+}

Added: vendor/atf/dist/atf-c++/check.hpp
===================================================================
--- vendor/atf/dist/atf-c++/check.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/check.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,131 @@
+// 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_CHECK_HPP)
+#define ATF_CXX_CHECK_HPP
+
+extern "C" {
+#include <atf-c/check.h>
+}
+
+#include <cstddef>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace atf {
+
+namespace process {
+class argv_array;
+} // namespace process
+
+namespace check {
+
+// ------------------------------------------------------------------------
+// The "check_result" class.
+// ------------------------------------------------------------------------
+
+//!
+//! \brief A class that contains results of executed command.
+//!
+//! The check_result class holds information about results
+//! of executing arbitrary command and manages files containing
+//! its output.
+//!
+class check_result {
+    // Non-copyable.
+    check_result(const check_result&);
+    check_result& operator=(const check_result&);
+
+    //!
+    //! \brief Internal representation of a result.
+    //!
+    atf_check_result_t m_result;
+
+    //!
+    //! \brief Constructs a results object and grabs ownership of the
+    //! parameter passed in.
+    //!
+    check_result(const atf_check_result_t* result);
+
+    friend check_result test_constructor(const char* const*);
+    friend std::auto_ptr< check_result > exec(const atf::process::argv_array&);
+
+public:
+    //!
+    //! \brief Destroys object and removes all managed files.
+    //!
+    ~check_result(void);
+
+    //!
+    //! \brief Returns whether the command exited correctly or not.
+    //!
+    bool exited(void) const;
+
+    //!
+    //! \brief Returns command's exit status.
+    //!
+    int exitcode(void) const;
+
+    //!
+    //! \brief Returns whether the command received a signal or not.
+    //!
+    bool signaled(void) const;
+
+    //!
+    //! \brief Returns the signal that terminated the command.
+    //!
+    int termsig(void) const;
+
+    //!
+    //! \brief Returns the path to file contaning command's stdout.
+    //!
+    const std::string stdout_path(void) const;
+
+    //!
+    //! \brief Returns the path to file contaning command's stderr.
+    //!
+    const std::string stderr_path(void) const;
+};
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+bool build_c_o(const std::string&, const std::string&,
+               const atf::process::argv_array&);
+bool build_cpp(const std::string&, const std::string&,
+               const atf::process::argv_array&);
+bool build_cxx_o(const std::string&, const std::string&,
+                 const atf::process::argv_array&);
+std::auto_ptr< check_result > exec(const atf::process::argv_array&);
+
+// Useful for testing only.
+check_result test_constructor(void);
+
+} // namespace check
+} // namespace atf
+
+#endif // !defined(ATF_CXX_CHECK_HPP)

Added: vendor/atf/dist/atf-c++/check_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/check_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/check_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,394 @@
+// 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++/check.hpp"
+
+extern "C" {
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+}
+
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <list>
+#include <memory>
+#include <vector>
+
+#include <atf-c++.hpp>
+
+#include "atf-c++/detail/fs.hpp"
+#include "atf-c++/detail/process.hpp"
+#include "atf-c++/detail/test_helpers.hpp"
+#include "atf-c++/detail/text.hpp"
+#include "atf-c++/utils.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+std::auto_ptr< atf::check::check_result >
+do_exec(const atf::tests::tc* tc, const char* helper_name)
+{
+    std::vector< std::string > argv;
+    argv.push_back(get_process_helpers_path(*tc, false).str());
+    argv.push_back(helper_name);
+    std::cout << "Executing " << argv[0] << " " << argv[1] << "\n";
+
+    atf::process::argv_array argva(argv);
+    return atf::check::exec(argva);
+}
+
+static
+std::auto_ptr< atf::check::check_result >
+do_exec(const atf::tests::tc* tc, const char* helper_name, const char *carg2)
+{
+    std::vector< std::string > argv;
+    argv.push_back(get_process_helpers_path(*tc, false).str());
+    argv.push_back(helper_name);
+    argv.push_back(carg2);
+    std::cout << "Executing " << argv[0] << " " << argv[1] << " "
+              << argv[2] << "\n";
+
+    atf::process::argv_array argva(argv);
+    return atf::check::exec(argva);
+}
+
+// ------------------------------------------------------------------------
+// Helper test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(h_build_c_o_ok);
+ATF_TEST_CASE_HEAD(h_build_c_o_ok)
+{
+    set_md_var("descr", "Helper test case for build_c_o");
+}
+ATF_TEST_CASE_BODY(h_build_c_o_ok)
+{
+    std::ofstream sfile("test.c");
+    sfile << "#include <stdio.h>\n";
+    sfile.close();
+
+    ATF_REQUIRE(atf::check::build_c_o("test.c", "test.o",
+                                      atf::process::argv_array()));
+}
+
+ATF_TEST_CASE(h_build_c_o_fail);
+ATF_TEST_CASE_HEAD(h_build_c_o_fail)
+{
+    set_md_var("descr", "Helper test case for build_c_o");
+}
+ATF_TEST_CASE_BODY(h_build_c_o_fail)
+{
+    std::ofstream sfile("test.c");
+    sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
+    sfile.close();
+
+    ATF_REQUIRE(!atf::check::build_c_o("test.c", "test.o",
+                                       atf::process::argv_array()));
+}
+
+ATF_TEST_CASE(h_build_cpp_ok);
+ATF_TEST_CASE_HEAD(h_build_cpp_ok)
+{
+    set_md_var("descr", "Helper test case for build_cpp");
+}
+ATF_TEST_CASE_BODY(h_build_cpp_ok)
+{
+    std::ofstream sfile("test.c");
+    sfile << "#define A foo\n";
+    sfile << "#define B bar\n";
+    sfile << "A B\n";
+    sfile.close();
+
+    ATF_REQUIRE(atf::check::build_cpp("test.c", "test.p",
+                                      atf::process::argv_array()));
+}
+
+ATF_TEST_CASE(h_build_cpp_fail);
+ATF_TEST_CASE_HEAD(h_build_cpp_fail)
+{
+    set_md_var("descr", "Helper test case for build_cpp");
+}
+ATF_TEST_CASE_BODY(h_build_cpp_fail)
+{
+    std::ofstream sfile("test.c");
+    sfile << "#include \"./non-existent.h\"\n";
+    sfile.close();
+
+    ATF_REQUIRE(!atf::check::build_cpp("test.c", "test.p",
+                                       atf::process::argv_array()));
+}
+
+ATF_TEST_CASE(h_build_cxx_o_ok);
+ATF_TEST_CASE_HEAD(h_build_cxx_o_ok)
+{
+    set_md_var("descr", "Helper test case for build_cxx_o");
+}
+ATF_TEST_CASE_BODY(h_build_cxx_o_ok)
+{
+    std::ofstream sfile("test.cpp");
+    sfile << "#include <iostream>\n";
+    sfile.close();
+
+    ATF_REQUIRE(atf::check::build_cxx_o("test.cpp", "test.o",
+                                        atf::process::argv_array()));
+}
+
+ATF_TEST_CASE(h_build_cxx_o_fail);
+ATF_TEST_CASE_HEAD(h_build_cxx_o_fail)
+{
+    set_md_var("descr", "Helper test case for build_cxx_o");
+}
+ATF_TEST_CASE_BODY(h_build_cxx_o_fail)
+{
+    std::ofstream sfile("test.cpp");
+    sfile << "void foo(void) { int a = UNDEFINED_SYMBOL; }\n";
+    sfile.close();
+
+    ATF_REQUIRE(!atf::check::build_cxx_o("test.cpp", "test.o",
+                                         atf::process::argv_array()));
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(build_c_o);
+ATF_TEST_CASE_HEAD(build_c_o)
+{
+    set_md_var("descr", "Tests the build_c_o function");
+}
+ATF_TEST_CASE_BODY(build_c_o)
+{
+    ATF_TEST_CASE_USE(h_build_c_o_ok);
+    run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_ok) >();
+    ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
+    ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
+
+    ATF_TEST_CASE_USE(h_build_c_o_fail);
+    run_h_tc< ATF_TEST_CASE_NAME(h_build_c_o_fail) >();
+    ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
+    ATF_REQUIRE(atf::utils::grep_file("-c test.c", "stdout"));
+    ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
+    ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
+}
+
+ATF_TEST_CASE(build_cpp);
+ATF_TEST_CASE_HEAD(build_cpp)
+{
+    set_md_var("descr", "Tests the build_cpp function");
+}
+ATF_TEST_CASE_BODY(build_cpp)
+{
+    ATF_TEST_CASE_USE(h_build_cpp_ok);
+    run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_ok) >();
+    ATF_REQUIRE(atf::utils::grep_file("-o.*test.p", "stdout"));
+    ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
+    ATF_REQUIRE(atf::utils::grep_file("foo bar", "test.p"));
+
+    ATF_TEST_CASE_USE(h_build_cpp_fail);
+    run_h_tc< ATF_TEST_CASE_NAME(h_build_cpp_fail) >();
+    ATF_REQUIRE(atf::utils::grep_file("-o test.p", "stdout"));
+    ATF_REQUIRE(atf::utils::grep_file("test.c", "stdout"));
+    ATF_REQUIRE(atf::utils::grep_file("test.c", "stderr"));
+    ATF_REQUIRE(atf::utils::grep_file("non-existent.h", "stderr"));
+}
+
+ATF_TEST_CASE(build_cxx_o);
+ATF_TEST_CASE_HEAD(build_cxx_o)
+{
+    set_md_var("descr", "Tests the build_cxx_o function");
+}
+ATF_TEST_CASE_BODY(build_cxx_o)
+{
+    ATF_TEST_CASE_USE(h_build_cxx_o_ok);
+    run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_ok) >();
+    ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
+    ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
+
+    ATF_TEST_CASE_USE(h_build_cxx_o_fail);
+    run_h_tc< ATF_TEST_CASE_NAME(h_build_cxx_o_fail) >();
+    ATF_REQUIRE(atf::utils::grep_file("-o test.o", "stdout"));
+    ATF_REQUIRE(atf::utils::grep_file("-c test.cpp", "stdout"));
+    ATF_REQUIRE(atf::utils::grep_file("test.cpp", "stderr"));
+    ATF_REQUIRE(atf::utils::grep_file("UNDEFINED_SYMBOL", "stderr"));
+}
+
+ATF_TEST_CASE(exec_cleanup);
+ATF_TEST_CASE_HEAD(exec_cleanup)
+{
+    set_md_var("descr", "Tests that exec properly cleans up the temporary "
+               "files it creates");
+}
+ATF_TEST_CASE_BODY(exec_cleanup)
+{
+    std::auto_ptr< atf::fs::path > out;
+    std::auto_ptr< atf::fs::path > err;
+
+    {
+        std::auto_ptr< atf::check::check_result > r =
+            do_exec(this, "exit-success");
+        out.reset(new atf::fs::path(r->stdout_path()));
+        err.reset(new atf::fs::path(r->stderr_path()));
+        ATF_REQUIRE(atf::fs::exists(*out.get()));
+        ATF_REQUIRE(atf::fs::exists(*err.get()));
+    }
+    ATF_REQUIRE(!atf::fs::exists(*out.get()));
+    ATF_REQUIRE(!atf::fs::exists(*err.get()));
+}
+
+ATF_TEST_CASE(exec_exitstatus);
+ATF_TEST_CASE_HEAD(exec_exitstatus)
+{
+    set_md_var("descr", "Tests that exec properly captures the exit "
+               "status of the executed command");
+}
+ATF_TEST_CASE_BODY(exec_exitstatus)
+{
+    {
+        std::auto_ptr< atf::check::check_result > r =
+            do_exec(this, "exit-success");
+        ATF_REQUIRE(r->exited());
+        ATF_REQUIRE(!r->signaled());
+        ATF_REQUIRE_EQ(r->exitcode(), EXIT_SUCCESS);
+    }
+
+    {
+        std::auto_ptr< atf::check::check_result > r =
+            do_exec(this, "exit-failure");
+        ATF_REQUIRE(r->exited());
+        ATF_REQUIRE(!r->signaled());
+        ATF_REQUIRE_EQ(r->exitcode(), EXIT_FAILURE);
+    }
+
+    {
+        std::auto_ptr< atf::check::check_result > r =
+            do_exec(this, "exit-signal");
+        ATF_REQUIRE(!r->exited());
+        ATF_REQUIRE(r->signaled());
+        ATF_REQUIRE_EQ(r->termsig(), SIGKILL);
+    }
+}
+
+static
+void
+check_lines(const std::string& path, const char* outname,
+            const char* resname)
+{
+    std::ifstream f(path.c_str());
+    ATF_REQUIRE(f);
+
+    std::string line;
+    std::getline(f, line);
+    ATF_REQUIRE_EQ(line, std::string("Line 1 to ") + outname + " for " +
+                    resname);
+    std::getline(f, line);
+    ATF_REQUIRE_EQ(line, std::string("Line 2 to ") + outname + " for " +
+                    resname);
+}
+
+ATF_TEST_CASE(exec_stdout_stderr);
+ATF_TEST_CASE_HEAD(exec_stdout_stderr)
+{
+    set_md_var("descr", "Tests that exec properly captures the stdout "
+               "and stderr streams of the child process");
+}
+ATF_TEST_CASE_BODY(exec_stdout_stderr)
+{
+    std::auto_ptr< atf::check::check_result > r1 =
+        do_exec(this, "stdout-stderr", "result1");
+    ATF_REQUIRE(r1->exited());
+    ATF_REQUIRE_EQ(r1->exitcode(), EXIT_SUCCESS);
+
+    std::auto_ptr< atf::check::check_result > r2 =
+        do_exec(this, "stdout-stderr", "result2");
+    ATF_REQUIRE(r2->exited());
+    ATF_REQUIRE_EQ(r2->exitcode(), EXIT_SUCCESS);
+
+    const std::string out1 = r1->stdout_path();
+    const std::string out2 = r2->stdout_path();
+    const std::string err1 = r1->stderr_path();
+    const std::string err2 = r2->stderr_path();
+
+    ATF_REQUIRE(out1.find("check.XXXXXX") == std::string::npos);
+    ATF_REQUIRE(out2.find("check.XXXXXX") == std::string::npos);
+    ATF_REQUIRE(err1.find("check.XXXXXX") == std::string::npos);
+    ATF_REQUIRE(err2.find("check.XXXXXX") == std::string::npos);
+
+    ATF_REQUIRE(out1.find("/check") != std::string::npos);
+    ATF_REQUIRE(out2.find("/check") != std::string::npos);
+    ATF_REQUIRE(err1.find("/check") != std::string::npos);
+    ATF_REQUIRE(err2.find("/check") != std::string::npos);
+
+    ATF_REQUIRE(out1.find("/stdout") != std::string::npos);
+    ATF_REQUIRE(out2.find("/stdout") != std::string::npos);
+    ATF_REQUIRE(err1.find("/stderr") != std::string::npos);
+    ATF_REQUIRE(err2.find("/stderr") != std::string::npos);
+
+    ATF_REQUIRE(out1 != out2);
+    ATF_REQUIRE(err1 != err2);
+
+    check_lines(out1, "stdout", "result1");
+    check_lines(out2, "stdout", "result2");
+    check_lines(err1, "stderr", "result1");
+    check_lines(err2, "stderr", "result2");
+}
+
+ATF_TEST_CASE(exec_unknown);
+ATF_TEST_CASE_HEAD(exec_unknown)
+{
+    set_md_var("descr", "Tests that running a non-existing binary "
+               "is handled correctly");
+}
+ATF_TEST_CASE_BODY(exec_unknown)
+{
+    std::vector< std::string > argv;
+    argv.push_back("/foo/bar/non-existent");
+
+    atf::process::argv_array argva(argv);
+    std::auto_ptr< atf::check::check_result > r = atf::check::exec(argva);
+    ATF_REQUIRE(r->exited());
+    ATF_REQUIRE_EQ(r->exitcode(), 127);
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    // Add the test cases for the free functions.
+    ATF_ADD_TEST_CASE(tcs, build_c_o);
+    ATF_ADD_TEST_CASE(tcs, build_cpp);
+    ATF_ADD_TEST_CASE(tcs, build_cxx_o);
+    ATF_ADD_TEST_CASE(tcs, exec_cleanup);
+    ATF_ADD_TEST_CASE(tcs, exec_exitstatus);
+    ATF_ADD_TEST_CASE(tcs, exec_stdout_stderr);
+    ATF_ADD_TEST_CASE(tcs, exec_unknown);
+}

Added: vendor/atf/dist/atf-c++/detail/Kyuafile
===================================================================
--- vendor/atf/dist/atf-c++/detail/Kyuafile	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/Kyuafile	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,11 @@
+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"}
+atf_test_program{name="process_test"}
+atf_test_program{name="text_test"}

Added: vendor/atf/dist/atf-c++/detail/application.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/application.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/application.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,249 @@
+// 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/application.hpp"
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+extern "C" {
+#include <unistd.h>
+}
+
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+
+extern "C" {
+#include "atf-c/defs.h"
+}
+
+#include "atf-c++/detail/sanity.hpp"
+
+#if !defined(HAVE_VSNPRINTF_IN_STD)
+namespace std {
+using ::vsnprintf;
+}
+#endif // !defined(HAVE_VSNPRINTF_IN_STD)
+
+namespace impl = atf::application;
+#define IMPL_NAME "atf::application"
+
+// ------------------------------------------------------------------------
+// The "usage_error" class.
+// ------------------------------------------------------------------------
+
+impl::usage_error::usage_error(const char *fmt, ...)
+    throw() :
+    std::runtime_error("usage_error; message unformatted")
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    std::vsnprintf(m_text, sizeof(m_text), fmt, ap);
+    va_end(ap);
+}
+
+impl::usage_error::~usage_error(void)
+    throw()
+{
+}
+
+const char*
+impl::usage_error::what(void)
+    const throw()
+{
+    return m_text;
+}
+
+// ------------------------------------------------------------------------
+// The "application" class.
+// ------------------------------------------------------------------------
+
+impl::option::option(char ch,
+                     const std::string& a,
+                     const std::string& desc) :
+    m_character(ch),
+    m_argument(a),
+    m_description(desc)
+{
+}
+
+bool
+impl::option::operator<(const impl::option& o)
+    const
+{
+    return m_character < o.m_character;
+}
+
+impl::app::app(const std::string& description,
+               const std::string& manpage) :
+    m_argc(-1),
+    m_argv(NULL),
+    m_prog_name(NULL),
+    m_description(description),
+    m_manpage(manpage)
+{
+}
+
+impl::app::~app(void)
+{
+}
+
+bool
+impl::app::inited(void)
+{
+    return m_argc != -1;
+}
+
+impl::app::options_set
+impl::app::options(void)
+{
+    return specific_options();
+}
+
+std::string
+impl::app::specific_args(void)
+    const
+{
+    return "";
+}
+
+impl::app::options_set
+impl::app::specific_options(void)
+    const
+{
+    return options_set();
+}
+
+void
+impl::app::process_option(int ch ATF_DEFS_ATTRIBUTE_UNUSED,
+                          const char* arg ATF_DEFS_ATTRIBUTE_UNUSED)
+{
+}
+
+void
+impl::app::process_options(void)
+{
+    PRE(inited());
+
+    std::string optstr;
+#if defined(HAVE_GNU_GETOPT)
+    optstr += '+'; // Turn on POSIX behavior.
+#endif
+    optstr += ':';
+    {
+        options_set opts = options();
+        for (options_set::const_iterator iter = opts.begin();
+             iter != opts.end(); iter++) {
+            const option& opt = (*iter);
+
+            optstr += opt.m_character;
+            if (!opt.m_argument.empty())
+                optstr += ':';
+        }
+    }
+
+    int ch;
+    const int old_opterr = ::opterr;
+    ::opterr = 0;
+    while ((ch = ::getopt(m_argc, m_argv, optstr.c_str())) != -1) {
+        switch (ch) {
+            case ':':
+                throw usage_error("Option -%c requires an argument.",
+                                  ::optopt);
+
+            case '?':
+                throw usage_error("Unknown option -%c.", ::optopt);
+
+            default:
+                process_option(ch, ::optarg);
+        }
+    }
+    m_argc -= ::optind;
+    m_argv += ::optind;
+
+    // Clear getopt state just in case the test wants to use it.
+    opterr = old_opterr;
+    optind = 1;
+#if defined(HAVE_OPTRESET)
+    optreset = 1;
+#endif
+}
+
+int
+impl::app::run(int argc, char* const* argv)
+{
+    PRE(argc > 0);
+    PRE(argv != NULL);
+
+    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;
+
+    const std::string bug =
+        std::string("This is probably a bug in ") + m_prog_name +
+        " or one of the libraries it uses.  Please report this problem to "
+        PACKAGE_BUGREPORT " and provide as many details as possible "
+        "describing how you got to this condition.";
+
+    int errcode;
+    try {
+        process_options();
+        errcode = main();
+    } catch (const usage_error& e) {
+        std::cerr << m_prog_name << ": ERROR: " << e.what() << "\n";
+        std::cerr << m_prog_name << ": See " << m_manpage << " for usage "
+            "details.\n";
+        errcode = EXIT_FAILURE;
+    } catch (const std::runtime_error& e) {
+        std::cerr << m_prog_name << ": ERROR: " << e.what() << "\n";
+        errcode = EXIT_FAILURE;
+    } catch (const std::exception& e) {
+        std::cerr << m_prog_name << ": ERROR: Caught unexpected error: "
+                  << e.what() << "\n";
+        errcode = EXIT_FAILURE;
+    } catch (...) {
+        std::cerr << m_prog_name << ": ERROR: Caught unknown error\n";
+        errcode = EXIT_FAILURE;
+    }
+    return errcode;
+}

Added: vendor/atf/dist/atf-c++/detail/application.hpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/application.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/application.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,107 @@
+// 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_APPLICATION_HPP)
+#define ATF_CXX_DETAIL_APPLICATION_HPP
+
+#include <ostream>
+#include <set>
+#include <stdexcept>
+#include <string>
+
+namespace atf {
+namespace application {
+
+// ------------------------------------------------------------------------
+// The "usage_error" class.
+// ------------------------------------------------------------------------
+
+class usage_error : public std::runtime_error {
+    char m_text[4096];
+
+public:
+    usage_error(const char*, ...) throw();
+    ~usage_error(void) throw();
+
+    const char* what(void) const throw();
+};
+
+// ------------------------------------------------------------------------
+// The "option" class.
+// ------------------------------------------------------------------------
+
+class option {
+    char m_character;
+    std::string m_argument;
+    std::string m_description;
+
+    friend class app;
+
+public:
+    option(char, const std::string&, const std::string&);
+
+    bool operator<(const option&) const;
+};
+
+// ------------------------------------------------------------------------
+// The "app" class.
+// ------------------------------------------------------------------------
+
+class app {
+    void process_options(void);
+    void usage(std::ostream&);
+
+    bool inited(void);
+
+protected:
+    typedef std::set< option > options_set;
+
+    int m_argc;
+    char* const* m_argv;
+
+    const char* m_argv0;
+    const char* m_prog_name;
+    std::string m_description;
+    std::string m_manpage;
+
+    options_set options(void);
+
+    // To be redefined.
+    virtual std::string specific_args(void) const;
+    virtual options_set specific_options(void) const;
+    virtual void process_option(int, const char*);
+    virtual int main(void) = 0;
+
+public:
+    app(const std::string&, const std::string&);
+    virtual ~app(void);
+
+    int run(int, char* const*);
+};
+
+} // namespace application
+} // namespace atf
+
+#endif // !defined(ATF_CXX_DETAIL_APPLICATION_HPP)

Added: vendor/atf/dist/atf-c++/detail/application_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/application_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/application_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,90 @@
+// Copyright (c) 2009 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/application.hpp"
+
+extern "C" {
+#include <unistd.h>
+}
+
+#include <atf-c++.hpp>
+
+class getopt_app : public atf::application::app {
+public:
+    getopt_app(void) : app("description", "manpage") {}
+
+    int main(void)
+    {
+        // Provide an option that is unknown to the application driver and
+        // one that is, together with an argument that would be swallowed by
+        // the test program option if it were recognized.
+        int argc = 4;
+        char arg1[] = "progname";
+        char arg2[] = "-Z";
+        char arg3[] = "-s";
+        char arg4[] = "foo";
+        char *const argv[] = { arg1, arg2, arg3, arg4, NULL };
+
+        int ch;
+        bool zflag;
+
+        // Given that this obviously is an application, and that we used the
+        // same driver to start, we can test getopt(3) right here without doing
+        // any fancy stuff.
+        zflag = false;
+        while ((ch = ::getopt(argc, argv, ":Z")) != -1) {
+            switch (ch) {
+            case 'Z':
+                zflag = true;
+                break;
+
+            case '?':
+            default:
+                if (optopt != 's')
+                    ATF_FAIL("Unexpected unknown option found");
+            }
+        }
+
+        ATF_REQUIRE(zflag);
+        ATF_REQUIRE_EQ(1, argc - optind);
+        ATF_REQUIRE_EQ(std::string("foo"), argv[optind]);
+
+        return 0;
+    }
+};
+
+ATF_TEST_CASE_WITHOUT_HEAD(getopt);
+ATF_TEST_CASE_BODY(getopt)
+{
+    int argc = 1;
+    char arg1[] = "progname";
+    char *const argv[] = { arg1, NULL };
+    ATF_REQUIRE_EQ(0, getopt_app().run(argc, argv));
+}
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    ATF_ADD_TEST_CASE(tcs, getopt);
+}

Added: vendor/atf/dist/atf-c++/detail/auto_array.hpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/auto_array.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/auto_array.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,175 @@
+// 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)

Added: vendor/atf/dist/atf-c++/detail/auto_array_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/auto_array_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/auto_array_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,302 @@
+// 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);
+}

Added: vendor/atf/dist/atf-c++/detail/env.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/env.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/env.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,75 @@
+// 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/env.hpp"
+
+extern "C" {
+#include "atf-c/detail/env.h"
+#include "atf-c/error.h"
+}
+
+#include "atf-c++/detail/exceptions.hpp"
+#include "atf-c++/detail/sanity.hpp"
+
+namespace impl = atf::env;
+#define IMPL_NAME "atf::env"
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+std::string
+impl::get(const std::string& name)
+{
+    return atf_env_get(name.c_str());
+}
+
+std::string
+impl::get(const std::string& name, const std::string& default_value)
+{
+    return atf_env_get_with_default(name.c_str(), default_value.c_str());
+}
+
+bool
+impl::has(const std::string& name)
+{
+    return atf_env_has(name.c_str());
+}
+
+void
+impl::set(const std::string& name, const std::string& val)
+{
+    atf_error_t err = atf_env_set(name.c_str(), val.c_str());
+    if (atf_is_error(err))
+        throw_atf_error(err);
+}
+
+void
+impl::unset(const std::string& name)
+{
+    atf_error_t err = atf_env_unset(name.c_str());
+    if (atf_is_error(err))
+        throw_atf_error(err);
+}

Added: vendor/atf/dist/atf-c++/detail/env.hpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/env.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/env.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,85 @@
+// 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_ENV_HPP)
+#define ATF_CXX_DETAIL_ENV_HPP
+
+#include <string>
+
+namespace atf {
+namespace env {
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+//!
+//! \brief Returns the value of an environment variable.
+//!
+//! Returns the value of the specified environment variable.  The variable
+//! must be defined.
+//!
+std::string get(const std::string&);
+
+//!
+//! \brief Returns the value of an environment variable with a default.
+//!
+std::string get(const std::string&, const std::string&);
+
+//!
+//! \brief Checks if the environment has a variable.
+//!
+//! Checks if the environment has a given variable.
+//!
+bool has(const std::string&);
+
+//!
+//! \brief Sets an environment variable to a given value.
+//!
+//! Sets the specified environment variable to the given value.  Note that
+//! variables set to the empty string are different to undefined ones.
+//!
+//! Be aware that this alters the program's global status, which in general
+//! is a bad thing to do due to the side-effects it may have.  There are
+//! some legitimate usages for this function, though.
+//!
+void set(const std::string&, const std::string&);
+
+//!
+//! \brief Unsets an environment variable.
+//!
+//! Unsets the specified environment variable  Note that undefined
+//! variables are different to those defined but set to an empty value.
+//!
+//! Be aware that this alters the program's global status, which in general
+//! is a bad thing to do due to the side-effects it may have.  There are
+//! some legitimate usages for this function, though.
+//!
+void unset(const std::string&);
+
+} // namespace env
+} // namespace atf
+
+#endif // !defined(ATF_CXX_DETAIL_ENV_HPP)

Added: vendor/atf/dist/atf-c++/detail/env_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/env_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/env_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,101 @@
+// 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/env.hpp"
+
+#include <atf-c++.hpp>
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(has_get);
+ATF_TEST_CASE_HEAD(has_get)
+{
+    set_md_var("descr", "Tests the has and get functions");
+}
+ATF_TEST_CASE_BODY(has_get)
+{
+    ATF_REQUIRE(atf::env::has("PATH"));
+    ATF_REQUIRE(!atf::env::get("PATH").empty());
+
+    ATF_REQUIRE(!atf::env::has("_UNDEFINED_VARIABLE_"));
+}
+
+ATF_TEST_CASE(get_with_default);
+ATF_TEST_CASE_HEAD(get_with_default)
+{
+    set_md_var("descr", "Tests the get function with a default value");
+}
+ATF_TEST_CASE_BODY(get_with_default)
+{
+    ATF_REQUIRE(atf::env::has("PATH"));
+    ATF_REQUIRE(atf::env::get("PATH", "default value") != "default value");
+
+    ATF_REQUIRE_EQ(atf::env::get("_UNDEFINED_VARIABLE_", "foo bar"), "foo bar");
+}
+
+ATF_TEST_CASE(set);
+ATF_TEST_CASE_HEAD(set)
+{
+    set_md_var("descr", "Tests the set function");
+}
+ATF_TEST_CASE_BODY(set)
+{
+    ATF_REQUIRE(atf::env::has("PATH"));
+    const std::string& oldval = atf::env::get("PATH");
+    atf::env::set("PATH", "foo-bar");
+    ATF_REQUIRE(atf::env::get("PATH") != oldval);
+    ATF_REQUIRE_EQ(atf::env::get("PATH"), "foo-bar");
+
+    ATF_REQUIRE(!atf::env::has("_UNDEFINED_VARIABLE_"));
+    atf::env::set("_UNDEFINED_VARIABLE_", "foo2-bar2");
+    ATF_REQUIRE_EQ(atf::env::get("_UNDEFINED_VARIABLE_"), "foo2-bar2");
+}
+
+ATF_TEST_CASE(unset);
+ATF_TEST_CASE_HEAD(unset)
+{
+    set_md_var("descr", "Tests the unset function");
+}
+ATF_TEST_CASE_BODY(unset)
+{
+    ATF_REQUIRE(atf::env::has("PATH"));
+    atf::env::unset("PATH");
+    ATF_REQUIRE(!atf::env::has("PATH"));
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    // Add the test cases for the free functions.
+    ATF_ADD_TEST_CASE(tcs, has_get);
+    ATF_ADD_TEST_CASE(tcs, get_with_default);
+    ATF_ADD_TEST_CASE(tcs, set);
+    ATF_ADD_TEST_CASE(tcs, unset);
+}

Added: vendor/atf/dist/atf-c++/detail/exceptions.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/exceptions.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/exceptions.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,154 @@
+// 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/exceptions.hpp"
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <cstdarg>
+#include <cstdio>
+#include <cstring>
+#include <new>
+
+extern "C" {
+#include "atf-c/error.h"
+}
+
+#include "atf-c++/detail/sanity.hpp"
+
+// ------------------------------------------------------------------------
+// The "system_error" type.
+// ------------------------------------------------------------------------
+
+atf::system_error::system_error(const std::string& who,
+                                const std::string& message,
+                                int sys_err) :
+    std::runtime_error(who + ": " + message),
+    m_sys_err(sys_err)
+{
+}
+
+atf::system_error::~system_error(void)
+    throw()
+{
+}
+
+int
+atf::system_error::code(void)
+    const
+    throw()
+{
+    return m_sys_err;
+}
+
+const char*
+atf::system_error::what(void)
+    const
+    throw()
+{
+    try {
+        if (m_message.length() == 0) {
+            m_message = std::string(std::runtime_error::what()) + ": ";
+            m_message += ::strerror(m_sys_err);
+        }
+
+        return m_message.c_str();
+    } catch (...) {
+        return "Unable to format system_error message";
+    }
+}
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+static
+void
+throw_libc_error(atf_error_t err)
+{
+    PRE(atf_error_is(err, "libc"));
+
+    const int ecode = atf_libc_error_code(err);
+    const std::string msg = atf_libc_error_msg(err);
+    atf_error_free(err);
+    throw atf::system_error("XXX", msg, ecode);
+}
+
+static
+void
+throw_no_memory_error(atf_error_t err)
+{
+    PRE(atf_error_is(err, "no_memory"));
+
+    atf_error_free(err);
+    throw std::bad_alloc();
+}
+
+static
+void
+throw_unknown_error(atf_error_t err)
+{
+    PRE(atf_is_error(err));
+
+    static char buf[4096];
+    atf_error_format(err, buf, sizeof(buf));
+    atf_error_free(err);
+    throw std::runtime_error(buf);
+}
+
+void
+atf::throw_atf_error(atf_error_t err)
+{
+    static struct handler {
+        const char* m_name;
+        void (*m_func)(atf_error_t);
+    } handlers[] = {
+        { "libc", throw_libc_error },
+        { "no_memory", throw_no_memory_error },
+        { NULL, throw_unknown_error },
+    };
+
+    PRE(atf_is_error(err));
+
+    handler* h = handlers;
+    while (h->m_name != NULL) {
+        if (atf_error_is(err, h->m_name)) {
+            h->m_func(err);
+            UNREACHABLE;
+        } else
+            h++;
+    }
+    // XXX: I'm not sure that raising an "unknown" error is a wise thing
+    // to do here.  The C++ binding is supposed to have feature parity
+    // with the C one, so all possible errors raised by the C library
+    // should have their counterpart in the C++ library.  Still, removing
+    // this will require some code auditing that I can't afford at the
+    // moment.
+    INV(h->m_name == NULL && h->m_func != NULL);
+    h->m_func(err);
+    UNREACHABLE;
+}

Added: vendor/atf/dist/atf-c++/detail/exceptions.hpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/exceptions.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/exceptions.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,54 @@
+// 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_EXCEPTIONS_HPP)
+#define ATF_CXX_DETAIL_EXCEPTIONS_HPP
+
+#include <stdexcept>
+#include <string>
+
+extern "C" {
+struct atf_error;
+}
+
+namespace atf {
+
+class system_error : public std::runtime_error {
+    int m_sys_err;
+    mutable std::string m_message;
+
+public:
+    system_error(const std::string&, const std::string&, int);
+    ~system_error(void) throw();
+
+    int code(void) const throw();
+    const char* what(void) const throw();
+};
+
+void throw_atf_error(struct atf_error *);
+
+} // namespace atf
+
+#endif // !defined(ATF_CXX_DETAIL_EXCEPTIONS_HPP)

Added: vendor/atf/dist/atf-c++/detail/exceptions_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/exceptions_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/exceptions_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,145 @@
+// Copyright (c) 2009 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/exceptions.hpp"
+
+extern "C" {
+#include "atf-c/error.h"
+}
+
+#include <cstdio>
+#include <new>
+
+#include <atf-c++.hpp>
+
+#include "atf-c++/detail/sanity.hpp"
+
+// ------------------------------------------------------------------------
+// The "test" error.
+// ------------------------------------------------------------------------
+
+extern "C" {
+
+struct test_error_data {
+    const char* m_msg;
+};
+typedef struct test_error_data test_error_data_t;
+
+static
+void
+test_format(const atf_error_t err, char *buf, size_t buflen)
+{
+    const test_error_data_t* data;
+
+    PRE(atf_error_is(err, "test"));
+
+    data = static_cast< const test_error_data_t * >(atf_error_data(err));
+    snprintf(buf, buflen, "Message: %s", data->m_msg);
+}
+
+static
+atf_error_t
+test_error(const char* msg)
+{
+    atf_error_t err;
+    test_error_data_t data;
+
+    data.m_msg = msg;
+
+    err = atf_error_new("test", &data, sizeof(data), test_format);
+
+    return err;
+}
+
+} // extern
+
+// ------------------------------------------------------------------------
+// Tests cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(throw_atf_error_libc);
+ATF_TEST_CASE_HEAD(throw_atf_error_libc)
+{
+    set_md_var("descr", "Tests the throw_atf_error function when raising "
+               "a libc error");
+}
+ATF_TEST_CASE_BODY(throw_atf_error_libc)
+{
+    try {
+        atf::throw_atf_error(atf_libc_error(1, "System error 1"));
+    } catch (const atf::system_error& e) {
+        ATF_REQUIRE(e.code() == 1);
+        ATF_REQUIRE(std::string(e.what()).find("System error 1") !=
+                  std::string::npos);
+    } catch (const std::exception& e) {
+        ATF_FAIL(std::string("Got unexpected exception: ") + e.what());
+    }
+}
+
+ATF_TEST_CASE(throw_atf_error_no_memory);
+ATF_TEST_CASE_HEAD(throw_atf_error_no_memory)
+{
+    set_md_var("descr", "Tests the throw_atf_error function when raising "
+               "a no_memory error");
+}
+ATF_TEST_CASE_BODY(throw_atf_error_no_memory)
+{
+    try {
+        atf::throw_atf_error(atf_no_memory_error());
+    } catch (const std::bad_alloc&) {
+    } catch (const std::exception& e) {
+        ATF_FAIL(std::string("Got unexpected exception: ") + e.what());
+    }
+}
+
+ATF_TEST_CASE(throw_atf_error_unknown);
+ATF_TEST_CASE_HEAD(throw_atf_error_unknown)
+{
+    set_md_var("descr", "Tests the throw_atf_error function when raising "
+               "an unknown error");
+}
+ATF_TEST_CASE_BODY(throw_atf_error_unknown)
+{
+    try {
+        atf::throw_atf_error(test_error("The message"));
+    } catch (const std::runtime_error& e) {
+        const std::string msg = e.what();
+        ATF_REQUIRE(msg.find("The message") != std::string::npos);
+    } catch (const std::exception& e) {
+        ATF_FAIL(std::string("Got unexpected exception: ") + e.what());
+    }
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    // Add the test cases for the free functions.
+    ATF_ADD_TEST_CASE(tcs, throw_atf_error_libc);
+    ATF_ADD_TEST_CASE(tcs, throw_atf_error_no_memory);
+    ATF_ADD_TEST_CASE(tcs, throw_atf_error_unknown);
+}

Added: vendor/atf/dist/atf-c++/detail/fs.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/fs.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/fs.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,513 @@
+// 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/fs.hpp"
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+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>
+#include <libgen.h>
+#include <unistd.h>
+}
+
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+
+extern "C" {
+#include "atf-c/error.h"
+}
+
+#include "atf-c++/detail/env.hpp"
+#include "atf-c++/detail/exceptions.hpp"
+#include "atf-c++/detail/process.hpp"
+#include "atf-c++/detail/sanity.hpp"
+#include "atf-c++/detail/text.hpp"
+#include "atf-c++/utils.hpp"
+
+namespace impl = atf::fs;
+#define IMPL_NAME "atf::fs"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static bool safe_access(const impl::path&, int, int);
+
+//!
+//! \brief A controlled version of access(2).
+//!
+//! This function reimplements the standard access(2) system call to
+//! safely control its exit status and raise an exception in case of
+//! failure.
+//!
+static
+bool
+safe_access(const impl::path& p, int mode, int experr)
+{
+    bool ok;
+
+    atf_error_t err = atf_fs_eaccess(p.c_path(), mode);
+    if (atf_is_error(err)) {
+        if (atf_error_is(err, "libc")) {
+            if (atf_libc_error_code(err) == experr) {
+                atf_error_free(err);
+                ok = false;
+            } else {
+                atf::throw_atf_error(err);
+                // XXX Silence warning; maybe throw_atf_error should be
+                // an exception and not a function.
+                ok = false;
+            }
+        } else {
+            atf::throw_atf_error(err);
+            // XXX Silence warning; maybe throw_atf_error should be
+            // an exception and not a function.
+            ok = false;
+        }
+    } else
+        ok = true;
+
+    return ok;
+}
+
+// ------------------------------------------------------------------------
+// The "path" class.
+// ------------------------------------------------------------------------
+
+impl::path::path(const std::string& s)
+{
+    atf_error_t err = atf_fs_path_init_fmt(&m_path, "%s", s.c_str());
+    if (atf_is_error(err))
+        throw_atf_error(err);
+}
+
+impl::path::path(const path& p)
+{
+    atf_error_t err = atf_fs_path_copy(&m_path, &p.m_path);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+}
+
+impl::path::path(const atf_fs_path_t *p)
+{
+    atf_error_t err = atf_fs_path_copy(&m_path, p);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+}
+
+impl::path::~path(void)
+{
+    atf_fs_path_fini(&m_path);
+}
+
+const char*
+impl::path::c_str(void)
+    const
+{
+    return atf_fs_path_cstring(&m_path);
+}
+
+const atf_fs_path_t*
+impl::path::c_path(void)
+    const
+{
+    return &m_path;
+}
+
+std::string
+impl::path::str(void)
+    const
+{
+    return c_str();
+}
+
+bool
+impl::path::is_absolute(void)
+    const
+{
+    return atf_fs_path_is_absolute(&m_path);
+}
+
+bool
+impl::path::is_root(void)
+    const
+{
+    return atf_fs_path_is_root(&m_path);
+}
+
+impl::path
+impl::path::branch_path(void)
+    const
+{
+    atf_fs_path_t bp;
+    atf_error_t err;
+
+    err = atf_fs_path_branch_path(&m_path, &bp);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    path p(atf_fs_path_cstring(&bp));
+    atf_fs_path_fini(&bp);
+    return p;
+}
+
+std::string
+impl::path::leaf_name(void)
+    const
+{
+    atf_dynstr_t ln;
+    atf_error_t err;
+
+    err = atf_fs_path_leaf_name(&m_path, &ln);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    std::string s(atf_dynstr_cstring(&ln));
+    atf_dynstr_fini(&ln);
+    return s;
+}
+
+impl::path
+impl::path::to_absolute(void)
+    const
+{
+    atf_fs_path_t pa;
+
+    atf_error_t err = atf_fs_path_to_absolute(&m_path, &pa);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    path p(atf_fs_path_cstring(&pa));
+    atf_fs_path_fini(&pa);
+    return p;
+}
+
+impl::path&
+impl::path::operator=(const path& p)
+{
+    atf_fs_path_t tmp;
+
+    atf_error_t err = atf_fs_path_init_fmt(&tmp, "%s", p.c_str());
+    if (atf_is_error(err))
+        throw_atf_error(err);
+    else {
+        atf_fs_path_fini(&m_path);
+        m_path = tmp;
+    }
+
+    return *this;
+}
+
+bool
+impl::path::operator==(const path& p)
+    const
+{
+    return atf_equal_fs_path_fs_path(&m_path, &p.m_path);
+}
+
+bool
+impl::path::operator!=(const path& p)
+    const
+{
+    return !atf_equal_fs_path_fs_path(&m_path, &p.m_path);
+}
+
+impl::path
+impl::path::operator/(const std::string& p)
+    const
+{
+    path p2 = *this;
+
+    atf_error_t err = atf_fs_path_append_fmt(&p2.m_path, "%s", p.c_str());
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return p2;
+}
+
+impl::path
+impl::path::operator/(const path& p)
+    const
+{
+    path p2 = *this;
+
+    atf_error_t err = atf_fs_path_append_fmt(&p2.m_path, "%s",
+                                             atf_fs_path_cstring(&p.m_path));
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return p2;
+}
+
+bool
+impl::path::operator<(const path& p)
+    const
+{
+    const char *s1 = atf_fs_path_cstring(&m_path);
+    const char *s2 = atf_fs_path_cstring(&p.m_path);
+    return std::strcmp(s1, s2) < 0;
+}
+
+// ------------------------------------------------------------------------
+// The "file_info" class.
+// ------------------------------------------------------------------------
+
+const int impl::file_info::blk_type = atf_fs_stat_blk_type;
+const int impl::file_info::chr_type = atf_fs_stat_chr_type;
+const int impl::file_info::dir_type = atf_fs_stat_dir_type;
+const int impl::file_info::fifo_type = atf_fs_stat_fifo_type;
+const int impl::file_info::lnk_type = atf_fs_stat_lnk_type;
+const int impl::file_info::reg_type = atf_fs_stat_reg_type;
+const int impl::file_info::sock_type = atf_fs_stat_sock_type;
+const int impl::file_info::wht_type = atf_fs_stat_wht_type;
+
+impl::file_info::file_info(const path& p)
+{
+    atf_error_t err;
+
+    err = atf_fs_stat_init(&m_stat, p.c_path());
+    if (atf_is_error(err))
+        throw_atf_error(err);
+}
+
+impl::file_info::file_info(const file_info& fi)
+{
+    atf_fs_stat_copy(&m_stat, &fi.m_stat);
+}
+
+impl::file_info::~file_info(void)
+{
+    atf_fs_stat_fini(&m_stat);
+}
+
+dev_t
+impl::file_info::get_device(void)
+    const
+{
+    return atf_fs_stat_get_device(&m_stat);
+}
+
+ino_t
+impl::file_info::get_inode(void)
+    const
+{
+    return atf_fs_stat_get_inode(&m_stat);
+}
+
+mode_t
+impl::file_info::get_mode(void)
+    const
+{
+    return atf_fs_stat_get_mode(&m_stat);
+}
+
+off_t
+impl::file_info::get_size(void)
+    const
+{
+    return atf_fs_stat_get_size(&m_stat);
+}
+
+int
+impl::file_info::get_type(void)
+    const
+{
+    return atf_fs_stat_get_type(&m_stat);
+}
+
+bool
+impl::file_info::is_owner_readable(void)
+    const
+{
+    return atf_fs_stat_is_owner_readable(&m_stat);
+}
+
+bool
+impl::file_info::is_owner_writable(void)
+    const
+{
+    return atf_fs_stat_is_owner_writable(&m_stat);
+}
+
+bool
+impl::file_info::is_owner_executable(void)
+    const
+{
+    return atf_fs_stat_is_owner_executable(&m_stat);
+}
+
+bool
+impl::file_info::is_group_readable(void)
+    const
+{
+    return atf_fs_stat_is_group_readable(&m_stat);
+}
+
+bool
+impl::file_info::is_group_writable(void)
+    const
+{
+    return atf_fs_stat_is_group_writable(&m_stat);
+}
+
+bool
+impl::file_info::is_group_executable(void)
+    const
+{
+    return atf_fs_stat_is_group_executable(&m_stat);
+}
+
+bool
+impl::file_info::is_other_readable(void)
+    const
+{
+    return atf_fs_stat_is_other_readable(&m_stat);
+}
+
+bool
+impl::file_info::is_other_writable(void)
+    const
+{
+    return atf_fs_stat_is_other_writable(&m_stat);
+}
+
+bool
+impl::file_info::is_other_executable(void)
+    const
+{
+    return atf_fs_stat_is_other_executable(&m_stat);
+}
+
+// ------------------------------------------------------------------------
+// The "directory" class.
+// ------------------------------------------------------------------------
+
+impl::directory::directory(const path& p)
+{
+    DIR* dp = ::opendir(p.c_str());
+    if (dp == NULL)
+        throw system_error(IMPL_NAME "::directory::directory(" +
+                           p.str() + ")", "opendir(3) failed", errno);
+
+    struct dirent* dep;
+    while ((dep = ::readdir(dp)) != NULL) {
+        path entryp = p / dep->d_name;
+        insert(value_type(dep->d_name, file_info(entryp)));
+    }
+
+    if (::closedir(dp) == -1)
+        throw system_error(IMPL_NAME "::directory::directory(" +
+                           p.str() + ")", "closedir(3) failed", errno);
+}
+
+std::set< std::string >
+impl::directory::names(void)
+    const
+{
+    std::set< std::string > ns;
+
+    for (const_iterator iter = begin(); iter != end(); iter++)
+        ns.insert((*iter).first);
+
+    return ns;
+}
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+bool
+impl::exists(const path& p)
+{
+    atf_error_t err;
+    bool b;
+
+    err = atf_fs_exists(p.c_path(), &b);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return b;
+}
+
+bool
+impl::have_prog_in_path(const std::string& prog)
+{
+    PRE(prog.find('/') == std::string::npos);
+
+    // Do not bother to provide a default value for PATH.  If it is not
+    // there something is broken in the user's environment.
+    if (!atf::env::has("PATH"))
+        throw std::runtime_error("PATH not defined in the environment");
+    std::vector< std::string > dirs =
+        atf::text::split(atf::env::get("PATH"), ":");
+
+    bool found = false;
+    for (std::vector< std::string >::const_iterator iter = dirs.begin();
+         !found && iter != dirs.end(); iter++) {
+        const path& dir = path(*iter);
+
+        if (is_executable(dir / prog))
+            found = true;
+    }
+    return found;
+}
+
+bool
+impl::is_executable(const path& p)
+{
+    if (!exists(p))
+        return false;
+    return safe_access(p, atf_fs_access_x, EACCES);
+}
+
+void
+impl::remove(const path& p)
+{
+    if (file_info(p).get_type() == file_info::dir_type)
+        throw atf::system_error(IMPL_NAME "::remove(" + p.str() + ")",
+                                "Is a directory",
+                                EPERM);
+    if (::unlink(p.c_str()) == -1)
+        throw atf::system_error(IMPL_NAME "::remove(" + p.str() + ")",
+                                "unlink(" + p.str() + ") failed",
+                                errno);
+}
+
+void
+impl::rmdir(const path& p)
+{
+    atf_error_t err = atf_fs_rmdir(p.c_path());
+    if (atf_is_error(err))
+        throw_atf_error(err);
+}

Added: vendor/atf/dist/atf-c++/detail/fs.hpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/fs.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/fs.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,387 @@
+// 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_FS_HPP)
+#define ATF_CXX_DETAIL_FS_HPP
+
+extern "C" {
+#include <sys/types.h>
+}
+
+#include <map>
+#include <memory>
+#include <ostream>
+#include <set>
+#include <stdexcept>
+#include <string>
+
+extern "C" {
+#include "atf-c/detail/fs.h"
+}
+
+namespace atf {
+
+namespace io {
+class systembuf;
+} // namespace io
+
+namespace fs {
+
+// ------------------------------------------------------------------------
+// The "path" class.
+// ------------------------------------------------------------------------
+
+//!
+//! \brief A class to represent a path to a file.
+//!
+//! The path class represents the route to a file or directory in the
+//! file system.  All file manipulation operations use this class to
+//! represent their arguments as it takes care of normalizing user-provided
+//! strings and ensures they are valid.
+//!
+//! It is important to note that the file pointed to by a path need not
+//! exist.
+//!
+class path {
+    //!
+    //! \brief Internal representation of a path.
+    //!
+    atf_fs_path_t m_path;
+
+public:
+    //! \brief Constructs a new path from a user-provided string.
+    //!
+    //! This constructor takes a string, either provided by the program's
+    //! code or by the user and constructs a new path object.  The string
+    //! is normalized to not contain multiple delimiters together and to
+    //! remove any trailing one.
+    //!
+    //! The input string cannot be empty.
+    //!
+    explicit path(const std::string&);
+
+    //!
+    //! \brief Copy constructor.
+    //!
+    path(const path&);
+
+    //!
+    //! \brief Copy constructor.
+    //!
+    path(const atf_fs_path_t *);
+
+    //!
+    //! \brief Destructor for the path class.
+    //!
+    ~path(void);
+
+    //!
+    //! \brief Returns a pointer to a C-style string representing this path.
+    //!
+    const char* c_str(void) const;
+
+    //!
+    //! \brief Returns a pointer to the implementation data.
+    //!
+    const atf_fs_path_t* c_path(void) const;
+
+    //!
+    //! \brief Returns a string representing this path.
+    //! XXX Really needed?
+    //!
+    std::string str(void) const;
+
+    //!
+    //! \brief Returns the branch path of this path.
+    //!
+    //! Calculates and returns the branch path of this path.  In other
+    //! words, it returns what the standard ::dirname function would return.
+    //!
+    path branch_path(void) const;
+
+    //!
+    //! \brief Returns the leaf name of this path.
+    //!
+    //! Calculates and returns the leaf name of this path.  In other words,
+    //! it returns what the standard ::basename function would return.
+    //!
+    std::string leaf_name(void) const;
+
+    //!
+    //! \brief Checks whether this path is absolute or not.
+    //!
+    //! Returns a boolean indicating if this is an absolute path or not;
+    //! i.e. if it starts with a slash.
+    //!
+    bool is_absolute(void) const;
+
+    //!
+    //! \brief Checks whether this path points to the root directory or not.
+    //!
+    //! Returns a boolean indicating if this is path points to the root
+    //! directory or not.  The checks made by this are extremely simple (so
+    //! the results cannot always be trusted) but they are enough for our
+    //! modest sanity-checking needs.  I.e. "/../" could return false.
+    //!
+    bool is_root(void) const;
+
+    //!
+    //! \brief Converts the path to be absolute.
+    //!
+    //! \pre The path was not absolute.
+    //!
+    path to_absolute(void) const;
+
+    //!
+    //! \brief Assignment operator.
+    //!
+    path& operator=(const path&);
+
+    //!
+    //! \brief Checks if two paths are equal.
+    //!
+    bool operator==(const path&) const;
+
+    //!
+    //! \brief Checks if two paths are different.
+    //!
+    bool operator!=(const path&) const;
+
+    //!
+    //! \brief Concatenates a path with a string.
+    //!
+    //! Constructs a new path object that is the concatenation of the
+    //! left-hand path with the right-hand string.  The string is normalized
+    //! before the concatenation, and a path delimiter is introduced between
+    //! the two components if needed.
+    //!
+    path operator/(const std::string&) const;
+
+    //!
+    //! \brief Concatenates a path with another path.
+    //!
+    //! Constructs a new path object that is the concatenation of the
+    //! left-hand path with the right-hand one. A path delimiter is
+    //! introduced between the two components if needed.
+    //!
+    path operator/(const path&) const;
+
+    //!
+    //! \brief Checks if a path has to be sorted before another one
+    //!        lexicographically.
+    //!
+    bool operator<(const path&) const;
+};
+
+// ------------------------------------------------------------------------
+// The "file_info" class.
+// ------------------------------------------------------------------------
+
+class directory;
+
+//!
+//! \brief A class that contains information about a file.
+//!
+//! The file_info class holds information about an specific file that
+//! exists in the file system.
+//!
+class file_info {
+    atf_fs_stat_t m_stat;
+
+public:
+    //!
+    //! \brief The file's type.
+    //!
+    static const int blk_type;
+    static const int chr_type;
+    static const int dir_type;
+    static const int fifo_type;
+    static const int lnk_type;
+    static const int reg_type;
+    static const int sock_type;
+    static const int wht_type;
+
+    //!
+    //! \brief Constructs a new file_info based on a given file.
+    //!
+    //! This constructor creates a new file_info object and fills it with
+    //! the data returned by ::stat when run on the given file, which must
+    //! exist.
+    //!
+    explicit file_info(const path&);
+
+    //!
+    //! \brief The copy constructor.
+    //!
+    file_info(const file_info&);
+
+    //!
+    //! \brief The destructor.
+    //!
+    ~file_info(void);
+
+    //!
+    //! \brief Returns the device containing the file.
+    //!
+    dev_t get_device(void) const;
+
+    //!
+    //! \brief Returns the file's inode.
+    //!
+    ino_t get_inode(void) const;
+
+    //!
+    //! \brief Returns the file's permissions.
+    //!
+    mode_t get_mode(void) const;
+
+    //!
+    //! \brief Returns the file's size.
+    //!
+    off_t get_size(void) const;
+
+    //!
+    //! \brief Returns the file's type.
+    //!
+    int get_type(void) const;
+
+    //!
+    //! \brief Returns whether the file is readable by its owner or not.
+    //!
+    bool is_owner_readable(void) const;
+
+    //!
+    //! \brief Returns whether the file is writable by its owner or not.
+    //!
+    bool is_owner_writable(void) const;
+
+    //!
+    //! \brief Returns whether the file is executable by its owner or not.
+    //!
+    bool is_owner_executable(void) const;
+
+    //!
+    //! \brief Returns whether the file is readable by the users belonging
+    //! to its group or not.
+    //!
+    bool is_group_readable(void) const;
+
+    //!
+    //! \brief Returns whether the file is writable the users belonging to
+    //! its group or not.
+    //!
+    bool is_group_writable(void) const;
+
+    //!
+    //! \brief Returns whether the file is executable by the users
+    //! belonging to its group or not.
+    //!
+    bool is_group_executable(void) const;
+
+    //!
+    //! \brief Returns whether the file is readable by people different
+    //! than the owner and those belonging to the group or not.
+    //!
+    bool is_other_readable(void) const;
+
+    //!
+    //! \brief Returns whether the file is write by people different
+    //! than the owner and those belonging to the group or not.
+    //!
+    bool is_other_writable(void) const;
+
+    //!
+    //! \brief Returns whether the file is executable by people different
+    //! than the owner and those belonging to the group or not.
+    //!
+    bool is_other_executable(void) const;
+};
+
+// ------------------------------------------------------------------------
+// The "directory" class.
+// ------------------------------------------------------------------------
+
+//!
+//! \brief A class representing a file system directory.
+//!
+//! The directory class represents a group of files in the file system and
+//! corresponds to exactly one directory.
+//!
+class directory : public std::map< std::string, file_info > {
+public:
+    //!
+    //! \brief Constructs a new directory.
+    //!
+    //! Constructs a new directory object representing the given path.
+    //! The directory must exist at creation time as the contents of the
+    //! class are gathered from it.
+    //!
+    directory(const path&);
+
+    //!
+    //! \brief Returns the file names of the files in the directory.
+    //!
+    //! Returns the leaf names of all files contained in the directory.
+    //! I.e. the keys of the directory map.
+    //!
+    std::set< std::string > names(void) const;
+};
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+//!
+//! \brief Checks if the given path exists.
+//!
+bool exists(const path&);
+
+//!
+//! \brief Looks for the given program in the PATH.
+//!
+//! Given a program name (without slashes) looks for it in the path and
+//! returns its full path name if found, otherwise an empty path.
+//!
+bool have_prog_in_path(const std::string&);
+
+//!
+//! \brief Checks if the given path exists, is accessible and is executable.
+//!
+bool is_executable(const path&);
+
+//!
+//! \brief Removes a given file.
+//!
+void remove(const path&);
+
+//!
+//! \brief Removes an empty directory.
+//!
+void rmdir(const path&);
+
+} // namespace fs
+} // namespace atf
+
+#endif // !defined(ATF_CXX_DETAIL_FS_HPP)

Added: vendor/atf/dist/atf-c++/detail/fs_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/fs_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/fs_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,542 @@
+// 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/fs.hpp"
+
+extern "C" {
+#include <sys/types.h>
+#include <sys/stat.h>
+}
+
+#include <fstream>
+#include <cerrno>
+#include <cstdio>
+
+#include <atf-c++.hpp>
+
+#include "atf-c++/detail/exceptions.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+void
+create_files(void)
+{
+    ::mkdir("files", 0755);
+    ::mkdir("files/dir", 0755);
+
+    std::ofstream os("files/reg");
+    os.close();
+
+    // TODO: Should create all other file types (blk, chr, fifo, lnk, sock)
+    // and test for them... but the underlying file system may not support
+    // most of these.  Specially as we are working on /tmp, which can be
+    // mounted with flags such as "nodev".  See how to deal with this
+    // situation.
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "path" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(path_normalize);
+ATF_TEST_CASE_HEAD(path_normalize)
+{
+    set_md_var("descr", "Tests the path's normalization");
+}
+ATF_TEST_CASE_BODY(path_normalize)
+{
+    using atf::fs::path;
+
+    ATF_REQUIRE_EQ(path(".").str(), ".");
+    ATF_REQUIRE_EQ(path("..").str(), "..");
+
+    ATF_REQUIRE_EQ(path("foo").str(), "foo");
+    ATF_REQUIRE_EQ(path("foo/bar").str(), "foo/bar");
+    ATF_REQUIRE_EQ(path("foo/bar/").str(), "foo/bar");
+
+    ATF_REQUIRE_EQ(path("/foo").str(), "/foo");
+    ATF_REQUIRE_EQ(path("/foo/bar").str(), "/foo/bar");
+    ATF_REQUIRE_EQ(path("/foo/bar/").str(), "/foo/bar");
+
+    ATF_REQUIRE_EQ(path("///foo").str(), "/foo");
+    ATF_REQUIRE_EQ(path("///foo///bar").str(), "/foo/bar");
+    ATF_REQUIRE_EQ(path("///foo///bar///").str(), "/foo/bar");
+}
+
+ATF_TEST_CASE(path_is_absolute);
+ATF_TEST_CASE_HEAD(path_is_absolute)
+{
+    set_md_var("descr", "Tests the path::is_absolute function");
+}
+ATF_TEST_CASE_BODY(path_is_absolute)
+{
+    using atf::fs::path;
+
+    ATF_REQUIRE( path("/").is_absolute());
+    ATF_REQUIRE( path("////").is_absolute());
+    ATF_REQUIRE( path("////a").is_absolute());
+    ATF_REQUIRE( path("//a//").is_absolute());
+    ATF_REQUIRE(!path("a////").is_absolute());
+    ATF_REQUIRE(!path("../foo").is_absolute());
+}
+
+ATF_TEST_CASE(path_is_root);
+ATF_TEST_CASE_HEAD(path_is_root)
+{
+    set_md_var("descr", "Tests the path::is_root function");
+}
+ATF_TEST_CASE_BODY(path_is_root)
+{
+    using atf::fs::path;
+
+    ATF_REQUIRE( path("/").is_root());
+    ATF_REQUIRE( path("////").is_root());
+    ATF_REQUIRE(!path("////a").is_root());
+    ATF_REQUIRE(!path("//a//").is_root());
+    ATF_REQUIRE(!path("a////").is_root());
+    ATF_REQUIRE(!path("../foo").is_root());
+}
+
+ATF_TEST_CASE(path_branch_path);
+ATF_TEST_CASE_HEAD(path_branch_path)
+{
+    set_md_var("descr", "Tests the path::branch_path function");
+}
+ATF_TEST_CASE_BODY(path_branch_path)
+{
+    using atf::fs::path;
+
+    ATF_REQUIRE_EQ(path(".").branch_path().str(), ".");
+    ATF_REQUIRE_EQ(path("foo").branch_path().str(), ".");
+    ATF_REQUIRE_EQ(path("foo/bar").branch_path().str(), "foo");
+    ATF_REQUIRE_EQ(path("/foo").branch_path().str(), "/");
+    ATF_REQUIRE_EQ(path("/foo/bar").branch_path().str(), "/foo");
+}
+
+ATF_TEST_CASE(path_leaf_name);
+ATF_TEST_CASE_HEAD(path_leaf_name)
+{
+    set_md_var("descr", "Tests the path::leaf_name function");
+}
+ATF_TEST_CASE_BODY(path_leaf_name)
+{
+    using atf::fs::path;
+
+    ATF_REQUIRE_EQ(path(".").leaf_name(), ".");
+    ATF_REQUIRE_EQ(path("foo").leaf_name(), "foo");
+    ATF_REQUIRE_EQ(path("foo/bar").leaf_name(), "bar");
+    ATF_REQUIRE_EQ(path("/foo").leaf_name(), "foo");
+    ATF_REQUIRE_EQ(path("/foo/bar").leaf_name(), "bar");
+}
+
+ATF_TEST_CASE(path_compare_equal);
+ATF_TEST_CASE_HEAD(path_compare_equal)
+{
+    set_md_var("descr", "Tests the comparison for equality between paths");
+}
+ATF_TEST_CASE_BODY(path_compare_equal)
+{
+    using atf::fs::path;
+
+    ATF_REQUIRE(path("/") == path("///"));
+    ATF_REQUIRE(path("/a") == path("///a"));
+    ATF_REQUIRE(path("/a") == path("///a///"));
+
+    ATF_REQUIRE(path("a/b/c") == path("a//b//c"));
+    ATF_REQUIRE(path("a/b/c") == path("a//b//c///"));
+}
+
+ATF_TEST_CASE(path_compare_different);
+ATF_TEST_CASE_HEAD(path_compare_different)
+{
+    set_md_var("descr", "Tests the comparison for difference between paths");
+}
+ATF_TEST_CASE_BODY(path_compare_different)
+{
+    using atf::fs::path;
+
+    ATF_REQUIRE(path("/") != path("//a/"));
+    ATF_REQUIRE(path("/a") != path("a///"));
+
+    ATF_REQUIRE(path("a/b/c") != path("a/b"));
+    ATF_REQUIRE(path("a/b/c") != path("a//b"));
+    ATF_REQUIRE(path("a/b/c") != path("/a/b/c"));
+    ATF_REQUIRE(path("a/b/c") != path("/a//b//c"));
+}
+
+ATF_TEST_CASE(path_concat);
+ATF_TEST_CASE_HEAD(path_concat)
+{
+    set_md_var("descr", "Tests the concatenation of multiple paths");
+}
+ATF_TEST_CASE_BODY(path_concat)
+{
+    using atf::fs::path;
+
+    ATF_REQUIRE_EQ((path("foo") / "bar").str(), "foo/bar");
+    ATF_REQUIRE_EQ((path("foo/") / "/bar").str(), "foo/bar");
+    ATF_REQUIRE_EQ((path("foo/") / "/bar/baz").str(), "foo/bar/baz");
+    ATF_REQUIRE_EQ((path("foo/") / "///bar///baz").str(), "foo/bar/baz");
+}
+
+ATF_TEST_CASE(path_to_absolute);
+ATF_TEST_CASE_HEAD(path_to_absolute)
+{
+    set_md_var("descr", "Tests the conversion of a relative path to an "
+               "absolute one");
+}
+ATF_TEST_CASE_BODY(path_to_absolute)
+{
+    using atf::fs::file_info;
+    using atf::fs::path;
+
+    create_files();
+
+    {
+        const path p(".");
+        path pa = p.to_absolute();
+        ATF_REQUIRE(pa.is_absolute());
+
+        file_info fi(p);
+        file_info fia(pa);
+        ATF_REQUIRE_EQ(fi.get_device(), fia.get_device());
+        ATF_REQUIRE_EQ(fi.get_inode(), fia.get_inode());
+    }
+
+    {
+        const path p("files/reg");
+        path pa = p.to_absolute();
+        ATF_REQUIRE(pa.is_absolute());
+
+        file_info fi(p);
+        file_info fia(pa);
+        ATF_REQUIRE_EQ(fi.get_device(), fia.get_device());
+        ATF_REQUIRE_EQ(fi.get_inode(), fia.get_inode());
+    }
+}
+
+ATF_TEST_CASE(path_op_less);
+ATF_TEST_CASE_HEAD(path_op_less)
+{
+    set_md_var("descr", "Tests that the path's less-than operator works");
+}
+ATF_TEST_CASE_BODY(path_op_less)
+{
+    using atf::fs::path;
+
+    create_files();
+
+    ATF_REQUIRE(!(path("aaa") < path("aaa")));
+
+    ATF_REQUIRE(  path("aab") < path("abc"));
+    ATF_REQUIRE(!(path("abc") < path("aab")));
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "directory" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(directory_read);
+ATF_TEST_CASE_HEAD(directory_read)
+{
+    set_md_var("descr", "Tests the directory class creation, which reads "
+               "the contents of a directory");
+}
+ATF_TEST_CASE_BODY(directory_read)
+{
+    using atf::fs::directory;
+    using atf::fs::path;
+
+    create_files();
+
+    directory d(path("files"));
+    ATF_REQUIRE_EQ(d.size(), 4);
+    ATF_REQUIRE(d.find(".") != d.end());
+    ATF_REQUIRE(d.find("..") != d.end());
+    ATF_REQUIRE(d.find("dir") != d.end());
+    ATF_REQUIRE(d.find("reg") != d.end());
+}
+
+ATF_TEST_CASE(directory_file_info);
+ATF_TEST_CASE_HEAD(directory_file_info)
+{
+    set_md_var("descr", "Tests that the file_info objects attached to the "
+               "directory are valid");
+}
+ATF_TEST_CASE_BODY(directory_file_info)
+{
+    using atf::fs::directory;
+    using atf::fs::file_info;
+    using atf::fs::path;
+
+    create_files();
+
+    directory d(path("files"));
+
+    {
+        directory::const_iterator iter = d.find("dir");
+        ATF_REQUIRE(iter != d.end());
+        const file_info& fi = (*iter).second;
+        ATF_REQUIRE(fi.get_type() == file_info::dir_type);
+    }
+
+    {
+        directory::const_iterator iter = d.find("reg");
+        ATF_REQUIRE(iter != d.end());
+        const file_info& fi = (*iter).second;
+        ATF_REQUIRE(fi.get_type() == file_info::reg_type);
+    }
+}
+
+ATF_TEST_CASE(directory_names);
+ATF_TEST_CASE_HEAD(directory_names)
+{
+    set_md_var("descr", "Tests the directory's names method");
+}
+ATF_TEST_CASE_BODY(directory_names)
+{
+    using atf::fs::directory;
+    using atf::fs::path;
+
+    create_files();
+
+    directory d(path("files"));
+    std::set< std::string > ns = d.names();
+    ATF_REQUIRE_EQ(ns.size(), 4);
+    ATF_REQUIRE(ns.find(".") != ns.end());
+    ATF_REQUIRE(ns.find("..") != ns.end());
+    ATF_REQUIRE(ns.find("dir") != ns.end());
+    ATF_REQUIRE(ns.find("reg") != ns.end());
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the "file_info" class.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(file_info_stat);
+ATF_TEST_CASE_HEAD(file_info_stat)
+{
+    set_md_var("descr", "Tests the file_info creation and its basic contents");
+}
+ATF_TEST_CASE_BODY(file_info_stat)
+{
+    using atf::fs::file_info;
+    using atf::fs::path;
+
+    create_files();
+
+    {
+        path p("files/dir");
+        file_info fi(p);
+        ATF_REQUIRE(fi.get_type() == file_info::dir_type);
+    }
+
+    {
+        path p("files/reg");
+        file_info fi(p);
+        ATF_REQUIRE(fi.get_type() == file_info::reg_type);
+    }
+}
+
+ATF_TEST_CASE(file_info_perms);
+ATF_TEST_CASE_HEAD(file_info_perms)
+{
+    set_md_var("descr", "Tests the file_info methods to get the file's "
+               "permissions");
+}
+ATF_TEST_CASE_BODY(file_info_perms)
+{
+    using atf::fs::file_info;
+    using atf::fs::path;
+
+    path p("file");
+
+    std::ofstream os(p.c_str());
+    os.close();
+
+#define perms(ur, uw, ux, gr, gw, gx, othr, othw, othx) \
+    { \
+        file_info fi(p); \
+        ATF_REQUIRE(fi.is_owner_readable() == ur); \
+        ATF_REQUIRE(fi.is_owner_writable() == uw); \
+        ATF_REQUIRE(fi.is_owner_executable() == ux); \
+        ATF_REQUIRE(fi.is_group_readable() == gr); \
+        ATF_REQUIRE(fi.is_group_writable() == gw); \
+        ATF_REQUIRE(fi.is_group_executable() == gx); \
+        ATF_REQUIRE(fi.is_other_readable() == othr); \
+        ATF_REQUIRE(fi.is_other_writable() == othw); \
+        ATF_REQUIRE(fi.is_other_executable() == othx); \
+    }
+
+    ::chmod(p.c_str(), 0000);
+    perms(false, false, false, false, false, false, false, false, false);
+
+    ::chmod(p.c_str(), 0001);
+    perms(false, false, false, false, false, false, false, false, true);
+
+    ::chmod(p.c_str(), 0010);
+    perms(false, false, false, false, false, true, false, false, false);
+
+    ::chmod(p.c_str(), 0100);
+    perms(false, false, true, false, false, false, false, false, false);
+
+    ::chmod(p.c_str(), 0002);
+    perms(false, false, false, false, false, false, false, true, false);
+
+    ::chmod(p.c_str(), 0020);
+    perms(false, false, false, false, true, false, false, false, false);
+
+    ::chmod(p.c_str(), 0200);
+    perms(false, true, false, false, false, false, false, false, false);
+
+    ::chmod(p.c_str(), 0004);
+    perms(false, false, false, false, false, false, true, false, false);
+
+    ::chmod(p.c_str(), 0040);
+    perms(false, false, false, true, false, false, false, false, false);
+
+    ::chmod(p.c_str(), 0400);
+    perms(true, false, false, false, false, false, false, false, false);
+
+    ::chmod(p.c_str(), 0644);
+    perms(true, true, false, true, false, false, true, false, false);
+
+    ::chmod(p.c_str(), 0755);
+    perms(true, true, true, true, false, true, true, false, true);
+
+    ::chmod(p.c_str(), 0777);
+    perms(true, true, true, true, true, true, true, true, true);
+
+#undef perms
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(exists);
+ATF_TEST_CASE_HEAD(exists)
+{
+    set_md_var("descr", "Tests the exists function");
+}
+ATF_TEST_CASE_BODY(exists)
+{
+    using atf::fs::exists;
+    using atf::fs::path;
+
+    create_files();
+
+    ATF_REQUIRE( exists(path("files")));
+    ATF_REQUIRE(!exists(path("file")));
+    ATF_REQUIRE(!exists(path("files2")));
+
+    ATF_REQUIRE( exists(path("files/.")));
+    ATF_REQUIRE( exists(path("files/..")));
+    ATF_REQUIRE( exists(path("files/dir")));
+    ATF_REQUIRE( exists(path("files/reg")));
+    ATF_REQUIRE(!exists(path("files/foo")));
+}
+
+ATF_TEST_CASE(is_executable);
+ATF_TEST_CASE_HEAD(is_executable)
+{
+    set_md_var("descr", "Tests the is_executable function");
+}
+ATF_TEST_CASE_BODY(is_executable)
+{
+    using atf::fs::is_executable;
+    using atf::fs::path;
+
+    create_files();
+
+    ATF_REQUIRE( is_executable(path("files")));
+    ATF_REQUIRE( is_executable(path("files/.")));
+    ATF_REQUIRE( is_executable(path("files/..")));
+    ATF_REQUIRE( is_executable(path("files/dir")));
+
+    ATF_REQUIRE(!is_executable(path("non-existent")));
+
+    ATF_REQUIRE(!is_executable(path("files/reg")));
+    ATF_REQUIRE(::chmod("files/reg", 0755) != -1);
+    ATF_REQUIRE( is_executable(path("files/reg")));
+}
+
+ATF_TEST_CASE(remove);
+ATF_TEST_CASE_HEAD(remove)
+{
+    set_md_var("descr", "Tests the remove function");
+}
+ATF_TEST_CASE_BODY(remove)
+{
+    using atf::fs::exists;
+    using atf::fs::path;
+    using atf::fs::remove;
+
+    create_files();
+
+    ATF_REQUIRE( exists(path("files/reg")));
+    remove(path("files/reg"));
+    ATF_REQUIRE(!exists(path("files/reg")));
+
+    ATF_REQUIRE( exists(path("files/dir")));
+    ATF_REQUIRE_THROW(atf::system_error, remove(path("files/dir")));
+    ATF_REQUIRE( exists(path("files/dir")));
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    // Add the tests for the "path" class.
+    ATF_ADD_TEST_CASE(tcs, path_normalize);
+    ATF_ADD_TEST_CASE(tcs, path_is_absolute);
+    ATF_ADD_TEST_CASE(tcs, path_is_root);
+    ATF_ADD_TEST_CASE(tcs, path_branch_path);
+    ATF_ADD_TEST_CASE(tcs, path_leaf_name);
+    ATF_ADD_TEST_CASE(tcs, path_compare_equal);
+    ATF_ADD_TEST_CASE(tcs, path_compare_different);
+    ATF_ADD_TEST_CASE(tcs, path_concat);
+    ATF_ADD_TEST_CASE(tcs, path_to_absolute);
+    ATF_ADD_TEST_CASE(tcs, path_op_less);
+
+    // Add the tests for the "file_info" class.
+    ATF_ADD_TEST_CASE(tcs, file_info_stat);
+    ATF_ADD_TEST_CASE(tcs, file_info_perms);
+
+    // Add the tests for the "directory" class.
+    ATF_ADD_TEST_CASE(tcs, directory_read);
+    ATF_ADD_TEST_CASE(tcs, directory_names);
+    ATF_ADD_TEST_CASE(tcs, directory_file_info);
+
+    // Add the tests for the free functions.
+    ATF_ADD_TEST_CASE(tcs, exists);
+    ATF_ADD_TEST_CASE(tcs, is_executable);
+    ATF_ADD_TEST_CASE(tcs, remove);
+}

Added: vendor/atf/dist/atf-c++/detail/process.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/process.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/process.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,346 @@
+// Copyright (c) 2008 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/process.hpp"
+
+extern "C" {
+#include <signal.h>
+
+#include "atf-c/detail/process.h"
+#include "atf-c/error.h"
+}
+
+#include <iostream>
+
+#include "atf-c++/detail/exceptions.hpp"
+#include "atf-c++/detail/sanity.hpp"
+
+namespace detail = atf::process::detail;
+namespace impl = atf::process;
+#define IMPL_NAME "atf::process"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+template< class C >
+atf::auto_array< const char* >
+collection_to_argv(const C& c)
+{
+    atf::auto_array< const char* > argv(new const char*[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++;
+    }
+    INV(pos == c.size());
+    argv[pos] = NULL;
+
+    return argv;
+}
+
+template< class C >
+C
+argv_to_collection(const char* const* argv)
+{
+    C c;
+
+    for (const char* const* iter = argv; *iter != NULL; iter++)
+        c.push_back(std::string(*iter));
+
+    return c;
+}
+
+// ------------------------------------------------------------------------
+// The "argv_array" type.
+// ------------------------------------------------------------------------
+
+impl::argv_array::argv_array(void) :
+    m_exec_argv(collection_to_argv(m_args))
+{
+}
+
+impl::argv_array::argv_array(const char* arg1, ...)
+{
+    m_args.push_back(arg1);
+
+    {
+        va_list ap;
+        const char* nextarg;
+
+        va_start(ap, arg1);
+        while ((nextarg = va_arg(ap, const char*)) != NULL)
+            m_args.push_back(nextarg);
+        va_end(ap);
+    }
+
+    ctor_init_exec_argv();
+}
+
+impl::argv_array::argv_array(const char* const* ca) :
+    m_args(argv_to_collection< args_vector >(ca)),
+    m_exec_argv(collection_to_argv(m_args))
+{
+}
+
+impl::argv_array::argv_array(const argv_array& a) :
+    m_args(a.m_args),
+    m_exec_argv(collection_to_argv(m_args))
+{
+}
+
+void
+impl::argv_array::ctor_init_exec_argv(void)
+{
+    m_exec_argv = collection_to_argv(m_args);
+}
+
+const char* const*
+impl::argv_array::exec_argv(void)
+    const
+{
+    return m_exec_argv.get();
+}
+
+impl::argv_array::size_type
+impl::argv_array::size(void)
+    const
+{
+    return m_args.size();
+}
+
+const char*
+impl::argv_array::operator[](int idx)
+    const
+{
+    return m_args[idx].c_str();
+}
+
+impl::argv_array::const_iterator
+impl::argv_array::begin(void)
+    const
+{
+    return m_args.begin();
+}
+
+impl::argv_array::const_iterator
+impl::argv_array::end(void)
+    const
+{
+    return m_args.end();
+}
+
+impl::argv_array&
+impl::argv_array::operator=(const argv_array& a)
+{
+    if (this != &a) {
+        m_args = a.m_args;
+        m_exec_argv = collection_to_argv(m_args);
+    }
+    return *this;
+}
+
+// ------------------------------------------------------------------------
+// The "stream" types.
+// ------------------------------------------------------------------------
+
+impl::basic_stream::basic_stream(void) :
+    m_inited(false)
+{
+}
+
+impl::basic_stream::~basic_stream(void)
+{
+    if (m_inited)
+        atf_process_stream_fini(&m_sb);
+}
+
+const atf_process_stream_t*
+impl::basic_stream::get_sb(void)
+    const
+{
+    INV(m_inited);
+    return &m_sb;
+}
+
+impl::stream_capture::stream_capture(void)
+{
+    atf_error_t err = atf_process_stream_init_capture(&m_sb);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+    m_inited = true;
+}
+
+impl::stream_connect::stream_connect(const int src_fd, const int tgt_fd)
+{
+    atf_error_t err = atf_process_stream_init_connect(&m_sb, src_fd, tgt_fd);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+    m_inited = true;
+}
+
+impl::stream_inherit::stream_inherit(void)
+{
+    atf_error_t err = atf_process_stream_init_inherit(&m_sb);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+    m_inited = true;
+}
+
+impl::stream_redirect_fd::stream_redirect_fd(const int fd)
+{
+    atf_error_t err = atf_process_stream_init_redirect_fd(&m_sb, fd);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+    m_inited = true;
+}
+
+impl::stream_redirect_path::stream_redirect_path(const fs::path& p)
+{
+    atf_error_t err = atf_process_stream_init_redirect_path(&m_sb, p.c_path());
+    if (atf_is_error(err))
+        throw_atf_error(err);
+    m_inited = true;
+}
+
+// ------------------------------------------------------------------------
+// The "status" type.
+// ------------------------------------------------------------------------
+
+impl::status::status(atf_process_status_t& s) :
+    m_status(s)
+{
+}
+
+impl::status::~status(void)
+{
+    atf_process_status_fini(&m_status);
+}
+
+bool
+impl::status::exited(void)
+    const
+{
+    return atf_process_status_exited(&m_status);
+}
+
+int
+impl::status::exitstatus(void)
+    const
+{
+    return atf_process_status_exitstatus(&m_status);
+}
+
+bool
+impl::status::signaled(void)
+    const
+{
+    return atf_process_status_signaled(&m_status);
+}
+
+int
+impl::status::termsig(void)
+    const
+{
+    return atf_process_status_termsig(&m_status);
+}
+
+bool
+impl::status::coredump(void)
+    const
+{
+    return atf_process_status_coredump(&m_status);
+}
+
+// ------------------------------------------------------------------------
+// The "child" type.
+// ------------------------------------------------------------------------
+
+impl::child::child(atf_process_child_t& c) :
+    m_child(c),
+    m_waited(false)
+{
+}
+
+impl::child::~child(void)
+{
+    if (!m_waited) {
+        ::kill(atf_process_child_pid(&m_child), SIGTERM);
+
+        atf_process_status_t s;
+        atf_error_t err = atf_process_child_wait(&m_child, &s);
+        INV(!atf_is_error(err));
+        atf_process_status_fini(&s);
+    }
+}
+
+impl::status
+impl::child::wait(void)
+{
+    atf_process_status_t s;
+
+    atf_error_t err = atf_process_child_wait(&m_child, &s);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    m_waited = true;
+    return status(s);
+}
+
+pid_t
+impl::child::pid(void)
+    const
+{
+    return atf_process_child_pid(&m_child);
+}
+
+int
+impl::child::stdout_fd(void)
+{
+    return atf_process_child_stdout(&m_child);
+}
+
+int
+impl::child::stderr_fd(void)
+{
+    return atf_process_child_stderr(&m_child);
+}
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+void
+detail::flush_streams(void)
+{
+    // TODO: This should only be executed when inheriting the stdout or
+    // stderr file descriptors.  However, the flushing is specific to the
+    // iostreams, so we cannot do it from the C library where all the process
+    // logic is performed.  Come up with a better design.
+    std::cout.flush();
+    std::cerr.flush();
+}

Added: vendor/atf/dist/atf-c++/detail/process.hpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/process.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/process.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,274 @@
+// Copyright (c) 2008 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_PROCESS_HPP)
+#define ATF_CXX_DETAIL_PROCESS_HPP
+
+extern "C" {
+#include <sys/types.h>
+
+#include <atf-c/detail/process.h>
+#include <atf-c/error.h>
+}
+
+#include <string>
+#include <vector>
+
+#include <atf-c++/detail/auto_array.hpp>
+#include <atf-c++/detail/exceptions.hpp>
+#include <atf-c++/detail/fs.hpp>
+
+namespace atf {
+namespace process {
+
+class child;
+class status;
+
+// ------------------------------------------------------------------------
+// The "argv_array" type.
+// ------------------------------------------------------------------------
+
+class argv_array {
+    typedef std::vector< std::string > args_vector;
+    args_vector m_args;
+
+    // TODO: This is immutable, so we should be able to use
+    // 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;
+    void ctor_init_exec_argv(void);
+
+public:
+    typedef args_vector::const_iterator const_iterator;
+    typedef args_vector::size_type size_type;
+
+    argv_array(void);
+    argv_array(const char*, ...);
+    explicit argv_array(const char* const*);
+    template< class C > explicit argv_array(const C&);
+    argv_array(const argv_array&);
+
+    const char* const* exec_argv(void) const;
+    size_type size(void) const;
+    const char* operator[](int) const;
+
+    const_iterator begin(void) const;
+    const_iterator end(void) const;
+
+    argv_array& operator=(const argv_array&);
+};
+
+template< class C >
+argv_array::argv_array(const C& c)
+{
+    for (typename C::const_iterator iter = c.begin(); iter != c.end();
+         iter++)
+        m_args.push_back(*iter);
+    ctor_init_exec_argv();
+}
+
+// ------------------------------------------------------------------------
+// The "stream" types.
+// ------------------------------------------------------------------------
+
+class basic_stream {
+protected:
+    atf_process_stream_t m_sb;
+    bool m_inited;
+
+    const atf_process_stream_t* get_sb(void) const;
+
+public:
+    basic_stream(void);
+    ~basic_stream(void);
+};
+
+class stream_capture : basic_stream {
+    // Allow access to the getters.
+    template< class OutStream, class ErrStream > friend
+    child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
+    template< class OutStream, class ErrStream > friend
+    status exec(const atf::fs::path&, const argv_array&,
+                const OutStream&, const ErrStream&, void (*)(void));
+
+public:
+    stream_capture(void);
+};
+
+class stream_connect : basic_stream {
+    // Allow access to the getters.
+    template< class OutStream, class ErrStream > friend
+    child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
+    template< class OutStream, class ErrStream > friend
+    status exec(const atf::fs::path&, const argv_array&,
+                const OutStream&, const ErrStream&, void (*)(void));
+
+public:
+    stream_connect(const int, const int);
+};
+
+class stream_inherit : basic_stream {
+    // Allow access to the getters.
+    template< class OutStream, class ErrStream > friend
+    child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
+    template< class OutStream, class ErrStream > friend
+    status exec(const atf::fs::path&, const argv_array&,
+                const OutStream&, const ErrStream&, void (*)(void));
+
+public:
+    stream_inherit(void);
+};
+
+class stream_redirect_fd : basic_stream {
+    // Allow access to the getters.
+    template< class OutStream, class ErrStream > friend
+    child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
+    template< class OutStream, class ErrStream > friend
+    status exec(const atf::fs::path&, const argv_array&,
+                const OutStream&, const ErrStream&, void (*)(void));
+
+public:
+    stream_redirect_fd(const int);
+};
+
+class stream_redirect_path : basic_stream {
+    // Allow access to the getters.
+    template< class OutStream, class ErrStream > friend
+    child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
+    template< class OutStream, class ErrStream > friend
+    status exec(const atf::fs::path&, const argv_array&,
+                const OutStream&, const ErrStream&, void (*)(void));
+
+public:
+    stream_redirect_path(const fs::path&);
+};
+
+// ------------------------------------------------------------------------
+// The "status" type.
+// ------------------------------------------------------------------------
+
+class status {
+    atf_process_status_t m_status;
+
+    friend class child;
+    template< class OutStream, class ErrStream > friend
+    status exec(const atf::fs::path&, const argv_array&,
+                const OutStream&, const ErrStream&, void (*)(void));
+
+    status(atf_process_status_t&);
+
+public:
+    ~status(void);
+
+    bool exited(void) const;
+    int exitstatus(void) const;
+
+    bool signaled(void) const;
+    int termsig(void) const;
+    bool coredump(void) const;
+};
+
+// ------------------------------------------------------------------------
+// The "child" type.
+// ------------------------------------------------------------------------
+
+class child {
+    atf_process_child_t m_child;
+    bool m_waited;
+
+    template< class OutStream, class ErrStream > friend
+    child fork(void (*)(void*), const OutStream&, const ErrStream&, void*);
+
+    child(atf_process_child_t& c);
+
+public:
+    ~child(void);
+
+    status wait(void);
+
+    pid_t pid(void) const;
+    int stdout_fd(void);
+    int stderr_fd(void);
+};
+
+// ------------------------------------------------------------------------
+// Free functions.
+// ------------------------------------------------------------------------
+
+namespace detail {
+void flush_streams(void);
+} // namespace detail
+
+// TODO: The void* cookie can probably be templatized, thus also allowing
+// const data structures.
+template< class OutStream, class ErrStream >
+child
+fork(void (*start)(void*), const OutStream& outsb,
+     const ErrStream& errsb, void* v)
+{
+    atf_process_child_t c;
+
+    detail::flush_streams();
+    atf_error_t err = atf_process_fork(&c, start, outsb.get_sb(),
+                                       errsb.get_sb(), v);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return child(c);
+}
+
+template< class OutStream, class ErrStream >
+status
+exec(const atf::fs::path& prog, const argv_array& argv,
+     const OutStream& outsb, const ErrStream& errsb,
+     void (*prehook)(void))
+{
+    atf_process_status_t s;
+
+    detail::flush_streams();
+    atf_error_t err = atf_process_exec_array(&s, prog.c_path(),
+                                             argv.exec_argv(),
+                                             outsb.get_sb(),
+                                             errsb.get_sb(),
+                                             prehook);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return status(s);
+}
+
+template< class OutStream, class ErrStream >
+status
+exec(const atf::fs::path& prog, const argv_array& argv,
+     const OutStream& outsb, const ErrStream& errsb)
+{
+    return exec(prog, argv, outsb, errsb, NULL);
+}
+
+} // namespace process
+} // namespace atf
+
+#endif // !defined(ATF_CXX_DETAIL_PROCESS_HPP)

Added: vendor/atf/dist/atf-c++/detail/process_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/process_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/process_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,354 @@
+// Copyright (c) 2008 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/process.hpp"
+
+#include <cstdlib>
+#include <cstring>
+
+#include <atf-c++.hpp>
+
+#include "atf-c++/detail/test_helpers.hpp"
+
+// TODO: Testing the fork function is a huge task and I'm afraid of
+// copy/pasting tons of stuff from the C version.  I'd rather not do that
+// until some code can be shared, which cannot happen until the C++ binding
+// is cleaned by a fair amount.  Instead... just rely (at the moment) on
+// the system tests for the tools using this module.
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+std::size_t
+array_size(const char* const* array)
+{
+    std::size_t size = 0;
+
+    for (const char* const* ptr = array; *ptr != NULL; ptr++)
+        size++;
+
+    return size;
+}
+
+static
+atf::process::status
+exec_process_helpers(const atf::tests::tc& tc, const char* helper_name)
+{
+    using atf::process::exec;
+
+    std::vector< std::string > argv;
+    argv.push_back(get_process_helpers_path(tc, true).leaf_name());
+    argv.push_back(helper_name);
+
+    return exec(get_process_helpers_path(tc, true),
+                atf::process::argv_array(argv),
+                atf::process::stream_inherit(),
+                atf::process::stream_inherit());
+}
+
+// ------------------------------------------------------------------------
+// Tests for the "argv_array" type.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(argv_array_init_carray);
+ATF_TEST_CASE_HEAD(argv_array_init_carray)
+{
+    set_md_var("descr", "Tests that argv_array is correctly constructed "
+               "from a C-style array of strings");
+}
+ATF_TEST_CASE_BODY(argv_array_init_carray)
+{
+    {
+        const char* const carray[] = { NULL };
+        atf::process::argv_array argv(carray);
+
+        ATF_REQUIRE_EQ(argv.size(), 0);
+    }
+
+    {
+        const char* const carray[] = { "arg0", NULL };
+        atf::process::argv_array argv(carray);
+
+        ATF_REQUIRE_EQ(argv.size(), 1);
+        ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0);
+    }
+
+    {
+        const char* const carray[] = { "arg0", "arg1", "arg2", NULL };
+        atf::process::argv_array argv(carray);
+
+        ATF_REQUIRE_EQ(argv.size(), 3);
+        ATF_REQUIRE(std::strcmp(argv[0], carray[0]) == 0);
+        ATF_REQUIRE(std::strcmp(argv[1], carray[1]) == 0);
+        ATF_REQUIRE(std::strcmp(argv[2], carray[2]) == 0);
+    }
+}
+
+ATF_TEST_CASE(argv_array_init_col);
+ATF_TEST_CASE_HEAD(argv_array_init_col)
+{
+    set_md_var("descr", "Tests that argv_array is correctly constructed "
+               "from a string collection");
+}
+ATF_TEST_CASE_BODY(argv_array_init_col)
+{
+    {
+        std::vector< std::string > col;
+        atf::process::argv_array argv(col);
+
+        ATF_REQUIRE_EQ(argv.size(), 0);
+    }
+
+    {
+        std::vector< std::string > col;
+        col.push_back("arg0");
+        atf::process::argv_array argv(col);
+
+        ATF_REQUIRE_EQ(argv.size(), 1);
+        ATF_REQUIRE_EQ(argv[0], col[0]);
+    }
+
+    {
+        std::vector< std::string > col;
+        col.push_back("arg0");
+        col.push_back("arg1");
+        col.push_back("arg2");
+        atf::process::argv_array argv(col);
+
+        ATF_REQUIRE_EQ(argv.size(), 3);
+        ATF_REQUIRE_EQ(argv[0], col[0]);
+        ATF_REQUIRE_EQ(argv[1], col[1]);
+        ATF_REQUIRE_EQ(argv[2], col[2]);
+    }
+}
+
+ATF_TEST_CASE(argv_array_init_empty);
+ATF_TEST_CASE_HEAD(argv_array_init_empty)
+{
+    set_md_var("descr", "Tests that argv_array is correctly constructed "
+               "by the default constructor");
+}
+ATF_TEST_CASE_BODY(argv_array_init_empty)
+{
+    atf::process::argv_array argv;
+
+    ATF_REQUIRE_EQ(argv.size(), 0);
+}
+
+ATF_TEST_CASE(argv_array_init_varargs);
+ATF_TEST_CASE_HEAD(argv_array_init_varargs)
+{
+    set_md_var("descr", "Tests that argv_array is correctly constructed "
+               "from a variable list of arguments");
+}
+ATF_TEST_CASE_BODY(argv_array_init_varargs)
+{
+    {
+        atf::process::argv_array argv("arg0", NULL);
+
+        ATF_REQUIRE_EQ(argv.size(), 1);
+        ATF_REQUIRE_EQ(argv[0], std::string("arg0"));
+    }
+
+    {
+        atf::process::argv_array argv("arg0", "arg1", "arg2", NULL);
+
+        ATF_REQUIRE_EQ(argv.size(), 3);
+        ATF_REQUIRE_EQ(argv[0], std::string("arg0"));
+        ATF_REQUIRE_EQ(argv[1], std::string("arg1"));
+        ATF_REQUIRE_EQ(argv[2], std::string("arg2"));
+    }
+}
+
+ATF_TEST_CASE(argv_array_assign);
+ATF_TEST_CASE_HEAD(argv_array_assign)
+{
+    set_md_var("descr", "Tests that assigning an argv_array works");
+}
+ATF_TEST_CASE_BODY(argv_array_assign)
+{
+    using atf::process::argv_array;
+
+    const char* const carray1[] = { "arg1", NULL };
+    const char* const carray2[] = { "arg1", "arg2", NULL };
+
+    std::auto_ptr< argv_array > argv1(new argv_array(carray1));
+    std::auto_ptr< argv_array > argv2(new argv_array(carray2));
+
+    *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();
+    {
+        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);
+ATF_TEST_CASE_HEAD(argv_array_copy)
+{
+    set_md_var("descr", "Tests that copying an argv_array constructed from "
+               "a C-style array of strings works");
+}
+ATF_TEST_CASE_BODY(argv_array_copy)
+{
+    using atf::process::argv_array;
+
+    const char* const carray[] = { "arg0", NULL };
+
+    std::auto_ptr< argv_array > argv1(new argv_array(carray));
+    std::auto_ptr< argv_array > argv2(new argv_array(*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();
+    {
+        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);
+ATF_TEST_CASE_HEAD(argv_array_exec_argv)
+{
+    set_md_var("descr", "Tests that the exec argv provided by an argv_array "
+               "is correct");
+}
+ATF_TEST_CASE_BODY(argv_array_exec_argv)
+{
+    using atf::process::argv_array;
+
+    {
+        argv_array argv;
+        const char* const* eargv = argv.exec_argv();
+        ATF_REQUIRE_EQ(array_size(eargv), 0);
+        ATF_REQUIRE_EQ(eargv[0], static_cast< const char* >(NULL));
+    }
+
+    {
+        const char* const carray[] = { "arg0", NULL };
+        argv_array argv(carray);
+        const char* const* eargv = argv.exec_argv();
+        ATF_REQUIRE_EQ(array_size(eargv), 1);
+        ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0);
+        ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL));
+    }
+
+    {
+        std::vector< std::string > col;
+        col.push_back("arg0");
+        argv_array argv(col);
+        const char* const* eargv = argv.exec_argv();
+        ATF_REQUIRE_EQ(array_size(eargv), 1);
+        ATF_REQUIRE(std::strcmp(eargv[0], "arg0") == 0);
+        ATF_REQUIRE_EQ(eargv[1], static_cast< const char* >(NULL));
+    }
+}
+
+ATF_TEST_CASE(argv_array_iter);
+ATF_TEST_CASE_HEAD(argv_array_iter)
+{
+    set_md_var("descr", "Tests that an argv_array can be iterated");
+}
+ATF_TEST_CASE_BODY(argv_array_iter)
+{
+    using atf::process::argv_array;
+
+    std::vector< std::string > vector;
+    vector.push_back("arg0");
+    vector.push_back("arg1");
+    vector.push_back("arg2");
+
+    argv_array argv(vector);
+    ATF_REQUIRE_EQ(argv.size(), 3);
+    std::vector< std::string >::size_type pos = 0;
+    for (argv_array::const_iterator iter = argv.begin(); iter != argv.end();
+         iter++) {
+        ATF_REQUIRE_EQ(*iter, vector[pos]);
+        pos++;
+    }
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(exec_failure);
+ATF_TEST_CASE_HEAD(exec_failure)
+{
+    set_md_var("descr", "Tests execing a command that reports failure");
+}
+ATF_TEST_CASE_BODY(exec_failure)
+{
+    const atf::process::status s = exec_process_helpers(*this, "exit-failure");
+    ATF_REQUIRE(s.exited());
+    ATF_REQUIRE_EQ(s.exitstatus(), EXIT_FAILURE);
+}
+
+ATF_TEST_CASE(exec_success);
+ATF_TEST_CASE_HEAD(exec_success)
+{
+    set_md_var("descr", "Tests execing a command that reports success");
+}
+ATF_TEST_CASE_BODY(exec_success)
+{
+    const atf::process::status s = exec_process_helpers(*this, "exit-success");
+    ATF_REQUIRE(s.exited());
+    ATF_REQUIRE_EQ(s.exitstatus(), EXIT_SUCCESS);
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    // Add the test cases for the "argv_array" type.
+    ATF_ADD_TEST_CASE(tcs, argv_array_assign);
+    ATF_ADD_TEST_CASE(tcs, argv_array_copy);
+    ATF_ADD_TEST_CASE(tcs, argv_array_exec_argv);
+    ATF_ADD_TEST_CASE(tcs, argv_array_init_carray);
+    ATF_ADD_TEST_CASE(tcs, argv_array_init_col);
+    ATF_ADD_TEST_CASE(tcs, argv_array_init_empty);
+    ATF_ADD_TEST_CASE(tcs, argv_array_init_varargs);
+    ATF_ADD_TEST_CASE(tcs, argv_array_iter);
+
+    // Add the test cases for the free functions.
+    ATF_ADD_TEST_CASE(tcs, exec_failure);
+    ATF_ADD_TEST_CASE(tcs, exec_success);
+}

Added: vendor/atf/dist/atf-c++/detail/sanity.hpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/sanity.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/sanity.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,33 @@
+// 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_SANITY_HPP)
+#define ATF_CXX_DETAIL_SANITY_HPP
+
+extern "C" {
+#include <atf-c/detail/sanity.h>
+}
+
+#endif // !defined(ATF_CXX_DETAIL_SANITY_HPP)

Added: vendor/atf/dist/atf-c++/detail/test_helpers.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/test_helpers.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/test_helpers.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,100 @@
+// Copyright (c) 2009 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/test_helpers.hpp"
+
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <atf-c++.hpp>
+
+#include "atf-c++/check.hpp"
+#include "atf-c++/detail/env.hpp"
+#include "atf-c++/detail/fs.hpp"
+#include "atf-c++/detail/process.hpp"
+
+// Path to the directory containing the libatf-c tests, used to locate the
+// process_helpers program.  If NULL (the default), the code will use a
+// relative path.  Otherwise, the provided path will be used; this is so
+// that we can locate the helpers binary if the installation uses a
+// different layout than the one we provide (as is the case in FreeBSD).
+#if defined(ATF_C_TESTS_BASE)
+static const char* atf_c_tests_base = ATF_C_TESTS_BASE;
+#else
+static const char* atf_c_tests_base = NULL;
+#endif
+#undef ATF_C_TESTS_BASE
+
+bool
+build_check_cxx_o(const char* sfile)
+{
+    std::vector< std::string > optargs;
+    optargs.push_back("-I" + atf::env::get("ATF_INCLUDEDIR", ATF_INCLUDEDIR));
+    optargs.push_back("-Wall");
+    optargs.push_back("-Werror");
+
+    return atf::check::build_cxx_o(sfile, "test.o",
+                                   atf::process::argv_array(optargs));
+}
+
+bool
+build_check_cxx_o_srcdir(const atf::tests::tc& tc, const char* sfile)
+{
+    const atf::fs::path sfilepath =
+        atf::fs::path(tc.get_config_var("srcdir")) / sfile;
+    return build_check_cxx_o(sfilepath.c_str());
+}
+
+void
+header_check(const char *hdrname)
+{
+    std::ofstream srcfile("test.cpp");
+    ATF_REQUIRE(srcfile);
+    srcfile << "#include <" << hdrname << ">\n";
+    srcfile.close();
+
+    const std::string failmsg = std::string("Header check failed; ") +
+        hdrname + " is not self-contained";
+    if (!build_check_cxx_o("test.cpp"))
+        ATF_FAIL(failmsg);
+}
+
+atf::fs::path
+get_process_helpers_path(const atf::tests::tc& tc, bool is_detail)
+{
+    const char* helper = "detail/process_helpers";
+    if (atf_c_tests_base == NULL) {
+        if (is_detail)
+            return atf::fs::path(tc.get_config_var("srcdir")) /
+                   ".." / ".." / "atf-c" / helper;
+        else
+            return atf::fs::path(tc.get_config_var("srcdir")) /
+                   ".." / "atf-c" / helper;
+    } else {
+        return atf::fs::path(atf_c_tests_base) / helper;
+    }
+}

Added: vendor/atf/dist/atf-c++/detail/test_helpers.hpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/test_helpers.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/test_helpers.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,107 @@
+// Copyright (c) 2009 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_TEST_HELPERS_H)
+#   error "Cannot include test_helpers.hpp more than once."
+#else
+#   define ATF_CXX_DETAIL_TEST_HELPERS_H
+#endif
+
+#include <cstdlib>
+#include <iostream>
+#include <sstream>
+#include <utility>
+
+#include <atf-c++.hpp>
+
+#include <atf-c++/detail/process.hpp>
+
+#define HEADER_TC(name, hdrname) \
+    ATF_TEST_CASE(name); \
+    ATF_TEST_CASE_HEAD(name) \
+    { \
+        set_md_var("descr", "Tests that the " hdrname " file can be " \
+            "included on its own, without any prerequisites"); \
+    } \
+    ATF_TEST_CASE_BODY(name) \
+    { \
+        header_check(hdrname); \
+    }
+
+#define BUILD_TC(name, sfile, descr, failmsg) \
+    ATF_TEST_CASE(name); \
+    ATF_TEST_CASE_HEAD(name) \
+    { \
+        set_md_var("descr", descr); \
+    } \
+    ATF_TEST_CASE_BODY(name) \
+    { \
+        if (!build_check_cxx_o_srcdir(*this, sfile)) \
+            ATF_FAIL(failmsg); \
+    }
+
+namespace atf {
+namespace tests {
+class tc;
+}
+}
+
+void header_check(const char*);
+bool build_check_cxx_o(const char*);
+bool build_check_cxx_o_srcdir(const atf::tests::tc&, const char*);
+atf::fs::path get_process_helpers_path(const atf::tests::tc&, bool);
+
+struct run_h_tc_data {
+    const atf::tests::vars_map& m_config;
+
+    run_h_tc_data(const atf::tests::vars_map& config) :
+        m_config(config) {}
+};
+
+template< class TestCase >
+void
+run_h_tc_child(void* v)
+{
+    run_h_tc_data* data = static_cast< run_h_tc_data* >(v);
+
+    TestCase tc;
+    tc.init(data->m_config);
+    tc.run("result");
+    std::exit(EXIT_SUCCESS);
+}
+
+template< class TestCase >
+void
+run_h_tc(atf::tests::vars_map config = atf::tests::vars_map())
+{
+    run_h_tc_data data(config);
+    atf::process::child c = atf::process::fork(
+        run_h_tc_child< TestCase >,
+        atf::process::stream_redirect_path(atf::fs::path("stdout")),
+        atf::process::stream_redirect_path(atf::fs::path("stderr")),
+        &data);
+    const atf::process::status s = c.wait();
+    ATF_REQUIRE(s.exited());
+}

Added: vendor/atf/dist/atf-c++/detail/text.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/text.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/text.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,156 @@
+// 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/text.hpp"
+
+extern "C" {
+#include <regex.h>
+}
+
+#include <cctype>
+#include <cstring>
+
+extern "C" {
+#include "atf-c/detail/text.h"
+#include "atf-c/error.h"
+}
+
+#include "atf-c++/detail/exceptions.hpp"
+
+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)
+{
+    bool found;
+
+    // Special case: regcomp does not like empty regular expressions.
+    if (regex.empty()) {
+        found = str.empty();
+    } else {
+        ::regex_t preg;
+
+        if (::regcomp(&preg, regex.c_str(), REG_EXTENDED) != 0)
+            throw std::runtime_error("Invalid regular expression '" + regex +
+                                     "'");
+
+        const int res = ::regexec(&preg, str.c_str(), 0, NULL, 0);
+        regfree(&preg);
+        if (res != 0 && res != REG_NOMATCH)
+            throw std::runtime_error("Invalid regular expression " + regex);
+
+        found = res == 0;
+    }
+
+    return found;
+}
+
+std::string
+impl::to_lower(const std::string& str)
+{
+    std::string lc;
+    for (std::string::const_iterator iter = str.begin(); iter != str.end();
+         iter++)
+        lc += std::tolower(*iter);
+    return lc;
+}
+
+std::vector< std::string >
+impl::split(const std::string& str, const std::string& delim)
+{
+    std::vector< std::string > words;
+
+    std::string::size_type pos = 0, newpos = 0;
+    while (pos < str.length() && newpos != std::string::npos) {
+        newpos = str.find(delim, pos);
+        if (newpos != pos)
+            words.push_back(str.substr(pos, newpos - pos));
+        pos = newpos + delim.length();
+    }
+
+    return words;
+}
+
+std::string
+impl::trim(const std::string& str)
+{
+    std::string::size_type pos1 = str.find_first_not_of(" \t");
+    std::string::size_type pos2 = str.find_last_not_of(" \t");
+
+    if (pos1 == std::string::npos && pos2 == std::string::npos)
+        return "";
+    else if (pos1 == std::string::npos)
+        return str.substr(0, str.length() - pos2);
+    else if (pos2 == std::string::npos)
+        return str.substr(pos1);
+    else
+        return str.substr(pos1, pos2 - pos1 + 1);
+}
+
+bool
+impl::to_bool(const std::string& str)
+{
+    bool b;
+
+    atf_error_t err = atf_text_to_bool(str.c_str(), &b);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+
+    return b;
+}
+
+int64_t
+impl::to_bytes(std::string str)
+{
+    if (str.empty())
+        throw std::runtime_error("Empty value");
+
+    const char unit = str[str.length() - 1];
+    int64_t multiplier;
+    switch (unit) {
+    case 'k': case 'K': multiplier = 1 << 10; break;
+    case 'm': case 'M': multiplier = 1 << 20; break;
+    case 'g': case 'G': multiplier = 1 << 30; break;
+    case 't': case 'T': multiplier = int64_t(1) << 40; break;
+    default:
+        if (!std::isdigit(unit))
+            throw std::runtime_error(std::string("Unknown size unit '") + unit
+                                     + "'");
+        multiplier = 1;
+    }
+    if (multiplier != 1)
+        str.erase(str.length() - 1);
+
+    return to_type< int64_t >(str) * multiplier;
+}

Added: vendor/atf/dist/atf-c++/detail/text.hpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/text.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/text.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,149 @@
+// 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_TEXT_HPP)
+#define ATF_CXX_DETAIL_TEXT_HPP
+
+extern "C" {
+#include <stdint.h>
+}
+
+#include <sstream>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
+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
+//! separator.  Empty words are not omitted.
+//!
+template< class T >
+std::string
+join(const T& words, const std::string& separator)
+{
+    std::string str;
+
+    typename T::const_iterator iter = words.begin();
+    bool done = iter == words.end();
+    while (!done) {
+        str += *iter;
+        iter++;
+        if (iter != words.end())
+            str += separator;
+        else
+            done = true;
+    }
+
+    return str;
+}
+
+//!
+//! \brief Checks if the string matches a regular expression.
+//!
+bool match(const std::string&, const std::string&);
+
+//!
+//! \brief Splits a string into words.
+//!
+//! Splits the given string into multiple words, all separated by the
+//! given delimiter.  Multiple occurrences of the same delimiter are
+//! not condensed so that rejoining the words later on using the same
+//! delimiter results in the original string.
+//!
+std::vector< std::string > split(const std::string&, const std::string&);
+
+//!
+//! \brief Removes whitespace from the beginning and end of a string.
+//!
+std::string trim(const std::string&);
+
+//!
+//! \brief Converts a string to a boolean value.
+//!
+bool to_bool(const std::string&);
+
+//!
+//! \brief Converts the given string to a bytes size.
+//!
+int64_t to_bytes(std::string);
+
+//!
+//! \brief Changes the case of a string to lowercase.
+//!
+//! Returns a new string that is a lowercased version of the original
+//! one.
+//!
+std::string to_lower(const std::string&);
+
+//!
+//! \brief Converts the given object to a string.
+//!
+//! Returns a string with the representation of the given object.  There
+//! must exist an operator<< method for that object.
+//!
+template< class T >
+std::string
+to_string(const T& ob)
+{
+    std::ostringstream ss;
+    ss << ob;
+    return ss.str();
+}
+
+//!
+//! \brief Converts the given string to another type.
+//!
+//! Attempts to convert the given string to the requested type.  Throws
+//! an exception if the conversion failed.
+//!
+template< class T >
+T
+to_type(const std::string& str)
+{
+    std::istringstream ss(str);
+    T value;
+    ss >> value;
+    if (!ss.eof() || (ss.eof() && (ss.fail() || ss.bad())))
+        throw std::runtime_error("Cannot convert string to requested type");
+    return value;
+}
+
+} // namespace text
+} // namespace atf
+
+#endif // !defined(ATF_CXX_DETAIL_TEXT_HPP)

Added: vendor/atf/dist/atf-c++/detail/text_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/text_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/text_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,386 @@
+// 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/text.hpp"
+
+#include <cstring>
+#include <set>
+#include <vector>
+
+#include <atf-c++.hpp>
+
+// ------------------------------------------------------------------------
+// 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)
+{
+    set_md_var("descr", "Tests the join function");
+}
+ATF_TEST_CASE_BODY(join)
+{
+    using atf::text::join;
+
+    // First set of tests using a non-sorted collection, std::vector.
+    {
+        std::vector< std::string > words;
+        std::string str;
+
+        words.clear();
+        str = join(words, ",");
+        ATF_REQUIRE_EQ(str, "");
+
+        words.clear();
+        words.push_back("");
+        str = join(words, ",");
+        ATF_REQUIRE_EQ(str, "");
+
+        words.clear();
+        words.push_back("");
+        words.push_back("");
+        str = join(words, ",");
+        ATF_REQUIRE_EQ(str, ",");
+
+        words.clear();
+        words.push_back("foo");
+        words.push_back("");
+        words.push_back("baz");
+        str = join(words, ",");
+        ATF_REQUIRE_EQ(str, "foo,,baz");
+
+        words.clear();
+        words.push_back("foo");
+        words.push_back("bar");
+        words.push_back("baz");
+        str = join(words, ",");
+        ATF_REQUIRE_EQ(str, "foo,bar,baz");
+    }
+
+    // Second set of tests using a sorted collection, std::set.
+    {
+        std::set< std::string > words;
+        std::string str;
+
+        words.clear();
+        str = join(words, ",");
+        ATF_REQUIRE_EQ(str, "");
+
+        words.clear();
+        words.insert("");
+        str = join(words, ",");
+        ATF_REQUIRE_EQ(str, "");
+
+        words.clear();
+        words.insert("foo");
+        words.insert("");
+        words.insert("baz");
+        str = join(words, ",");
+        ATF_REQUIRE_EQ(str, ",baz,foo");
+
+        words.clear();
+        words.insert("foo");
+        words.insert("bar");
+        words.insert("baz");
+        str = join(words, ",");
+        ATF_REQUIRE_EQ(str, "bar,baz,foo");
+    }
+}
+
+ATF_TEST_CASE(match);
+ATF_TEST_CASE_HEAD(match)
+{
+    set_md_var("descr", "Tests the match function");
+}
+ATF_TEST_CASE_BODY(match)
+{
+    using atf::text::match;
+
+    ATF_REQUIRE_THROW(std::runtime_error, match("", "["));
+
+    ATF_REQUIRE(match("", ""));
+    ATF_REQUIRE(!match("foo", ""));
+
+    ATF_REQUIRE(match("", ".*"));
+    ATF_REQUIRE(match("", "[a-z]*"));
+
+    ATF_REQUIRE(match("hello", "hello"));
+    ATF_REQUIRE(match("hello", "[a-z]+"));
+    ATF_REQUIRE(match("hello", "^[a-z]+$"));
+
+    ATF_REQUIRE(!match("hello", "helooo"));
+    ATF_REQUIRE(!match("hello", "[a-z]+5"));
+    ATF_REQUIRE(!match("hello", "^ [a-z]+$"));
+}
+
+ATF_TEST_CASE(split);
+ATF_TEST_CASE_HEAD(split)
+{
+    set_md_var("descr", "Tests the split function");
+}
+ATF_TEST_CASE_BODY(split)
+{
+    using atf::text::split;
+
+    std::vector< std::string > words;
+
+    words = split("", " ");
+    ATF_REQUIRE_EQ(words.size(), 0);
+
+    words = split(" ", " ");
+    ATF_REQUIRE_EQ(words.size(), 0);
+
+    words = split("    ", " ");
+    ATF_REQUIRE_EQ(words.size(), 0);
+
+    words = split("a b", " ");
+    ATF_REQUIRE_EQ(words.size(), 2);
+    ATF_REQUIRE_EQ(words[0], "a");
+    ATF_REQUIRE_EQ(words[1], "b");
+
+    words = split("a b c d", " ");
+    ATF_REQUIRE_EQ(words.size(), 4);
+    ATF_REQUIRE_EQ(words[0], "a");
+    ATF_REQUIRE_EQ(words[1], "b");
+    ATF_REQUIRE_EQ(words[2], "c");
+    ATF_REQUIRE_EQ(words[3], "d");
+
+    words = split("foo bar", " ");
+    ATF_REQUIRE_EQ(words.size(), 2);
+    ATF_REQUIRE_EQ(words[0], "foo");
+    ATF_REQUIRE_EQ(words[1], "bar");
+
+    words = split("foo bar baz foobar", " ");
+    ATF_REQUIRE_EQ(words.size(), 4);
+    ATF_REQUIRE_EQ(words[0], "foo");
+    ATF_REQUIRE_EQ(words[1], "bar");
+    ATF_REQUIRE_EQ(words[2], "baz");
+    ATF_REQUIRE_EQ(words[3], "foobar");
+
+    words = split(" foo bar", " ");
+    ATF_REQUIRE_EQ(words.size(), 2);
+    ATF_REQUIRE_EQ(words[0], "foo");
+    ATF_REQUIRE_EQ(words[1], "bar");
+
+    words = split("foo  bar", " ");
+    ATF_REQUIRE_EQ(words.size(), 2);
+    ATF_REQUIRE_EQ(words[0], "foo");
+    ATF_REQUIRE_EQ(words[1], "bar");
+
+    words = split("foo bar ", " ");
+    ATF_REQUIRE_EQ(words.size(), 2);
+    ATF_REQUIRE_EQ(words[0], "foo");
+    ATF_REQUIRE_EQ(words[1], "bar");
+
+    words = split("  foo  bar  ", " ");
+    ATF_REQUIRE_EQ(words.size(), 2);
+    ATF_REQUIRE_EQ(words[0], "foo");
+    ATF_REQUIRE_EQ(words[1], "bar");
+}
+
+ATF_TEST_CASE(split_delims);
+ATF_TEST_CASE_HEAD(split_delims)
+{
+    set_md_var("descr", "Tests the split function using different delimiters");
+}
+ATF_TEST_CASE_BODY(split_delims)
+{
+    using atf::text::split;
+
+    std::vector< std::string > words;
+
+    words = split("", "/");
+    ATF_REQUIRE_EQ(words.size(), 0);
+
+    words = split(" ", "/");
+    ATF_REQUIRE_EQ(words.size(), 1);
+    ATF_REQUIRE_EQ(words[0], " ");
+
+    words = split("    ", "/");
+    ATF_REQUIRE_EQ(words.size(), 1);
+    ATF_REQUIRE_EQ(words[0], "    ");
+
+    words = split("a/b", "/");
+    ATF_REQUIRE_EQ(words.size(), 2);
+    ATF_REQUIRE_EQ(words[0], "a");
+    ATF_REQUIRE_EQ(words[1], "b");
+
+    words = split("aLONGDELIMbcdLONGDELIMef", "LONGDELIM");
+    ATF_REQUIRE_EQ(words.size(), 3);
+    ATF_REQUIRE_EQ(words[0], "a");
+    ATF_REQUIRE_EQ(words[1], "bcd");
+    ATF_REQUIRE_EQ(words[2], "ef");
+}
+
+ATF_TEST_CASE(trim);
+ATF_TEST_CASE_HEAD(trim)
+{
+    set_md_var("descr", "Tests the trim function");
+}
+ATF_TEST_CASE_BODY(trim)
+{
+    using atf::text::trim;
+
+    ATF_REQUIRE_EQ(trim(""), "");
+    ATF_REQUIRE_EQ(trim(" "), "");
+    ATF_REQUIRE_EQ(trim("\t"), "");
+
+    ATF_REQUIRE_EQ(trim(" foo"), "foo");
+    ATF_REQUIRE_EQ(trim("\t foo"), "foo");
+    ATF_REQUIRE_EQ(trim(" \tfoo"), "foo");
+    ATF_REQUIRE_EQ(trim("foo\t "), "foo");
+    ATF_REQUIRE_EQ(trim("foo \t"), "foo");
+
+    ATF_REQUIRE_EQ(trim("foo bar"), "foo bar");
+    ATF_REQUIRE_EQ(trim("\t foo bar"), "foo bar");
+    ATF_REQUIRE_EQ(trim(" \tfoo bar"), "foo bar");
+    ATF_REQUIRE_EQ(trim("foo bar\t "), "foo bar");
+    ATF_REQUIRE_EQ(trim("foo bar \t"), "foo bar");
+}
+
+ATF_TEST_CASE(to_bool);
+ATF_TEST_CASE_HEAD(to_bool)
+{
+    set_md_var("descr", "Tests the to_string function");
+}
+ATF_TEST_CASE_BODY(to_bool)
+{
+    using atf::text::to_bool;
+
+    ATF_REQUIRE(to_bool("true"));
+    ATF_REQUIRE(to_bool("TRUE"));
+    ATF_REQUIRE(to_bool("yes"));
+    ATF_REQUIRE(to_bool("YES"));
+
+    ATF_REQUIRE(!to_bool("false"));
+    ATF_REQUIRE(!to_bool("FALSE"));
+    ATF_REQUIRE(!to_bool("no"));
+    ATF_REQUIRE(!to_bool("NO"));
+
+    ATF_REQUIRE_THROW(std::runtime_error, to_bool(""));
+    ATF_REQUIRE_THROW(std::runtime_error, to_bool("tru"));
+    ATF_REQUIRE_THROW(std::runtime_error, to_bool("true2"));
+    ATF_REQUIRE_THROW(std::runtime_error, to_bool("fals"));
+    ATF_REQUIRE_THROW(std::runtime_error, to_bool("false2"));
+}
+
+ATF_TEST_CASE(to_bytes);
+ATF_TEST_CASE_HEAD(to_bytes)
+{
+    set_md_var("descr", "Tests the to_bytes function");
+}
+ATF_TEST_CASE_BODY(to_bytes)
+{
+    using atf::text::to_bytes;
+
+    ATF_REQUIRE_EQ(0, to_bytes("0"));
+    ATF_REQUIRE_EQ(12345, to_bytes("12345"));
+    ATF_REQUIRE_EQ(2 * 1024, to_bytes("2k"));
+    ATF_REQUIRE_EQ(4 * 1024 * 1024, to_bytes("4m"));
+    ATF_REQUIRE_EQ(int64_t(8) * 1024 * 1024 * 1024, to_bytes("8g"));
+    ATF_REQUIRE_EQ(int64_t(16) * 1024 * 1024 * 1024 * 1024, to_bytes("16t"));
+
+    ATF_REQUIRE_THROW_RE(std::runtime_error, "Empty", to_bytes(""));
+    ATF_REQUIRE_THROW_RE(std::runtime_error, "Unknown size unit 'd'",
+                         to_bytes("12d"));
+    ATF_REQUIRE_THROW(std::runtime_error, to_bytes(" "));
+    ATF_REQUIRE_THROW(std::runtime_error, to_bytes(" k"));
+}
+
+ATF_TEST_CASE(to_string);
+ATF_TEST_CASE_HEAD(to_string)
+{
+    set_md_var("descr", "Tests the to_string function");
+}
+ATF_TEST_CASE_BODY(to_string)
+{
+    using atf::text::to_string;
+
+    ATF_REQUIRE_EQ(to_string('a'), "a");
+    ATF_REQUIRE_EQ(to_string("a"), "a");
+    ATF_REQUIRE_EQ(to_string(5), "5");
+}
+
+ATF_TEST_CASE(to_type);
+ATF_TEST_CASE_HEAD(to_type)
+{
+    set_md_var("descr", "Tests the to_type function");
+}
+ATF_TEST_CASE_BODY(to_type)
+{
+    using atf::text::to_type;
+
+    ATF_REQUIRE_EQ(to_type< int >("0"), 0);
+    ATF_REQUIRE_EQ(to_type< int >("1234"), 1234);
+    ATF_REQUIRE_THROW(std::runtime_error, to_type< int >("   "));
+    ATF_REQUIRE_THROW(std::runtime_error, to_type< int >("0 a"));
+    ATF_REQUIRE_THROW(std::runtime_error, to_type< int >("a"));
+
+    ATF_REQUIRE_EQ(to_type< float >("0.5"), 0.5);
+    ATF_REQUIRE_EQ(to_type< float >("1234.5"), 1234.5);
+    ATF_REQUIRE_THROW(std::runtime_error, to_type< float >("0.5 a"));
+    ATF_REQUIRE_THROW(std::runtime_error, to_type< float >("a"));
+
+    ATF_REQUIRE_EQ(to_type< std::string >("a"), "a");
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+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);
+    ATF_ADD_TEST_CASE(tcs, split_delims);
+    ATF_ADD_TEST_CASE(tcs, trim);
+    ATF_ADD_TEST_CASE(tcs, to_bool);
+    ATF_ADD_TEST_CASE(tcs, to_bytes);
+    ATF_ADD_TEST_CASE(tcs, to_string);
+    ATF_ADD_TEST_CASE(tcs, to_type);
+}

Added: vendor/atf/dist/atf-c++/detail/version_helper.cpp
===================================================================
--- vendor/atf/dist/atf-c++/detail/version_helper.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/detail/version_helper.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,41 @@
+// Copyright 2014 Google 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:
+//
+// * Redistributions of source code must retain the above copyright
+//   notice, this list of conditions and the following disclaimer.
+// * 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.
+// * Neither the name of Google Inc. nor the names of its contributors
+//   may be used to endorse or promote products derived from this software
+//   without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
+// OWNER 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(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <cstdlib>
+#include <iostream>
+
+int
+main(void)
+{
+    std::cout << PACKAGE_VERSION << "\n";
+    return EXIT_SUCCESS;
+}

Added: vendor/atf/dist/atf-c++/macros.hpp
===================================================================
--- vendor/atf/dist/atf-c++/macros.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/macros.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,225 @@
+// 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_MACROS_HPP)
+#define ATF_CXX_MACROS_HPP
+
+#include <sstream>
+#include <stdexcept>
+#include <vector>
+
+#include <atf-c++/tests.hpp>
+
+// Do not define inline methods for the test case classes.  Doing so
+// significantly increases the memory requirements of GNU G++ during
+// compilation.
+
+#define ATF_TEST_CASE_WITHOUT_HEAD(name) \
+    namespace { \
+    class atfu_tc_ ## name : public atf::tests::tc { \
+        void body(void) const; \
+    public: \
+        atfu_tc_ ## name(void); \
+    }; \
+    static atfu_tc_ ## name* atfu_tcptr_ ## name; \
+    atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
+    }
+
+#define ATF_TEST_CASE(name) \
+    namespace { \
+    class atfu_tc_ ## name : public atf::tests::tc { \
+        void head(void); \
+        void body(void) const; \
+    public: \
+        atfu_tc_ ## name(void); \
+    }; \
+    static atfu_tc_ ## name* atfu_tcptr_ ## name; \
+    atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, false) {} \
+    }
+
+#define ATF_TEST_CASE_WITH_CLEANUP(name) \
+    namespace { \
+    class atfu_tc_ ## name : public atf::tests::tc { \
+        void head(void); \
+        void body(void) const; \
+        void cleanup(void) const; \
+    public: \
+        atfu_tc_ ## name(void); \
+    }; \
+    static atfu_tc_ ## name* atfu_tcptr_ ## name; \
+    atfu_tc_ ## name::atfu_tc_ ## name(void) : atf::tests::tc(#name, true) {} \
+    }
+
+#define ATF_TEST_CASE_NAME(name) atfu_tc_ ## name
+#define ATF_TEST_CASE_USE(name) (atfu_tcptr_ ## name) = NULL
+
+#define ATF_TEST_CASE_HEAD(name) \
+    void \
+    atfu_tc_ ## name::head(void)
+
+#define ATF_TEST_CASE_BODY(name) \
+    void \
+    atfu_tc_ ## name::body(void) \
+        const
+
+#define ATF_TEST_CASE_CLEANUP(name) \
+    void \
+    atfu_tc_ ## name::cleanup(void) \
+        const
+
+#define ATF_FAIL(reason) atf::tests::tc::fail(reason)
+
+#define ATF_SKIP(reason) atf::tests::tc::skip(reason)
+
+#define ATF_PASS() atf::tests::tc::pass()
+
+#define ATF_REQUIRE(expression) \
+    do { \
+        if (!(expression)) { \
+            std::ostringstream atfu_ss; \
+            atfu_ss << "Line " << __LINE__ << ": " << #expression \
+                    << " not met"; \
+            atf::tests::tc::fail(atfu_ss.str()); \
+        } \
+    } while (false)
+
+#define ATF_REQUIRE_EQ(expected, actual) \
+    do { \
+        if ((expected) != (actual)) { \
+            std::ostringstream atfu_ss; \
+            atfu_ss << "Line " << __LINE__ << ": " \
+                    << #expected << " != " << #actual \
+                    << " (" << (expected) << " != " << (actual) << ")"; \
+            atf::tests::tc::fail(atfu_ss.str()); \
+        } \
+    } while (false)
+
+#define ATF_REQUIRE_IN(element, collection) \
+    ATF_REQUIRE((collection).find(element) != (collection).end())
+
+#define ATF_REQUIRE_NOT_IN(element, collection) \
+    ATF_REQUIRE((collection).find(element) == (collection).end())
+
+#define ATF_REQUIRE_MATCH(regexp, string) \
+    do { \
+        if (!atf::tests::detail::match(regexp, string)) { \
+            std::ostringstream atfu_ss; \
+            atfu_ss << "Line " << __LINE__ << ": '" << string << "' does not " \
+                    << "match regexp '" << regexp << "'"; \
+            atf::tests::tc::fail(atfu_ss.str()); \
+        } \
+    } while (false)
+
+#define ATF_REQUIRE_THROW(expected_exception, statement) \
+    do { \
+        try { \
+            statement; \
+            std::ostringstream atfu_ss; \
+            atfu_ss << "Line " << __LINE__ \
+                    << ": " #statement " did not throw " #expected_exception \
+                       " as expected"; \
+            atf::tests::tc::fail(atfu_ss.str()); \
+        } catch (const expected_exception&) { \
+        } catch (const std::exception& atfu_e) { \
+            std::ostringstream atfu_ss; \
+            atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
+                       "unexpected error (not " #expected_exception "): " \
+                    << atfu_e.what(); \
+            atf::tests::tc::fail(atfu_ss.str()); \
+        } catch (...) { \
+            std::ostringstream atfu_ss; \
+            atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
+                       "unexpected error (not " #expected_exception ")"; \
+            atf::tests::tc::fail(atfu_ss.str()); \
+        } \
+    } while (false)
+
+#define ATF_REQUIRE_THROW_RE(expected_exception, regexp, statement) \
+    do { \
+        try { \
+            statement; \
+            std::ostringstream atfu_ss; \
+            atfu_ss << "Line " << __LINE__ \
+                    << ": " #statement " did not throw " #expected_exception \
+                       " as expected"; \
+            atf::tests::tc::fail(atfu_ss.str()); \
+        } catch (const expected_exception& e) { \
+            if (!atf::tests::detail::match(regexp, e.what())) { \
+                std::ostringstream atfu_ss; \
+                atfu_ss << "Line " << __LINE__ \
+                        << ": " #statement " threw " #expected_exception "(" \
+                        << e.what() << "), but does not match '" << regexp \
+                        << "'"; \
+                atf::tests::tc::fail(atfu_ss.str()); \
+            } \
+        } catch (const std::exception& atfu_e) { \
+            std::ostringstream atfu_ss; \
+            atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
+                        "unexpected error (not " #expected_exception "): " \
+                    << atfu_e.what(); \
+            atf::tests::tc::fail(atfu_ss.str()); \
+        } catch (...) { \
+            std::ostringstream atfu_ss; \
+            atfu_ss << "Line " << __LINE__ << ": " #statement " threw an " \
+                        "unexpected error (not " #expected_exception ")"; \
+            atf::tests::tc::fail(atfu_ss.str()); \
+        } \
+    } while (false)
+
+#define ATF_CHECK_ERRNO(expected_errno, bool_expr) \
+    atf::tests::tc::check_errno(__FILE__, __LINE__, expected_errno, \
+                                #bool_expr, bool_expr)
+
+#define ATF_REQUIRE_ERRNO(expected_errno, bool_expr) \
+    atf::tests::tc::require_errno(__FILE__, __LINE__, expected_errno, \
+                                  #bool_expr, bool_expr)
+
+#define ATF_INIT_TEST_CASES(tcs) \
+    namespace atf { \
+        namespace tests { \
+            int run_tp(int, char**, \
+                       void (*)(std::vector< atf::tests::tc * >&)); \
+        } \
+    } \
+    \
+    static void atfu_init_tcs(std::vector< atf::tests::tc * >&); \
+    \
+    int \
+    main(int argc, char** argv) \
+    { \
+        return atf::tests::run_tp(argc, argv, atfu_init_tcs); \
+    } \
+    \
+    static \
+    void \
+    atfu_init_tcs(std::vector< atf::tests::tc * >& tcs)
+
+#define ATF_ADD_TEST_CASE(tcs, tcname) \
+    do { \
+        atfu_tcptr_ ## tcname = new atfu_tc_ ## tcname(); \
+        (tcs).push_back(atfu_tcptr_ ## tcname); \
+    } while (0);
+
+#endif // !defined(ATF_CXX_MACROS_HPP)

Added: vendor/atf/dist/atf-c++/macros_hpp_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/macros_hpp_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/macros_hpp_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,126 @@
+// Copyright (c) 2008 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++/macros.hpp>
+
+#include <stdexcept>
+
+void
+atf_check_errno_semicolons(void)
+{
+    // Check that ATF_CHECK_ERRNO does not contain a semicolon that would
+    // cause an empty-statement that confuses some compilers.
+    ATF_CHECK_ERRNO(1, 1 == 1);
+    ATF_CHECK_ERRNO(2, 2 == 2);
+}
+
+void
+atf_require_inside_if(void)
+{
+    // Make sure that ATF_REQUIRE can be used inside an if statement that
+    // does not have braces.  Earlier versions of it generated an error
+    // if there was an else clause because they confused the compiler
+    // by defining an unprotected nested if.
+    if (true)
+        ATF_REQUIRE(true);
+    else
+        ATF_REQUIRE(true);
+}
+
+void
+atf_require_eq_inside_if(void)
+{
+    // Make sure that ATF_REQUIRE_EQ can be used inside an if statement
+    // that does not have braces.  Earlier versions of it generated an
+    // error if there was an else clause because they confused the
+    // compiler by defining an unprotected nested if.
+    if (true)
+        ATF_REQUIRE_EQ(true, true);
+    else
+        ATF_REQUIRE_EQ(true, true);
+}
+
+void
+atf_require_throw_runtime_error(void)
+{
+    // Check that we can pass std::runtime_error to ATF_REQUIRE_THROW.
+    // Earlier versions generated a warning because the macro's code also
+    // attempted to capture this exception, and thus we had a duplicate
+    // catch clause.
+    ATF_REQUIRE_THROW(std::runtime_error, (void)0);
+}
+
+void
+atf_require_throw_inside_if(void)
+{
+    // Make sure that ATF_REQUIRE_THROW can be used inside an if statement
+    // that does not have braces.  Earlier versions of it generated an
+    // error because a trailing ; after a catch block was not allowed.
+    if (true)
+        ATF_REQUIRE_THROW(std::runtime_error, (void)0);
+    else
+        ATF_REQUIRE_THROW(std::runtime_error, (void)1);
+}
+
+void
+atf_require_errno_semicolons(void)
+{
+    // Check that ATF_REQUIRE_ERRNO does not contain a semicolon that would
+    // cause an empty-statement that confuses some compilers.
+    ATF_REQUIRE_ERRNO(1, 1 == 1);
+    ATF_REQUIRE_ERRNO(2, 2 == 2);
+}
+
+// Test case names should not be expanded during instatiation so that they
+// can have the exact same name as macros.
+#define TEST_MACRO_1 invalid + name
+#define TEST_MACRO_2 invalid + name
+#define TEST_MACRO_3 invalid + name
+ATF_TEST_CASE(TEST_MACRO_1);
+ATF_TEST_CASE_HEAD(TEST_MACRO_1) { }
+ATF_TEST_CASE_BODY(TEST_MACRO_1) { }
+void instantiate_1(void) {
+    ATF_TEST_CASE_USE(TEST_MACRO_1);
+    atf::tests::tc* the_test = new ATF_TEST_CASE_NAME(TEST_MACRO_1)();
+    delete the_test;
+}
+ATF_TEST_CASE_WITH_CLEANUP(TEST_MACRO_2);
+ATF_TEST_CASE_HEAD(TEST_MACRO_2) { }
+ATF_TEST_CASE_BODY(TEST_MACRO_2) { }
+ATF_TEST_CASE_CLEANUP(TEST_MACRO_2) { }
+void instatiate_2(void) {
+    ATF_TEST_CASE_USE(TEST_MACRO_2);
+    atf::tests::tc* the_test = new ATF_TEST_CASE_NAME(TEST_MACRO_2)();
+    delete the_test;
+}
+ATF_TEST_CASE_WITH_CLEANUP(TEST_MACRO_3);
+ATF_TEST_CASE_HEAD(TEST_MACRO_3) { }
+ATF_TEST_CASE_BODY(TEST_MACRO_3) { }
+ATF_TEST_CASE_CLEANUP(TEST_MACRO_3) { }
+void instatiate_3(void) {
+    ATF_TEST_CASE_USE(TEST_MACRO_3);
+    atf::tests::tc* the_test = new ATF_TEST_CASE_NAME(TEST_MACRO_3)();
+    delete the_test;
+}

Added: vendor/atf/dist/atf-c++/macros_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/macros_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/macros_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,811 @@
+// Copyright (c) 2008 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++/macros.hpp"
+
+extern "C" {
+#include <fcntl.h>
+#include <unistd.h>
+}
+
+#include <cerrno>
+#include <cstdlib>
+#include <iostream>
+#include <stdexcept>
+
+#include <atf-c++.hpp>
+
+#include "atf-c++/detail/fs.hpp"
+#include "atf-c++/detail/process.hpp"
+#include "atf-c++/detail/sanity.hpp"
+#include "atf-c++/detail/test_helpers.hpp"
+#include "atf-c++/detail/text.hpp"
+#include "atf-c++/utils.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+static
+void
+create_ctl_file(const char *name)
+{
+    ATF_REQUIRE(open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1);
+}
+
+// ------------------------------------------------------------------------
+// Auxiliary test cases.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(h_pass);
+ATF_TEST_CASE_HEAD(h_pass)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_pass)
+{
+    create_ctl_file("before");
+    ATF_PASS();
+    create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_fail);
+ATF_TEST_CASE_HEAD(h_fail)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_fail)
+{
+    create_ctl_file("before");
+    ATF_FAIL("Failed on purpose");
+    create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_skip);
+ATF_TEST_CASE_HEAD(h_skip)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_skip)
+{
+    create_ctl_file("before");
+    ATF_SKIP("Skipped on purpose");
+    create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_require);
+ATF_TEST_CASE_HEAD(h_require)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_require)
+{
+    bool condition = atf::text::to_bool(get_config_var("condition"));
+
+    create_ctl_file("before");
+    ATF_REQUIRE(condition);
+    create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_require_eq);
+ATF_TEST_CASE_HEAD(h_require_eq)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_require_eq)
+{
+    long v1 = atf::text::to_type< long >(get_config_var("v1"));
+    long v2 = atf::text::to_type< long >(get_config_var("v2"));
+
+    create_ctl_file("before");
+    ATF_REQUIRE_EQ(v1, v2);
+    create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_require_in);
+ATF_TEST_CASE_HEAD(h_require_in)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_require_in)
+{
+    const std::string element = get_config_var("value");
+
+    std::set< std::string > collection;
+    collection.insert("foo");
+    collection.insert("bar");
+    collection.insert("baz");
+
+    create_ctl_file("before");
+    ATF_REQUIRE_IN(element, collection);
+    create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_require_match);
+ATF_TEST_CASE_HEAD(h_require_match)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_require_match)
+{
+    const std::string regexp = get_config_var("regexp");
+    const std::string string = get_config_var("string");
+
+    create_ctl_file("before");
+    ATF_REQUIRE_MATCH(regexp, string);
+    create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_require_not_in);
+ATF_TEST_CASE_HEAD(h_require_not_in)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_require_not_in)
+{
+    const std::string element = get_config_var("value");
+
+    std::set< std::string > collection;
+    collection.insert("foo");
+    collection.insert("bar");
+    collection.insert("baz");
+
+    create_ctl_file("before");
+    ATF_REQUIRE_NOT_IN(element, collection);
+    create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_require_throw);
+ATF_TEST_CASE_HEAD(h_require_throw)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_require_throw)
+{
+    create_ctl_file("before");
+
+    if (get_config_var("what") == "throw_int")
+        ATF_REQUIRE_THROW(std::runtime_error, if (1) throw int(5));
+    else if (get_config_var("what") == "throw_rt")
+        ATF_REQUIRE_THROW(std::runtime_error,
+                        if (1) throw std::runtime_error("e"));
+    else if (get_config_var("what") == "no_throw_rt")
+        ATF_REQUIRE_THROW(std::runtime_error,
+                        if (0) throw std::runtime_error("e"));
+
+    create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_require_throw_re);
+ATF_TEST_CASE_HEAD(h_require_throw_re)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_require_throw_re)
+{
+    create_ctl_file("before");
+
+    if (get_config_var("what") == "throw_int")
+        ATF_REQUIRE_THROW_RE(std::runtime_error, "5", if (1) throw int(5));
+    else if (get_config_var("what") == "throw_rt_match")
+        ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
+                             if (1) throw std::runtime_error("a foo bar baz"));
+    else if (get_config_var("what") == "throw_rt_no_match")
+        ATF_REQUIRE_THROW_RE(std::runtime_error, "foo.*baz",
+                             if (1) throw std::runtime_error("baz foo bar a"));
+    else if (get_config_var("what") == "no_throw_rt")
+        ATF_REQUIRE_THROW_RE(std::runtime_error, "e",
+                             if (0) throw std::runtime_error("e"));
+
+    create_ctl_file("after");
+}
+
+static int
+errno_fail_stub(const int raised_errno)
+{
+    errno = raised_errno;
+    return -1;
+}
+
+static int
+errno_ok_stub(void)
+{
+    return 0;
+}
+
+ATF_TEST_CASE(h_check_errno);
+ATF_TEST_CASE_HEAD(h_check_errno)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_check_errno)
+{
+    create_ctl_file("before");
+
+    if (get_config_var("what") == "no_error")
+        ATF_CHECK_ERRNO(-1, errno_ok_stub() == -1);
+    else if (get_config_var("what") == "errno_ok")
+        ATF_CHECK_ERRNO(2, errno_fail_stub(2) == -1);
+    else if (get_config_var("what") == "errno_fail")
+        ATF_CHECK_ERRNO(3, errno_fail_stub(4) == -1);
+    else
+        UNREACHABLE;
+
+    create_ctl_file("after");
+}
+
+ATF_TEST_CASE(h_require_errno);
+ATF_TEST_CASE_HEAD(h_require_errno)
+{
+    set_md_var("descr", "Helper test case");
+}
+ATF_TEST_CASE_BODY(h_require_errno)
+{
+    create_ctl_file("before");
+
+    if (get_config_var("what") == "no_error")
+        ATF_REQUIRE_ERRNO(-1, errno_ok_stub() == -1);
+    else if (get_config_var("what") == "errno_ok")
+        ATF_REQUIRE_ERRNO(2, errno_fail_stub(2) == -1);
+    else if (get_config_var("what") == "errno_fail")
+        ATF_REQUIRE_ERRNO(3, errno_fail_stub(4) == -1);
+    else
+        UNREACHABLE;
+
+    create_ctl_file("after");
+}
+
+// ------------------------------------------------------------------------
+// Test cases for the macros.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(pass);
+ATF_TEST_CASE_HEAD(pass)
+{
+    set_md_var("descr", "Tests the ATF_PASS macro");
+}
+ATF_TEST_CASE_BODY(pass)
+{
+    ATF_TEST_CASE_USE(h_pass);
+    run_h_tc< ATF_TEST_CASE_NAME(h_pass) >();
+    ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+    ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
+    ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
+}
+
+ATF_TEST_CASE(fail);
+ATF_TEST_CASE_HEAD(fail)
+{
+    set_md_var("descr", "Tests the ATF_FAIL macro");
+}
+ATF_TEST_CASE_BODY(fail)
+{
+    ATF_TEST_CASE_USE(h_fail);
+    run_h_tc< ATF_TEST_CASE_NAME(h_fail) >();
+    ATF_REQUIRE(atf::utils::grep_file("^failed: Failed on purpose", "result"));
+    ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
+    ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
+}
+
+ATF_TEST_CASE(skip);
+ATF_TEST_CASE_HEAD(skip)
+{
+    set_md_var("descr", "Tests the ATF_SKIP macro");
+}
+ATF_TEST_CASE_BODY(skip)
+{
+    ATF_TEST_CASE_USE(h_skip);
+    run_h_tc< ATF_TEST_CASE_NAME(h_skip) >();
+    ATF_REQUIRE(atf::utils::grep_file("^skipped: Skipped on purpose",
+        "result"));
+    ATF_REQUIRE(atf::fs::exists(atf::fs::path("before")));
+    ATF_REQUIRE(!atf::fs::exists(atf::fs::path("after")));
+}
+
+ATF_TEST_CASE(require);
+ATF_TEST_CASE_HEAD(require)
+{
+    set_md_var("descr", "Tests the ATF_REQUIRE macro");
+}
+ATF_TEST_CASE_BODY(require)
+{
+    struct test {
+        const char *cond;
+        bool ok;
+    } *t, tests[] = {
+        { "false", false },
+        { "true", true },
+        { NULL, false }
+    };
+
+    const atf::fs::path before("before");
+    const atf::fs::path after("after");
+
+    for (t = &tests[0]; t->cond != NULL; t++) {
+        atf::tests::vars_map config;
+        config["condition"] = t->cond;
+
+        std::cout << "Checking with a " << t->cond << " value\n";
+
+        ATF_TEST_CASE_USE(h_require);
+        run_h_tc< ATF_TEST_CASE_NAME(h_require) >(config);
+
+        ATF_REQUIRE(atf::fs::exists(before));
+        if (t->ok) {
+            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+            ATF_REQUIRE(atf::fs::exists(after));
+        } else {
+            ATF_REQUIRE(atf::utils::grep_file(
+                "^failed: .*condition not met", "result"));
+            ATF_REQUIRE(!atf::fs::exists(after));
+        }
+
+        atf::fs::remove(before);
+        if (t->ok)
+            atf::fs::remove(after);
+    }
+}
+
+ATF_TEST_CASE(require_eq);
+ATF_TEST_CASE_HEAD(require_eq)
+{
+    set_md_var("descr", "Tests the ATF_REQUIRE_EQ macro");
+}
+ATF_TEST_CASE_BODY(require_eq)
+{
+    struct test {
+        const char *v1;
+        const char *v2;
+        bool ok;
+    } *t, tests[] = {
+        { "1", "1", true },
+        { "1", "2", false },
+        { "2", "1", false },
+        { "2", "2", true },
+        { NULL, NULL, false }
+    };
+
+    const atf::fs::path before("before");
+    const atf::fs::path after("after");
+
+    for (t = &tests[0]; t->v1 != NULL; t++) {
+        atf::tests::vars_map config;
+        config["v1"] = t->v1;
+        config["v2"] = t->v2;
+
+        std::cout << "Checking with " << t->v1 << ", " << t->v2
+                  << " and expecting " << (t->ok ? "true" : "false")
+                  << "\n";
+
+        ATF_TEST_CASE_USE(h_require_eq);
+        run_h_tc< ATF_TEST_CASE_NAME(h_require_eq) >(config);
+
+        ATF_REQUIRE(atf::fs::exists(before));
+        if (t->ok) {
+            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+            ATF_REQUIRE(atf::fs::exists(after));
+        } else {
+            ATF_REQUIRE(atf::utils::grep_file("^failed: .*v1 != v2", "result"));
+            ATF_REQUIRE(!atf::fs::exists(after));
+        }
+
+        atf::fs::remove(before);
+        if (t->ok)
+            atf::fs::remove(after);
+    }
+}
+
+ATF_TEST_CASE(require_in);
+ATF_TEST_CASE_HEAD(require_in)
+{
+    set_md_var("descr", "Tests the ATF_REQUIRE_IN macro");
+}
+ATF_TEST_CASE_BODY(require_in)
+{
+    struct test {
+        const char *value;
+        bool ok;
+    } *t, tests[] = {
+        { "foo", true },
+        { "bar", true },
+        { "baz", true },
+        { "xxx", false },
+        { "fooa", false },
+        { "foo ", false },
+        { NULL, false }
+    };
+
+    const atf::fs::path before("before");
+    const atf::fs::path after("after");
+
+    for (t = &tests[0]; t->value != NULL; t++) {
+        atf::tests::vars_map config;
+        config["value"] = t->value;
+
+        ATF_TEST_CASE_USE(h_require_in);
+        run_h_tc< ATF_TEST_CASE_NAME(h_require_in) >(config);
+
+        ATF_REQUIRE(atf::fs::exists(before));
+        if (t->ok) {
+            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+            ATF_REQUIRE(atf::fs::exists(after));
+        } else {
+            ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
+            ATF_REQUIRE(!atf::fs::exists(after));
+        }
+
+        atf::fs::remove(before);
+        if (t->ok)
+            atf::fs::remove(after);
+    }
+}
+
+ATF_TEST_CASE(require_match);
+ATF_TEST_CASE_HEAD(require_match)
+{
+    set_md_var("descr", "Tests the ATF_REQUIRE_MATCH macro");
+}
+ATF_TEST_CASE_BODY(require_match)
+{
+    struct test {
+        const char *regexp;
+        const char *string;
+        bool ok;
+    } *t, tests[] = {
+        { "foo.*bar", "this is a foo, bar, baz", true },
+        { "bar.*baz", "this is a baz, bar, foo", false },
+        { NULL, NULL, false }
+    };
+
+    const atf::fs::path before("before");
+    const atf::fs::path after("after");
+
+    for (t = &tests[0]; t->regexp != NULL; t++) {
+        atf::tests::vars_map config;
+        config["regexp"] = t->regexp;
+        config["string"] = t->string;
+
+        std::cout << "Checking with " << t->regexp << ", " << t->string
+                  << " and expecting " << (t->ok ? "true" : "false")
+                  << "\n";
+
+        ATF_TEST_CASE_USE(h_require_match);
+        run_h_tc< ATF_TEST_CASE_NAME(h_require_match) >(config);
+
+        ATF_REQUIRE(atf::fs::exists(before));
+        if (t->ok) {
+            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+            ATF_REQUIRE(atf::fs::exists(after));
+        } else {
+            ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
+            ATF_REQUIRE(!atf::fs::exists(after));
+        }
+
+        atf::fs::remove(before);
+        if (t->ok)
+            atf::fs::remove(after);
+    }
+}
+
+ATF_TEST_CASE(require_not_in);
+ATF_TEST_CASE_HEAD(require_not_in)
+{
+    set_md_var("descr", "Tests the ATF_REQUIRE_NOT_IN macro");
+}
+ATF_TEST_CASE_BODY(require_not_in)
+{
+    struct test {
+        const char *value;
+        bool ok;
+    } *t, tests[] = {
+        { "foo", false },
+        { "bar", false },
+        { "baz", false },
+        { "xxx", true },
+        { "fooa", true },
+        { "foo ", true },
+        { NULL, false }
+    };
+
+    const atf::fs::path before("before");
+    const atf::fs::path after("after");
+
+    for (t = &tests[0]; t->value != NULL; t++) {
+        atf::tests::vars_map config;
+        config["value"] = t->value;
+
+        ATF_TEST_CASE_USE(h_require_not_in);
+        run_h_tc< ATF_TEST_CASE_NAME(h_require_not_in) >(config);
+
+        ATF_REQUIRE(atf::fs::exists(before));
+        if (t->ok) {
+            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+            ATF_REQUIRE(atf::fs::exists(after));
+        } else {
+            ATF_REQUIRE(atf::utils::grep_file("^failed: ", "result"));
+            ATF_REQUIRE(!atf::fs::exists(after));
+        }
+
+        atf::fs::remove(before);
+        if (t->ok)
+            atf::fs::remove(after);
+    }
+}
+
+ATF_TEST_CASE(require_throw);
+ATF_TEST_CASE_HEAD(require_throw)
+{
+    set_md_var("descr", "Tests the ATF_REQUIRE_THROW macro");
+}
+ATF_TEST_CASE_BODY(require_throw)
+{
+    struct test {
+        const char *what;
+        bool ok;
+        const char *msg;
+    } *t, tests[] = {
+        { "throw_int", false, "unexpected error" },
+        { "throw_rt", true, NULL },
+        { "no_throw_rt", false, "did not throw" },
+        { NULL, false, NULL }
+    };
+
+    const atf::fs::path before("before");
+    const atf::fs::path after("after");
+
+    for (t = &tests[0]; t->what != NULL; t++) {
+        atf::tests::vars_map config;
+        config["what"] = t->what;
+
+        std::cout << "Checking with " << t->what << " and expecting "
+                  << (t->ok ? "true" : "false") << "\n";
+
+        ATF_TEST_CASE_USE(h_require_throw);
+        run_h_tc< ATF_TEST_CASE_NAME(h_require_throw) >(config);
+
+        ATF_REQUIRE(atf::fs::exists(before));
+        if (t->ok) {
+            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+            ATF_REQUIRE(atf::fs::exists(after));
+        } else {
+            std::cout << "Checking that message contains '" << t->msg
+                      << "'\n";
+            std::string exp_result = std::string("^failed: .*") + t->msg;
+            ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
+            ATF_REQUIRE(!atf::fs::exists(after));
+        }
+
+        atf::fs::remove(before);
+        if (t->ok)
+            atf::fs::remove(after);
+    }
+}
+
+ATF_TEST_CASE(require_throw_re);
+ATF_TEST_CASE_HEAD(require_throw_re)
+{
+    set_md_var("descr", "Tests the ATF_REQUIRE_THROW_RE macro");
+}
+ATF_TEST_CASE_BODY(require_throw_re)
+{
+    struct test {
+        const char *what;
+        bool ok;
+        const char *msg;
+    } *t, tests[] = {
+        { "throw_int", false, "unexpected error" },
+        { "throw_rt_match", true, NULL },
+        { "throw_rt_no_match", false,
+          "threw.*runtime_error\\(baz foo bar a\\).*"
+          "does not match 'foo\\.\\*baz'" },
+        { "no_throw_rt", false, "did not throw" },
+        { NULL, false, NULL }
+    };
+
+    const atf::fs::path before("before");
+    const atf::fs::path after("after");
+
+    for (t = &tests[0]; t->what != NULL; t++) {
+        atf::tests::vars_map config;
+        config["what"] = t->what;
+
+        std::cout << "Checking with " << t->what << " and expecting "
+                  << (t->ok ? "true" : "false") << "\n";
+
+        ATF_TEST_CASE_USE(h_require_throw_re);
+        run_h_tc< ATF_TEST_CASE_NAME(h_require_throw_re) >(config);
+
+        ATF_REQUIRE(atf::fs::exists(before));
+        if (t->ok) {
+            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+            ATF_REQUIRE(atf::fs::exists(after));
+        } else {
+            std::cout << "Checking that message contains '" << t->msg
+                      << "'\n";
+            std::string exp_result = std::string("^failed: .*") + t->msg;
+            ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
+            ATF_REQUIRE(!atf::fs::exists(after));
+        }
+
+        atf::fs::remove(before);
+        if (t->ok)
+            atf::fs::remove(after);
+    }
+}
+
+ATF_TEST_CASE(check_errno);
+ATF_TEST_CASE_HEAD(check_errno)
+{
+    set_md_var("descr", "Tests the ATF_CHECK_ERRNO macro");
+}
+ATF_TEST_CASE_BODY(check_errno)
+{
+    struct test {
+        const char *what;
+        bool ok;
+        const char *msg;
+    } *t, tests[] = {
+        { "no_error", false,
+          "Expected true value in errno_ok_stub\\(\\) == -1" },
+        { "errno_ok", true, NULL },
+        { "errno_fail", false,
+          "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
+        { NULL, false, NULL }
+    };
+
+    const atf::fs::path before("before");
+    const atf::fs::path after("after");
+
+    for (t = &tests[0]; t->what != NULL; t++) {
+        atf::tests::vars_map config;
+        config["what"] = t->what;
+
+        ATF_TEST_CASE_USE(h_check_errno);
+        run_h_tc< ATF_TEST_CASE_NAME(h_check_errno) >(config);
+
+        ATF_REQUIRE(atf::fs::exists(before));
+        ATF_REQUIRE(atf::fs::exists(after));
+
+        if (t->ok) {
+            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+        } else {
+            ATF_REQUIRE(atf::utils::grep_file("^failed", "result"));
+
+            std::string exp_result = "macros_test.cpp:[0-9]+: " +
+                std::string(t->msg) + "$";
+            ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "stderr"));
+        }
+
+        atf::fs::remove(before);
+        atf::fs::remove(after);
+    }
+}
+
+ATF_TEST_CASE(require_errno);
+ATF_TEST_CASE_HEAD(require_errno)
+{
+    set_md_var("descr", "Tests the ATF_REQUIRE_ERRNO macro");
+}
+ATF_TEST_CASE_BODY(require_errno)
+{
+    struct test {
+        const char *what;
+        bool ok;
+        const char *msg;
+    } *t, tests[] = {
+        { "no_error", false,
+          "Expected true value in errno_ok_stub\\(\\) == -1" },
+        { "errno_ok", true, NULL },
+        { "errno_fail", false,
+          "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" },
+        { NULL, false, NULL }
+    };
+
+    const atf::fs::path before("before");
+    const atf::fs::path after("after");
+
+    for (t = &tests[0]; t->what != NULL; t++) {
+        atf::tests::vars_map config;
+        config["what"] = t->what;
+
+        ATF_TEST_CASE_USE(h_require_errno);
+        run_h_tc< ATF_TEST_CASE_NAME(h_require_errno) >(config);
+
+        ATF_REQUIRE(atf::fs::exists(before));
+        if (t->ok) {
+            ATF_REQUIRE(atf::utils::grep_file("^passed", "result"));
+            ATF_REQUIRE(atf::fs::exists(after));
+        } else {
+            std::string exp_result = "^failed: .*macros_test.cpp:[0-9]+: " +
+                std::string(t->msg) + "$";
+            ATF_REQUIRE(atf::utils::grep_file(exp_result.c_str(), "result"));
+
+            ATF_REQUIRE(!atf::fs::exists(after));
+        }
+
+        atf::fs::remove(before);
+        if (t->ok)
+            atf::fs::remove(after);
+    }
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the header file.
+// ------------------------------------------------------------------------
+
+BUILD_TC(use, "macros_hpp_test.cpp",
+         "Tests that the macros provided by the atf-c++/macros.hpp file "
+         "do not cause syntax errors when used",
+         "Build of macros_hpp_test.cpp failed; some macros in "
+         "atf-c++/macros.hpp are broken");
+
+ATF_TEST_CASE(detect_unused_tests);
+ATF_TEST_CASE_HEAD(detect_unused_tests)
+{
+    set_md_var("descr",
+               "Tests that defining an unused test case raises a warning (and "
+               "thus an error)");
+}
+ATF_TEST_CASE_BODY(detect_unused_tests)
+{
+    const char* validate_compiler =
+        "class test_class { public: int dummy; };\n"
+        "#define define_unused static test_class unused\n"
+        "define_unused;\n";
+
+    atf::utils::create_file("compiler_test.cpp", validate_compiler);
+    if (build_check_cxx_o("compiler_test.cpp"))
+        expect_fail("Compiler does not raise a warning on an unused "
+                    "static global variable declared by a macro");
+
+    if (build_check_cxx_o_srcdir(*this, "unused_test.cpp"))
+        ATF_FAIL("Build of unused_test.cpp passed; unused test cases are "
+                 "not properly detected");
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    // Add the test cases for the macros.
+    ATF_ADD_TEST_CASE(tcs, pass);
+    ATF_ADD_TEST_CASE(tcs, fail);
+    ATF_ADD_TEST_CASE(tcs, skip);
+    ATF_ADD_TEST_CASE(tcs, check_errno);
+    ATF_ADD_TEST_CASE(tcs, require);
+    ATF_ADD_TEST_CASE(tcs, require_eq);
+    ATF_ADD_TEST_CASE(tcs, require_in);
+    ATF_ADD_TEST_CASE(tcs, require_match);
+    ATF_ADD_TEST_CASE(tcs, require_not_in);
+    ATF_ADD_TEST_CASE(tcs, require_throw);
+    ATF_ADD_TEST_CASE(tcs, require_throw_re);
+    ATF_ADD_TEST_CASE(tcs, require_errno);
+
+    // Add the test cases for the header file.
+    ATF_ADD_TEST_CASE(tcs, use);
+    ATF_ADD_TEST_CASE(tcs, detect_unused_tests);
+}

Added: vendor/atf/dist/atf-c++/pkg_config_test.sh
===================================================================
--- vendor/atf/dist/atf-c++/pkg_config_test.sh	                        (rev 0)
+++ vendor/atf/dist/atf-c++/pkg_config_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,143 @@
+# Copyright (c) 2008 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.
+
+# The following tests assume that the atfc++.pc file is installed in a
+# directory that is known by pkg-config.  Otherwise they will fail,
+# and you will be required to adjust PKG_CONFIG_PATH accordingly.
+#
+# It would be possible to bypass this requirement by setting the path
+# explicitly during the tests, but then this would not do a real check
+# to ensure that the installation is working.
+
+require_pc()
+{
+    pkg-config ${1} || atf_fail "pkg-config could not locate ${1}.pc;" \
+                                "maybe need to set PKG_CONFIG_PATH?"
+}
+
+check_version()
+{
+    ver1=$($(atf_get_srcdir)/detail/version_helper)
+    echo "Version reported by builtin PACKAGE_VERSION: ${ver1}"
+
+    atf_check -s eq:0 -o save:stdout -e empty pkg-config --modversion "${1}"
+    ver2=$(cat stdout)
+    echo "Version reported by pkg-config: ${ver2}"
+
+    atf_check_equal ${ver1} ${ver2}
+}
+
+atf_test_case version
+version_head()
+{
+    atf_set "descr" "Checks that the version in atf-c++ is correct"
+    atf_set "require.progs" "pkg-config"
+}
+version_body()
+{
+    require_pc "atf-c++"
+
+    check_version "atf-c++"
+}
+
+atf_test_case build
+build_head()
+{
+    atf_set "descr" "Checks that a test program can be built against" \
+                    "the C++ library based on the pkg-config information"
+    atf_set "require.progs" "pkg-config"
+}
+build_body()
+{
+    require_pc "atf-c++"
+
+    atf_check -s eq:0 -o save:stdout -e empty \
+              pkg-config --variable=cxx atf-c++
+    cxx=$(cat stdout)
+    echo "Compiler is: ${cxx}"
+    atf_require_prog ${cxx}
+
+    cat >tp.cpp <<EOF
+#include <iostream>
+
+#include <atf-c++.hpp>
+
+ATF_TEST_CASE(tc);
+ATF_TEST_CASE_HEAD(tc) {
+    set_md_var("descr", "A test case");
+}
+ATF_TEST_CASE_BODY(tc) {
+    std::cout << "Running\n";
+}
+
+ATF_INIT_TEST_CASES(tcs) {
+    ATF_ADD_TEST_CASE(tcs, tc);
+}
+EOF
+
+    atf_check -s eq:0 -o save:stdout -e empty pkg-config --cflags atf-c++
+    cxxflags=$(cat stdout)
+    echo "CXXFLAGS are: ${cxxflags}"
+
+    atf_check -s eq:0 -o save:stdout -e empty \
+        pkg-config --libs-only-L --libs-only-other atf-c++
+    ldflags=$(cat stdout)
+    atf_check -s eq:0 -o save:stdout -e empty \
+              pkg-config --libs-only-l atf-c++
+    libs=$(cat stdout)
+    echo "LDFLAGS are: ${ldflags}"
+    echo "LIBS are: ${libs}"
+
+    atf_check -s eq:0 -o empty -e empty ${cxx} ${cxxflags} -o tp.o -c tp.cpp
+    atf_check -s eq:0 -o empty -e empty ${cxx} ${ldflags} -o tp tp.o ${libs}
+
+    libpath=
+    for f in ${ldflags}; do
+        case ${f} in
+            -L*)
+                dir=$(echo ${f} | sed -e 's,^-L,,')
+                if [ -z "${libpath}" ]; then
+                    libpath="${dir}"
+                else
+                    libpath="${libpath}:${dir}"
+                fi
+                ;;
+            *)
+                ;;
+        esac
+    done
+
+    atf_check -s eq:0 -o empty -e empty test -x tp
+    atf_check -s eq:0 -o match:'Running' -e empty -x \
+              "LD_LIBRARY_PATH=${libpath} ./tp tc"
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case version
+    atf_add_test_case build
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/atf-c++/tests.cpp
===================================================================
--- vendor/atf/dist/atf-c++/tests.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/tests.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,658 @@
+// 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++/tests.hpp"
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+extern "C" {
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <unistd.h>
+}
+
+#include <algorithm>
+#include <cctype>
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <sstream>
+#include <stdexcept>
+#include <vector>
+
+extern "C" {
+#include "atf-c/error.h"
+#include "atf-c/tc.h"
+#include "atf-c/utils.h"
+}
+
+#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"
+#include "atf-c++/detail/sanity.hpp"
+#include "atf-c++/detail/text.hpp"
+
+#if defined(HAVE_GNU_GETOPT)
+#   define GETOPT_POSIX "+"
+#else
+#   define GETOPT_POSIX ""
+#endif
+
+namespace impl = atf::tests;
+namespace detail = atf::tests::detail;
+#define IMPL_NAME "atf::tests"
+
+using atf::application::usage_error;
+
+// ------------------------------------------------------------------------
+// The "atf_tp_writer" class.
+// ------------------------------------------------------------------------
+
+detail::atf_tp_writer::atf_tp_writer(std::ostream& os) :
+    m_os(os),
+    m_is_first(true)
+{
+    m_os << "Content-Type: application/X-atf-tp; version=\"1\"\n\n";
+}
+
+void
+detail::atf_tp_writer::start_tc(const std::string& ident)
+{
+    if (!m_is_first)
+        m_os << "\n";
+    m_os << "ident: " << ident << "\n";
+    m_os.flush();
+}
+
+void
+detail::atf_tp_writer::end_tc(void)
+{
+    if (m_is_first)
+        m_is_first = false;
+}
+
+void
+detail::atf_tp_writer::tc_meta_data(const std::string& name,
+                                    const std::string& value)
+{
+    PRE(name != "ident");
+    m_os << name << ": " << value << "\n";
+    m_os.flush();
+}
+
+// ------------------------------------------------------------------------
+// Free helper functions.
+// ------------------------------------------------------------------------
+
+std::string Program_Name;
+
+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;
+}
+
+bool
+detail::match(const std::string& regexp, const std::string& str)
+{
+    return atf::text::match(str, regexp);
+}
+
+// ------------------------------------------------------------------------
+// The "tc" class.
+// ------------------------------------------------------------------------
+
+static std::map< atf_tc_t*, impl::tc* > wraps;
+static std::map< const atf_tc_t*, const impl::tc* > cwraps;
+
+struct impl::tc_impl {
+private:
+    // Non-copyable.
+    tc_impl(const tc_impl&);
+    tc_impl& operator=(const tc_impl&);
+
+public:
+    std::string m_ident;
+    atf_tc_t m_tc;
+    bool m_has_cleanup;
+
+    tc_impl(const std::string& ident, const bool has_cleanup) :
+        m_ident(ident),
+        m_has_cleanup(has_cleanup)
+    {
+    }
+
+    static void
+    wrap_head(atf_tc_t *tc)
+    {
+        std::map< atf_tc_t*, impl::tc* >::iterator iter = wraps.find(tc);
+        INV(iter != wraps.end());
+        (*iter).second->head();
+    }
+
+    static void
+    wrap_body(const atf_tc_t *tc)
+    {
+        std::map< const atf_tc_t*, const impl::tc* >::const_iterator iter =
+            cwraps.find(tc);
+        INV(iter != cwraps.end());
+        (*iter).second->body();
+    }
+
+    static void
+    wrap_cleanup(const atf_tc_t *tc)
+    {
+        std::map< const atf_tc_t*, const impl::tc* >::const_iterator iter =
+            cwraps.find(tc);
+        INV(iter != cwraps.end());
+        (*iter).second->cleanup();
+    }
+};
+
+impl::tc::tc(const std::string& ident, const bool has_cleanup) :
+    pimpl(new tc_impl(ident, has_cleanup))
+{
+}
+
+impl::tc::~tc(void)
+{
+    cwraps.erase(&pimpl->m_tc);
+    wraps.erase(&pimpl->m_tc);
+
+    atf_tc_fini(&pimpl->m_tc);
+}
+
+void
+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();
+    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;
+    }
+    *ptr = NULL;
+
+    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());
+    if (atf_is_error(err))
+        throw_atf_error(err);
+}
+
+bool
+impl::tc::has_config_var(const std::string& var)
+    const
+{
+    return atf_tc_has_config_var(&pimpl->m_tc, var.c_str());
+}
+
+bool
+impl::tc::has_md_var(const std::string& var)
+    const
+{
+    return atf_tc_has_md_var(&pimpl->m_tc, var.c_str());
+}
+
+const std::string
+impl::tc::get_config_var(const std::string& var)
+    const
+{
+    return atf_tc_get_config_var(&pimpl->m_tc, var.c_str());
+}
+
+const std::string
+impl::tc::get_config_var(const std::string& var, const std::string& defval)
+    const
+{
+    return atf_tc_get_config_var_wd(&pimpl->m_tc, var.c_str(), defval.c_str());
+}
+
+const std::string
+impl::tc::get_md_var(const std::string& var)
+    const
+{
+    return atf_tc_get_md_var(&pimpl->m_tc, var.c_str());
+}
+
+const impl::vars_map
+impl::tc::get_md_vars(void)
+    const
+{
+    vars_map vars;
+
+    char **array = atf_tc_get_md_vars(&pimpl->m_tc);
+    try {
+        char **ptr;
+        for (ptr = array; *ptr != NULL; ptr += 2)
+            vars[*ptr] = *(ptr + 1);
+    } catch (...) {
+        atf_utils_free_charpp(array);
+        throw;
+    }
+
+    return vars;
+}
+
+void
+impl::tc::set_md_var(const std::string& var, const std::string& val)
+{
+    atf_error_t err = atf_tc_set_md_var(&pimpl->m_tc, var.c_str(), val.c_str());
+    if (atf_is_error(err))
+        throw_atf_error(err);
+}
+
+void
+impl::tc::run(const std::string& resfile)
+    const
+{
+    atf_error_t err = atf_tc_run(&pimpl->m_tc, resfile.c_str());
+    if (atf_is_error(err))
+        throw_atf_error(err);
+}
+
+void
+impl::tc::run_cleanup(void)
+    const
+{
+    atf_error_t err = atf_tc_cleanup(&pimpl->m_tc);
+    if (atf_is_error(err))
+        throw_atf_error(err);
+}
+
+void
+impl::tc::head(void)
+{
+}
+
+void
+impl::tc::cleanup(void)
+    const
+{
+}
+
+void
+impl::tc::require_prog(const std::string& prog)
+    const
+{
+    atf_tc_require_prog(prog.c_str());
+}
+
+void
+impl::tc::pass(void)
+{
+    atf_tc_pass();
+}
+
+void
+impl::tc::fail(const std::string& reason)
+{
+    atf_tc_fail("%s", reason.c_str());
+}
+
+void
+impl::tc::fail_nonfatal(const std::string& reason)
+{
+    atf_tc_fail_nonfatal("%s", reason.c_str());
+}
+
+void
+impl::tc::skip(const std::string& reason)
+{
+    atf_tc_skip("%s", reason.c_str());
+}
+
+void
+impl::tc::check_errno(const char* file, const int line, const int exp_errno,
+                      const char* expr_str, const bool result)
+{
+    atf_tc_check_errno(file, line, exp_errno, expr_str, result);
+}
+
+void
+impl::tc::require_errno(const char* file, const int line, const int exp_errno,
+                        const char* expr_str, const bool result)
+{
+    atf_tc_require_errno(file, line, exp_errno, expr_str, result);
+}
+
+void
+impl::tc::expect_pass(void)
+{
+    atf_tc_expect_pass();
+}
+
+void
+impl::tc::expect_fail(const std::string& reason)
+{
+    atf_tc_expect_fail("%s", reason.c_str());
+}
+
+void
+impl::tc::expect_exit(const int exitcode, const std::string& reason)
+{
+    atf_tc_expect_exit(exitcode, "%s", reason.c_str());
+}
+
+void
+impl::tc::expect_signal(const int signo, const std::string& reason)
+{
+    atf_tc_expect_signal(signo, "%s", reason.c_str());
+}
+
+void
+impl::tc::expect_death(const std::string& reason)
+{
+    atf_tc_expect_death("%s", reason.c_str());
+}
+
+void
+impl::tc::expect_timeout(const std::string& reason)
+{
+    atf_tc_expect_timeout("%s", reason.c_str());
+}
+
+// ------------------------------------------------------------------------
+// Test program main code.
+// ------------------------------------------------------------------------
+
+namespace {
+
+typedef std::vector< impl::tc * > tc_vector;
+
+enum tc_part { BODY, CLEANUP };
+
+static void
+parse_vflag(const std::string& str, atf::tests::vars_map& vars)
+{
+    if (str.empty())
+        throw std::runtime_error("-v requires a non-empty argument");
+
+    std::vector< std::string > ws = atf::text::split(str, "=");
+    if (ws.size() == 1 && str[str.length() - 1] == '=') {
+        vars[ws[0]] = "";
+    } else {
+        if (ws.size() != 2)
+            throw std::runtime_error("-v requires an argument of the form "
+                                     "var=value");
+
+        vars[ws[0]] = ws[1];
+    }
+}
+
+static atf::fs::path
+handle_srcdir(const char* argv0, const std::string& srcdir_arg)
+{
+    atf::fs::path srcdir(".");
+
+    if (srcdir_arg.empty()) {
+        srcdir = atf::fs::path(argv0).branch_path();
+        if (srcdir.leaf_name() == ".libs")
+            srcdir = srcdir.branch_path();
+    } else
+        srcdir = atf::fs::path(srcdir_arg);
+
+    if (!atf::fs::exists(srcdir / Program_Name))
+        throw usage_error("Cannot find the test program in the source "
+                          "directory `%s'", srcdir.c_str());
+
+    if (!srcdir.is_absolute())
+        srcdir = srcdir.to_absolute();
+
+    return srcdir;
+}
+
+static void
+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;
+
+        tc->init(vars);
+    }
+}
+
+static int
+list_tcs(const tc_vector& tcs)
+{
+    detail::atf_tp_writer writer(std::cout);
+
+    for (tc_vector::const_iterator iter = tcs.begin();
+         iter != tcs.end(); iter++) {
+        const impl::vars_map vars = (*iter)->get_md_vars();
+
+        {
+            impl::vars_map::const_iterator iter2 = vars.find("ident");
+            INV(iter2 != vars.end());
+            writer.start_tc((*iter2).second);
+        }
+
+        for (impl::vars_map::const_iterator iter2 = vars.begin();
+             iter2 != vars.end(); iter2++) {
+            const std::string& key = (*iter2).first;
+            if (key != "ident")
+                writer.tc_meta_data(key, (*iter2).second);
+        }
+
+        writer.end_tc();
+    }
+
+    return EXIT_SUCCESS;
+}
+
+static impl::tc*
+find_tc(tc_vector tcs, const std::string& name)
+{
+    std::vector< std::string > ids;
+    for (tc_vector::iterator iter = tcs.begin();
+         iter != tcs.end(); iter++) {
+        impl::tc* tc = *iter;
+
+        if (tc->get_md_var("ident") == name)
+            return tc;
+    }
+    throw usage_error("Unknown test case `%s'", name.c_str());
+}
+
+static std::pair< std::string, tc_part >
+process_tcarg(const std::string& tcarg)
+{
+    const std::string::size_type pos = tcarg.find(':');
+    if (pos == std::string::npos) {
+        return std::make_pair(tcarg, BODY);
+    } else {
+        const std::string tcname = tcarg.substr(0, pos);
+
+        const std::string partname = tcarg.substr(pos + 1);
+        if (partname == "body")
+            return std::make_pair(tcname, BODY);
+        else if (partname == "cleanup")
+            return std::make_pair(tcname, CLEANUP);
+        else {
+            throw usage_error("Invalid test case part `%s'", partname.c_str());
+        }
+    }
+}
+
+static int
+run_tc(tc_vector& tcs, const std::string& tcarg, const atf::fs::path& resfile)
+{
+    const std::pair< std::string, tc_part > fields = process_tcarg(tcarg);
+
+    impl::tc* tc = find_tc(tcs, fields.first);
+
+    if (!atf::env::has("__RUNNING_INSIDE_ATF_RUN") || atf::env::get(
+        "__RUNNING_INSIDE_ATF_RUN") != "internal-yes-value")
+    {
+        std::cerr << Program_Name << ": WARNING: Running test cases outside "
+            "of kyua(1) is unsupported\n";
+        std::cerr << Program_Name << ": WARNING: No isolation nor timeout "
+            "control is being applied; you may get unexpected failures; see "
+            "atf-test-case(4)\n";
+    }
+
+    switch (fields.second) {
+    case BODY:
+        tc->run(resfile.str());
+        break;
+    case CLEANUP:
+        tc->run_cleanup();
+        break;
+    default:
+        UNREACHABLE;
+    }
+    return EXIT_SUCCESS;
+}
+
+static int
+safe_main(int argc, char** argv, void (*add_tcs)(tc_vector&))
+{
+    const char* argv0 = argv[0];
+
+    bool lflag = false;
+    atf::fs::path resfile("/dev/stdout");
+    std::string srcdir_arg;
+    atf::tests::vars_map vars;
+
+    int ch;
+    int old_opterr;
+
+    old_opterr = opterr;
+    ::opterr = 0;
+    while ((ch = ::getopt(argc, argv, GETOPT_POSIX ":lr:s:v:")) != -1) {
+        switch (ch) {
+        case 'l':
+            lflag = true;
+            break;
+
+        case 'r':
+            resfile = atf::fs::path(::optarg);
+            break;
+
+        case 's':
+            srcdir_arg = ::optarg;
+            break;
+
+        case 'v':
+            parse_vflag(::optarg, vars);
+            break;
+
+        case ':':
+            throw usage_error("Option -%c requires an argument.", ::optopt);
+            break;
+
+        case '?':
+        default:
+            throw usage_error("Unknown option -%c.", ::optopt);
+        }
+    }
+    argc -= optind;
+    argv += optind;
+
+    // Clear getopt state just in case the test wants to use it.
+    ::opterr = old_opterr;
+    ::optind = 1;
+#if defined(HAVE_OPTRESET)
+    ::optreset = 1;
+#endif
+
+    vars["srcdir"] = handle_srcdir(argv0, srcdir_arg).str();
+
+    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;
+    }
+
+    return errcode;
+}
+
+}  // anonymous namespace
+
+namespace atf {
+    namespace tests {
+        int run_tp(int, char**, void (*)(tc_vector&));
+    }
+}
+
+int
+impl::run_tp(int argc, char** argv, void (*add_tcs)(tc_vector&))
+{
+    try {
+        set_program_name(argv[0]);
+        return ::safe_main(argc, argv, add_tcs);
+    } catch (const usage_error& e) {
+        std::cerr
+            << Program_Name << ": ERROR: " << e.what() << '\n'
+            << Program_Name << ": See atf-test-program(1) for usage details.\n";
+        return EXIT_FAILURE;
+    }
+}

Added: vendor/atf/dist/atf-c++/tests.hpp
===================================================================
--- vendor/atf/dist/atf-c++/tests.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/tests.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,125 @@
+// 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_TESTS_HPP)
+#define ATF_CXX_TESTS_HPP
+
+#include <map>
+#include <memory>
+#include <string>
+
+extern "C" {
+#include <atf-c/defs.h>
+}
+
+namespace atf {
+namespace tests {
+
+namespace detail {
+
+class atf_tp_writer {
+    std::ostream& m_os;
+
+    bool m_is_first;
+
+public:
+    atf_tp_writer(std::ostream&);
+
+    void start_tc(const std::string&);
+    void end_tc(void);
+    void tc_meta_data(const std::string&, const std::string&);
+};
+
+bool match(const std::string&, const std::string&);
+
+} // namespace
+
+// ------------------------------------------------------------------------
+// The "vars_map" class.
+// ------------------------------------------------------------------------
+
+typedef std::map< std::string, std::string > vars_map;
+
+// ------------------------------------------------------------------------
+// The "tc" class.
+// ------------------------------------------------------------------------
+
+struct tc_impl;
+
+class tc {
+    // Non-copyable.
+    tc(const tc&);
+    tc& operator=(const tc&);
+
+    std::auto_ptr< tc_impl > pimpl;
+
+protected:
+    virtual void head(void);
+    virtual void body(void) const = 0;
+    virtual void cleanup(void) const;
+
+    void require_prog(const std::string&) const;
+
+    friend struct tc_impl;
+
+public:
+    tc(const std::string&, const bool);
+    virtual ~tc(void);
+
+    void init(const vars_map&);
+
+    const std::string get_config_var(const std::string&) const;
+    const std::string get_config_var(const std::string&, const std::string&)
+        const;
+    const std::string get_md_var(const std::string&) const;
+    const vars_map get_md_vars(void) const;
+    bool has_config_var(const std::string&) const;
+    bool has_md_var(const std::string&) const;
+    void set_md_var(const std::string&, const std::string&);
+
+    void run(const std::string&) const;
+    void run_cleanup(void) const;
+
+    // To be called from the child process only.
+    static void pass(void) ATF_DEFS_ATTRIBUTE_NORETURN;
+    static void fail(const std::string&) ATF_DEFS_ATTRIBUTE_NORETURN;
+    static void fail_nonfatal(const std::string&);
+    static void skip(const std::string&) ATF_DEFS_ATTRIBUTE_NORETURN;
+    static void check_errno(const char*, const int, const int, const char*,
+                            const bool);
+    static void require_errno(const char*, const int, const int, const char*,
+                              const bool);
+    static void expect_pass(void);
+    static void expect_fail(const std::string&);
+    static void expect_exit(const int, const std::string&);
+    static void expect_signal(const int, const std::string&);
+    static void expect_death(const std::string&);
+    static void expect_timeout(const std::string&);
+};
+
+} // namespace tests
+} // namespace atf
+
+#endif // !defined(ATF_CXX_TESTS_HPP)

Added: vendor/atf/dist/atf-c++/tests_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/tests_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/tests_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,190 @@
+// 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++/tests.hpp"
+
+extern "C" {
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+}
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+#include <atf-c++.hpp>
+
+#include "atf-c++/detail/text.hpp"
+
+// ------------------------------------------------------------------------
+// Tests for the "atf_tp_writer" class.
+// ------------------------------------------------------------------------
+
+static
+void
+print_indented(const std::string& str)
+{
+    std::vector< std::string > ws = atf::text::split(str, "\n");
+    for (std::vector< std::string >::const_iterator iter = ws.begin();
+         iter != ws.end(); iter++)
+        std::cout << ">>" << *iter << "<<\n";
+}
+
+// XXX Should this string handling and verbosity level be part of the
+// ATF_REQUIRE_EQ macro?  It may be hard to predict sometimes that a
+// string can have newlines in it, and so the error message generated
+// at the moment will be bogus if there are some.
+static
+void
+check_equal(const atf::tests::tc& tc, const std::string& str,
+            const std::string& exp)
+{
+    if (str != exp) {
+        std::cout << "String equality check failed.\n"
+            "Adding >> and << to delimit the string boundaries below.\n";
+        std::cout << "GOT:\n";
+        print_indented(str);
+        std::cout << "EXPECTED:\n";
+        print_indented(exp);
+        tc.fail("Constructed string differs from the expected one");
+    }
+}
+
+ATF_TEST_CASE(atf_tp_writer);
+ATF_TEST_CASE_HEAD(atf_tp_writer)
+{
+    set_md_var("descr", "Verifies the application/X-atf-tp writer");
+}
+ATF_TEST_CASE_BODY(atf_tp_writer)
+{
+    std::ostringstream expss;
+    std::ostringstream ss;
+
+#define RESET \
+    expss.str(""); \
+    ss.str("")
+
+#define CHECK \
+    check_equal(*this, ss.str(), expss.str())
+
+    {
+        RESET;
+
+        atf::tests::detail::atf_tp_writer w(ss);
+        expss << "Content-Type: application/X-atf-tp; version=\"1\"\n\n";
+        CHECK;
+    }
+
+    {
+        RESET;
+
+        atf::tests::detail::atf_tp_writer w(ss);
+        expss << "Content-Type: application/X-atf-tp; version=\"1\"\n\n";
+        CHECK;
+
+        w.start_tc("test1");
+        expss << "ident: test1\n";
+        CHECK;
+
+        w.end_tc();
+        CHECK;
+    }
+
+    {
+        RESET;
+
+        atf::tests::detail::atf_tp_writer w(ss);
+        expss << "Content-Type: application/X-atf-tp; version=\"1\"\n\n";
+        CHECK;
+
+        w.start_tc("test1");
+        expss << "ident: test1\n";
+        CHECK;
+
+        w.end_tc();
+        CHECK;
+
+        w.start_tc("test2");
+        expss << "\nident: test2\n";
+        CHECK;
+
+        w.end_tc();
+        CHECK;
+    }
+
+    {
+        RESET;
+
+        atf::tests::detail::atf_tp_writer w(ss);
+        expss << "Content-Type: application/X-atf-tp; version=\"1\"\n\n";
+        CHECK;
+
+        w.start_tc("test1");
+        expss << "ident: test1\n";
+        CHECK;
+
+        w.tc_meta_data("descr", "the description");
+        expss << "descr: the description\n";
+        CHECK;
+
+        w.end_tc();
+        CHECK;
+
+        w.start_tc("test2");
+        expss << "\nident: test2\n";
+        CHECK;
+
+        w.tc_meta_data("descr", "second test case");
+        expss << "descr: second test case\n";
+        CHECK;
+
+        w.tc_meta_data("require.progs", "/bin/cp");
+        expss << "require.progs: /bin/cp\n";
+        CHECK;
+
+        w.tc_meta_data("X-custom", "foo bar baz");
+        expss << "X-custom: foo bar baz\n";
+        CHECK;
+
+        w.end_tc();
+        CHECK;
+    }
+
+#undef CHECK
+#undef RESET
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    // Add tests for the "atf_tp_writer" class.
+    ATF_ADD_TEST_CASE(tcs, atf_tp_writer);
+}

Added: vendor/atf/dist/atf-c++/unused_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/unused_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/unused_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,48 @@
+// Copyright (c) 2012 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++.hpp>
+
+ATF_TEST_CASE(this_is_used);
+ATF_TEST_CASE_HEAD(this_is_used)
+{
+}
+ATF_TEST_CASE_BODY(this_is_used)
+{
+}
+
+ATF_TEST_CASE(this_is_unused);
+ATF_TEST_CASE_HEAD(this_is_unused)
+{
+}
+ATF_TEST_CASE_BODY(this_is_unused)
+{
+}
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    ATF_ADD_TEST_CASE(tcs, this_is_used);
+    //ATF_ADD_TEST_CASE(tcs, this_is_unused);
+}

Added: vendor/atf/dist/atf-c++/utils.cpp
===================================================================
--- vendor/atf/dist/atf-c++/utils.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/utils.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,100 @@
+// 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++/utils.hpp"
+
+extern "C" {
+#include "atf-c/utils.h"
+}
+
+#include <cstdlib>
+#include <iostream>
+
+void
+atf::utils::cat_file(const std::string& path, const std::string& prefix)
+{
+    atf_utils_cat_file(path.c_str(), prefix.c_str());
+}
+
+void
+atf::utils::copy_file(const std::string& source, const std::string& destination)
+{
+    atf_utils_copy_file(source.c_str(), destination.c_str());
+}
+
+bool
+atf::utils::compare_file(const std::string& path, const std::string& contents)
+{
+    return atf_utils_compare_file(path.c_str(), contents.c_str());
+}
+
+void
+atf::utils::create_file(const std::string& path, const std::string& contents)
+{
+    atf_utils_create_file(path.c_str(), "%s", contents.c_str());
+}
+
+bool
+atf::utils::file_exists(const std::string& path)
+{
+    return atf_utils_file_exists(path.c_str());
+}
+
+pid_t
+atf::utils::fork(void)
+{
+    std::cout.flush();
+    std::cerr.flush();
+    return atf_utils_fork();
+}
+
+bool
+atf::utils::grep_file(const std::string& regex, const std::string& path)
+{
+    return atf_utils_grep_file("%s", path.c_str(), regex.c_str());
+}
+
+bool
+atf::utils::grep_string(const std::string& regex, const std::string& str)
+{
+    return atf_utils_grep_string("%s", str.c_str(), regex.c_str());
+}
+
+void
+atf::utils::redirect(const int fd, const std::string& path)
+{
+    if (fd == STDOUT_FILENO)
+        std::cout.flush();
+    else if (fd == STDERR_FILENO)
+        std::cerr.flush();
+    atf_utils_redirect(fd, path.c_str());
+}
+
+void
+atf::utils::wait(const pid_t pid, const int exitstatus,
+                 const std::string& expout, const std::string& experr)
+{
+    atf_utils_wait(pid, exitstatus, expout.c_str(), experr.c_str());
+}

Added: vendor/atf/dist/atf-c++/utils.hpp
===================================================================
--- vendor/atf/dist/atf-c++/utils.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/utils.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,64 @@
+// 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_UTILS_HPP)
+#define ATF_CXX_UTILS_HPP
+
+extern "C" {
+#include <unistd.h>
+}
+
+#include <string>
+
+namespace atf {
+namespace utils {
+
+void cat_file(const std::string&, const std::string&);
+bool compare_file(const std::string&, const std::string&);
+void copy_file(const std::string&, const std::string&);
+void create_file(const std::string&, const std::string&);
+bool file_exists(const std::string&);
+pid_t fork(void);
+bool grep_file(const std::string&, const std::string&);
+bool grep_string(const std::string&, const std::string&);
+void redirect(const int, const std::string&);
+void wait(const pid_t, const int, const std::string&, const std::string&);
+
+template< typename Collection >
+bool
+grep_collection(const std::string& regexp, const Collection& collection)
+{
+    for (typename Collection::const_iterator iter = collection.begin();
+         iter != collection.end(); ++iter) {
+        if (grep_string(regexp, *iter))
+            return true;
+    }
+    return false;
+}
+
+} // namespace utils
+} // namespace atf
+
+#endif // !defined(ATF_CXX_UTILS_HPP)

Added: vendor/atf/dist/atf-c++/utils_test.cpp
===================================================================
--- vendor/atf/dist/atf-c++/utils_test.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++/utils_test.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,509 @@
+// 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++/utils.hpp"
+
+extern "C" {
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+}
+
+#include <cstdlib>
+#include <iostream>
+#include <set>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <atf-c++.hpp>
+
+static std::string
+read_file(const std::string& path)
+{
+    char buffer[1024];
+
+    const int fd = open(path.c_str(), O_RDONLY);
+    if (fd == -1)
+        ATF_FAIL("Cannot open " + path);
+    const ssize_t length = read(fd, buffer, sizeof(buffer) - 1);
+    close(fd);
+    ATF_REQUIRE(length != -1);
+    if (length == sizeof(buffer) - 1)
+        ATF_FAIL("Internal buffer not long enough to read temporary file");
+    ((char *)buffer)[length] = '\0';
+
+    return buffer;
+}
+
+// ------------------------------------------------------------------------
+// Tests cases for the free functions.
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE_WITHOUT_HEAD(cat_file__empty);
+ATF_TEST_CASE_BODY(cat_file__empty)
+{
+    atf::utils::create_file("file.txt", "");
+    atf::utils::redirect(STDOUT_FILENO, "captured.txt");
+    atf::utils::cat_file("file.txt", "PREFIX");
+    std::cout.flush();
+    close(STDOUT_FILENO);
+
+    ATF_REQUIRE_EQ("", read_file("captured.txt"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(cat_file__one_line);
+ATF_TEST_CASE_BODY(cat_file__one_line)
+{
+    atf::utils::create_file("file.txt", "This is a single line\n");
+    atf::utils::redirect(STDOUT_FILENO, "captured.txt");
+    atf::utils::cat_file("file.txt", "PREFIX");
+    std::cout.flush();
+    close(STDOUT_FILENO);
+
+    ATF_REQUIRE_EQ("PREFIXThis is a single line\n", read_file("captured.txt"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(cat_file__several_lines);
+ATF_TEST_CASE_BODY(cat_file__several_lines)
+{
+    atf::utils::create_file("file.txt", "First\nSecond line\nAnd third\n");
+    atf::utils::redirect(STDOUT_FILENO, "captured.txt");
+    atf::utils::cat_file("file.txt", ">");
+    std::cout.flush();
+    close(STDOUT_FILENO);
+
+    ATF_REQUIRE_EQ(">First\n>Second line\n>And third\n",
+                   read_file("captured.txt"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(cat_file__no_newline_eof);
+ATF_TEST_CASE_BODY(cat_file__no_newline_eof)
+{
+    atf::utils::create_file("file.txt", "Foo\n bar baz");
+    atf::utils::redirect(STDOUT_FILENO, "captured.txt");
+    atf::utils::cat_file("file.txt", "PREFIX");
+    std::cout.flush();
+    close(STDOUT_FILENO);
+
+    ATF_REQUIRE_EQ("PREFIXFoo\nPREFIX bar baz", read_file("captured.txt"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__empty__match);
+ATF_TEST_CASE_BODY(compare_file__empty__match)
+{
+    atf::utils::create_file("test.txt", "");
+    ATF_REQUIRE(atf::utils::compare_file("test.txt", ""));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__empty__not_match);
+ATF_TEST_CASE_BODY(compare_file__empty__not_match)
+{
+    atf::utils::create_file("test.txt", "");
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", "foo"));
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", " "));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__short__match);
+ATF_TEST_CASE_BODY(compare_file__short__match)
+{
+    atf::utils::create_file("test.txt", "this is a short file");
+    ATF_REQUIRE(atf::utils::compare_file("test.txt", "this is a short file"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__short__not_match);
+ATF_TEST_CASE_BODY(compare_file__short__not_match)
+{
+    atf::utils::create_file("test.txt", "this is a short file");
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", ""));
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a Short file"));
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a short fil"));
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", "this is a short file "));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__long__match);
+ATF_TEST_CASE_BODY(compare_file__long__match)
+{
+    char long_contents[3456];
+    size_t i = 0;
+    for (; i < sizeof(long_contents) - 1; i++)
+        long_contents[i] = '0' + (i % 10);
+    long_contents[i] = '\0';
+    atf::utils::create_file("test.txt", long_contents);
+
+    ATF_REQUIRE(atf::utils::compare_file("test.txt", long_contents));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(compare_file__long__not_match);
+ATF_TEST_CASE_BODY(compare_file__long__not_match)
+{
+    char long_contents[3456];
+    size_t i = 0;
+    for (; i < sizeof(long_contents) - 1; i++)
+        long_contents[i] = '0' + (i % 10);
+    long_contents[i] = '\0';
+    atf::utils::create_file("test.txt", long_contents);
+
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", ""));
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", "\n"));
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", "0123456789"));
+    long_contents[i - 1] = 'Z';
+    ATF_REQUIRE(!atf::utils::compare_file("test.txt", long_contents));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(copy_file__empty);
+ATF_TEST_CASE_BODY(copy_file__empty)
+{
+    atf::utils::create_file("src.txt", "");
+    ATF_REQUIRE(chmod("src.txt", 0520) != -1);
+
+    atf::utils::copy_file("src.txt", "dest.txt");
+    ATF_REQUIRE(atf::utils::compare_file("dest.txt", ""));
+    struct stat sb;
+    ATF_REQUIRE(stat("dest.txt", &sb) != -1);
+    ATF_REQUIRE_EQ(0520, sb.st_mode & 0xfff);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(copy_file__some_contents);
+ATF_TEST_CASE_BODY(copy_file__some_contents)
+{
+    atf::utils::create_file("src.txt", "This is a\ntest file\n");
+    atf::utils::copy_file("src.txt", "dest.txt");
+    ATF_REQUIRE(atf::utils::compare_file("dest.txt", "This is a\ntest file\n"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(create_file);
+ATF_TEST_CASE_BODY(create_file)
+{
+    atf::utils::create_file("test.txt", "This is a %d test");
+
+    ATF_REQUIRE_EQ("This is a %d test", read_file("test.txt"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(file_exists);
+ATF_TEST_CASE_BODY(file_exists)
+{
+    atf::utils::create_file("test.txt", "foo");
+
+    ATF_REQUIRE( atf::utils::file_exists("test.txt"));
+    ATF_REQUIRE( atf::utils::file_exists("./test.txt"));
+    ATF_REQUIRE(!atf::utils::file_exists("./test.tx"));
+    ATF_REQUIRE(!atf::utils::file_exists("test.txt2"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(fork);
+ATF_TEST_CASE_BODY(fork)
+{
+    std::cout << "Should not get into child\n";
+    std::cerr << "Should not get into child\n";
+    pid_t pid = atf::utils::fork();
+    if (pid == 0) {
+        std::cout << "Child stdout\n";
+        std::cerr << "Child stderr\n";
+        exit(EXIT_SUCCESS);
+    }
+
+    int status;
+    ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
+    ATF_REQUIRE(WIFEXITED(status));
+    ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+    std::ostringstream out_name;
+    out_name << "atf_utils_fork_" << pid << "_out.txt";
+    std::ostringstream err_name;
+    err_name << "atf_utils_fork_" << pid << "_err.txt";
+
+    ATF_REQUIRE_EQ("Child stdout\n", read_file(out_name.str()));
+    ATF_REQUIRE_EQ("Child stderr\n", read_file(err_name.str()));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(grep_collection__set);
+ATF_TEST_CASE_BODY(grep_collection__set)
+{
+    std::set< std::string > strings;
+    strings.insert("First");
+    strings.insert("Second");
+
+    ATF_REQUIRE( atf::utils::grep_collection("irs", strings));
+    ATF_REQUIRE( atf::utils::grep_collection("cond", strings));
+    ATF_REQUIRE(!atf::utils::grep_collection("Third", strings));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(grep_collection__vector);
+ATF_TEST_CASE_BODY(grep_collection__vector)
+{
+    std::vector< std::string > strings;
+    strings.push_back("First");
+    strings.push_back("Second");
+
+    ATF_REQUIRE( atf::utils::grep_collection("irs", strings));
+    ATF_REQUIRE( atf::utils::grep_collection("cond", strings));
+    ATF_REQUIRE(!atf::utils::grep_collection("Third", strings));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(grep_file);
+ATF_TEST_CASE_BODY(grep_file)
+{
+    atf::utils::create_file("test.txt", "line1\nthe second line\naaaabbbb\n");
+
+    ATF_REQUIRE(atf::utils::grep_file("line1", "test.txt"));
+    ATF_REQUIRE(atf::utils::grep_file("second line", "test.txt"));
+    ATF_REQUIRE(atf::utils::grep_file("aa.*bb", "test.txt"));
+    ATF_REQUIRE(!atf::utils::grep_file("foo", "test.txt"));
+    ATF_REQUIRE(!atf::utils::grep_file("bar", "test.txt"));
+    ATF_REQUIRE(!atf::utils::grep_file("aaaaa", "test.txt"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(grep_string);
+ATF_TEST_CASE_BODY(grep_string)
+{
+    const char *str = "a string - aaaabbbb";
+    ATF_REQUIRE(atf::utils::grep_string("a string", str));
+    ATF_REQUIRE(atf::utils::grep_string("^a string", str));
+    ATF_REQUIRE(atf::utils::grep_string("aaaabbbb$", str));
+    ATF_REQUIRE(atf::utils::grep_string("aa.*bb", str));
+    ATF_REQUIRE(!atf::utils::grep_string("foo", str));
+    ATF_REQUIRE(!atf::utils::grep_string("bar", str));
+    ATF_REQUIRE(!atf::utils::grep_string("aaaaa", str));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(redirect__stdout);
+ATF_TEST_CASE_BODY(redirect__stdout)
+{
+    std::cout << "Buffer this";
+    atf::utils::redirect(STDOUT_FILENO, "captured.txt");
+    std::cout << "The printed message";
+    std::cout.flush();
+
+    ATF_REQUIRE_EQ("The printed message", read_file("captured.txt"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(redirect__stderr);
+ATF_TEST_CASE_BODY(redirect__stderr)
+{
+    std::cerr << "Buffer this";
+    atf::utils::redirect(STDERR_FILENO, "captured.txt");
+    std::cerr << "The printed message";
+    std::cerr.flush();
+
+    ATF_REQUIRE_EQ("The printed message", read_file("captured.txt"));
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(redirect__other);
+ATF_TEST_CASE_BODY(redirect__other)
+{
+    const std::string message = "Foo bar\nbaz\n";
+    atf::utils::redirect(15, "captured.txt");
+    ATF_REQUIRE(write(15, message.c_str(), message.length()) != -1);
+    close(15);
+
+    ATF_REQUIRE_EQ(message, read_file("captured.txt"));
+}
+
+static void
+fork_and_wait(const int exitstatus, const char* expout, const char* experr)
+{
+    const pid_t pid = atf::utils::fork();
+    if (pid == 0) {
+        std::cout << "Some output\n";
+        std::cerr << "Some error\n";
+        exit(123);
+    }
+    atf::utils::wait(pid, exitstatus, expout, experr);
+    exit(EXIT_SUCCESS);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(wait__ok);
+ATF_TEST_CASE_BODY(wait__ok)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(123, "Some output\n", "Some error\n");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+    }
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(wait__ok_nested);
+ATF_TEST_CASE_BODY(wait__ok_nested)
+{
+    const pid_t parent = atf::utils::fork();
+    ATF_REQUIRE(parent != -1);
+    if (parent == 0) {
+        const pid_t child = atf::utils::fork();
+        ATF_REQUIRE(child != -1);
+        if (child == 0) {
+            std::cerr.flush();
+            std::cout << "Child output\n";
+            std::cout.flush();
+            std::cerr << "Child error\n";
+            std::exit(50);
+        } else {
+            std::cout << "Parent output\n";
+            std::cerr << "Parent error\n";
+            atf::utils::wait(child, 50, "Child output\n", "Child error\n");
+            std::exit(40);
+        }
+    } else {
+        atf::utils::wait(parent, 40,
+                         "Parent output\n"
+                         "subprocess stdout: Child output\n"
+                         "subprocess stderr: Child error\n",
+                         "Parent error\n");
+    }
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_exitstatus);
+ATF_TEST_CASE_BODY(wait__invalid_exitstatus)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(120, "Some output\n", "Some error\n");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
+    }
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_stdout);
+ATF_TEST_CASE_BODY(wait__invalid_stdout)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(123, "Some output foo\n", "Some error\n");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
+    }
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(wait__invalid_stderr);
+ATF_TEST_CASE_BODY(wait__invalid_stderr)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(123, "Some output\n", "Some error foo\n");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_FAILURE, WEXITSTATUS(status));
+    }
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(wait__save_stdout);
+ATF_TEST_CASE_BODY(wait__save_stdout)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(123, "save:my-output.txt", "Some error\n");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+        ATF_REQUIRE(atf::utils::compare_file("my-output.txt", "Some output\n"));
+    }
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(wait__save_stderr);
+ATF_TEST_CASE_BODY(wait__save_stderr)
+{
+    const pid_t control = fork();
+    ATF_REQUIRE(control != -1);
+    if (control == 0)
+        fork_and_wait(123, "Some output\n", "save:my-output.txt");
+    else {
+        int status;
+        ATF_REQUIRE(waitpid(control, &status, 0) != -1);
+        ATF_REQUIRE(WIFEXITED(status));
+        ATF_REQUIRE_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+        ATF_REQUIRE(atf::utils::compare_file("my-output.txt", "Some error\n"));
+    }
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    // Add the test for the free functions.
+    ATF_ADD_TEST_CASE(tcs, cat_file__empty);
+    ATF_ADD_TEST_CASE(tcs, cat_file__one_line);
+    ATF_ADD_TEST_CASE(tcs, cat_file__several_lines);
+    ATF_ADD_TEST_CASE(tcs, cat_file__no_newline_eof);
+
+    ATF_ADD_TEST_CASE(tcs, compare_file__empty__match);
+    ATF_ADD_TEST_CASE(tcs, compare_file__empty__not_match);
+    ATF_ADD_TEST_CASE(tcs, compare_file__short__match);
+    ATF_ADD_TEST_CASE(tcs, compare_file__short__not_match);
+    ATF_ADD_TEST_CASE(tcs, compare_file__long__match);
+    ATF_ADD_TEST_CASE(tcs, compare_file__long__not_match);
+
+    ATF_ADD_TEST_CASE(tcs, copy_file__empty);
+    ATF_ADD_TEST_CASE(tcs, copy_file__some_contents);
+
+    ATF_ADD_TEST_CASE(tcs, create_file);
+
+    ATF_ADD_TEST_CASE(tcs, file_exists);
+
+    ATF_ADD_TEST_CASE(tcs, fork);
+
+    ATF_ADD_TEST_CASE(tcs, grep_collection__set);
+    ATF_ADD_TEST_CASE(tcs, grep_collection__vector);
+    ATF_ADD_TEST_CASE(tcs, grep_file);
+    ATF_ADD_TEST_CASE(tcs, grep_string);
+
+    ATF_ADD_TEST_CASE(tcs, redirect__stdout);
+    ATF_ADD_TEST_CASE(tcs, redirect__stderr);
+    ATF_ADD_TEST_CASE(tcs, redirect__other);
+
+    ATF_ADD_TEST_CASE(tcs, wait__ok);
+    ATF_ADD_TEST_CASE(tcs, wait__ok_nested);
+    ATF_ADD_TEST_CASE(tcs, wait__invalid_exitstatus);
+    ATF_ADD_TEST_CASE(tcs, wait__invalid_stdout);
+    ATF_ADD_TEST_CASE(tcs, wait__invalid_stderr);
+    ATF_ADD_TEST_CASE(tcs, wait__save_stdout);
+    ATF_ADD_TEST_CASE(tcs, wait__save_stderr);
+}

Added: vendor/atf/dist/atf-c++.hpp
===================================================================
--- vendor/atf/dist/atf-c++.hpp	                        (rev 0)
+++ vendor/atf/dist/atf-c++.hpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,32 @@
+// 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_HPP)
+#define ATF_CXX_HPP
+
+#include <atf-c++/macros.hpp>
+#include <atf-c++/utils.hpp>
+
+#endif // !defined(ATF_CXX_HPP)

Added: vendor/atf/dist/atf-c.h
===================================================================
--- vendor/atf/dist/atf-c.h	                        (rev 0)
+++ vendor/atf/dist/atf-c.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,33 @@
+/* Copyright (c) 2008 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_C_H)
+#define ATF_C_H
+
+#include <atf-c/error.h>
+#include <atf-c/macros.h>
+#include <atf-c/utils.h>
+
+#endif /* !defined(ATF_C_H) */

Added: vendor/atf/dist/atf-sh/Kyuafile
===================================================================
--- vendor/atf/dist/atf-sh/Kyuafile	                        (rev 0)
+++ vendor/atf/dist/atf-sh/Kyuafile	2018-06-27 00:27:29 UTC (rev 11143)
@@ -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"}

Added: vendor/atf/dist/atf-sh/atf-check.1
===================================================================
--- vendor/atf/dist/atf-sh/atf-check.1	                        (rev 0)
+++ vendor/atf/dist/atf-sh/atf-check.1	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,162 @@
+.\" Copyright (c) 2008 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.
+.Dd March 6, 2017
+.Dt ATF-CHECK 1
+.Os
+.Sh NAME
+.Nm atf-check
+.Nd executes a command and analyzes its results
+.Sh SYNOPSIS
+.Nm
+.Op Fl s Ar qual:value
+.Op Fl o Ar action:arg ...
+.Op Fl e Ar action:arg ...
+.Op Fl x
+.Ar command
+.Sh DESCRIPTION
+.Nm
+executes a given command and analyzes its results, including
+exit code, stdout and stderr.
+.Pp
+.Bf Em
+Test cases must use
+.Xr atf-sh 3 Ns ' Ns s
+.Nm atf_check
+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
+.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.
+.Pp
+The following options are available:
+.Bl -tag  -width XqualXvalueXX
+.It Fl s Ar qual:value
+Analyzes termination status.
+Must be one of:
+.Bl -tag -width signal:<value> -compact
+.It Ar exit:<value>
+checks that the program exited cleanly and that its exit status is equal to
+.Va value .
+The exit code can be omitted altogether, in which case any clean exit is
+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
+.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.
+.El
+.Pp
+Most of these checkers can be prefixed by the
+.Sq not-
+string, which effectively reverses the check.
+.It Fl o Ar action:arg
+Analyzes standard output.
+Must be one of:
+.Bl -tag -width inline:<value> -compact
+.It Ar empty
+checks that stdout is empty
+.It Ar ignore
+ignores stdout
+.It Ar file:<path>
+compares stdout with given file
+.It Ar inline:<value>
+compares stdout with inline value
+.It Ar match:<regexp>
+looks for a regular expression in stdout
+.It Ar save:<path>
+saves stdout to given file
+.El
+.Pp
+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)
+.It Fl x
+Executes
+.Ar command
+as a shell command line, executing it with the system shell defined by
+.Va ATF_SHELL .
+You should avoid using this flag if at all possible to prevent shell quoting
+issues.
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width ATFXSHELLXX -compact
+.It Va ATF_SHELL
+Path to the system shell to be used when the
+.Fl x
+is given to run commands.
+.El
+.Sh EXIT STATUS
+.Nm
+exits 0 on success, and other (unspecified) value on failure.
+.Sh EXAMPLES
+The following are sample invocations from within a test case.
+Note that we use the
+.Nm atf_check
+function provided by
+.Xr atf-sh 3
+instead of executing
+.Nm
+directly:
+.Bd -literal -offset indent
+# Exit code 0, nothing on stdout/stderr
+atf_check 'true'
+
+# Typical usage if failure is expected
+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'
+
+# Checking for a crash
+atf_check -s signal:sigsegv my_program
+
+# Combined checks
+atf_check -o match:foo -o not-match:bar echo foo baz
+.Ed
+.Sh SEE ALSO
+.Xr atf-sh 1

Added: vendor/atf/dist/atf-sh/atf-check.cpp
===================================================================
--- vendor/atf/dist/atf-sh/atf-check.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-sh/atf-check.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,834 @@
+// Copyright (c) 2008 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.
+
+extern "C" {
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <limits.h>
+#include <signal.h>
+#include <unistd.h>
+}
+
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <ios>
+#include <iostream>
+#include <iterator>
+#include <list>
+#include <memory>
+#include <utility>
+
+#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"
+#include "atf-c++/detail/process.hpp"
+#include "atf-c++/detail/sanity.hpp"
+#include "atf-c++/detail/text.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+namespace {
+
+enum status_check_t {
+    sc_exit,
+    sc_ignore,
+    sc_signal,
+};
+
+struct status_check {
+    status_check_t type;
+    bool negated;
+    int value;
+
+    status_check(const status_check_t& p_type, const bool p_negated,
+                 const int p_value) :
+        type(p_type),
+        negated(p_negated),
+        value(p_value)
+    {
+    }
+};
+
+enum output_check_t {
+    oc_ignore,
+    oc_inline,
+    oc_file,
+    oc_empty,
+    oc_match,
+    oc_save
+};
+
+struct output_check {
+    output_check_t type;
+    bool negated;
+    std::string value;
+
+    output_check(const output_check_t& p_type, const bool p_negated,
+                 const std::string& p_value) :
+        type(p_type),
+        negated(p_negated),
+        value(p_value)
+    {
+    }
+};
+
+class temp_file : public std::ostream {
+    std::auto_ptr< atf::fs::path > m_path;
+    int m_fd;
+
+public:
+    temp_file(const char* pattern) :
+        std::ostream(NULL),
+        m_fd(-1)
+    {
+        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());
+        if (m_fd == -1)
+            throw atf::system_error("atf_check::temp_file::temp_file(" +
+                                    file.str() + ")", "mkstemp(3) failed",
+                                    errno);
+
+        m_path.reset(new atf::fs::path(buf.get()));
+    }
+
+    ~temp_file(void)
+    {
+        close();
+        try {
+            remove(*m_path);
+        } catch (const atf::system_error&) {
+            // Ignore deletion errors.
+        }
+    }
+
+    const atf::fs::path&
+    get_path(void) const
+    {
+        return *m_path;
+    }
+
+    void
+    write(const std::string& text)
+    {
+        if (::write(m_fd, text.c_str(), text.size()) == -1)
+            throw atf::system_error("atf_check", "write(2) failed", errno);
+    }
+
+    void
+    close(void)
+    {
+        if (m_fd != -1) {
+            flush();
+            ::close(m_fd);
+            m_fd = -1;
+        }
+    }
+};
+
+} // anonymous namespace
+
+static int
+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");
+        return value;
+    } catch (const std::runtime_error&) {
+        throw atf::application::usage_error("Invalid exit code for -s option; "
+            "must be an integer in range 0-255");
+    }
+}
+
+static struct name_number {
+    const char *name;
+    int signo;
+} signal_names_to_numbers[] = {
+    { "hup", SIGHUP },
+    { "int", SIGINT },
+    { "quit", SIGQUIT },
+    { "trap", SIGTRAP },
+    { "abrt", SIGABRT },
+    { "kill", SIGKILL },
+    { "segv", SIGSEGV },
+    { "pipe", SIGPIPE },
+    { "alrm", SIGALRM },
+    { "term", SIGTERM },
+    { "usr1", SIGUSR1 },
+    { "usr2", SIGUSR2 },
+    { NULL, INT_MIN },
+};
+
+static int
+signal_name_to_number(const std::string& str)
+{
+    struct name_number* iter = signal_names_to_numbers;
+    int signo = INT_MIN;
+    while (signo == INT_MIN && iter->name != NULL) {
+        if (str == iter->name || str == std::string("sig") + iter->name)
+            signo = iter->signo;
+        else
+            iter++;
+    }
+    return signo;
+}
+
+static int
+parse_signal(const std::string& str)
+{
+    const int signo = signal_name_to_number(str);
+    if (signo == INT_MIN) {
+        try {
+            return atf::text::to_type< int >(str);
+        } catch (std::runtime_error) {
+            throw atf::application::usage_error("Invalid signal name or number "
+                "in -s option");
+        }
+    }
+    INV(signo != INT_MIN);
+    return signo;
+}
+
+static status_check
+parse_status_check_arg(const std::string& arg)
+{
+    const std::string::size_type delimiter = arg.find(':');
+    bool negated = (arg.compare(0, 4, "not-") == 0);
+    const std::string action_str = arg.substr(0, delimiter);
+    const std::string action = negated ? action_str.substr(4) : action_str;
+    const std::string value_str = (
+        delimiter == std::string::npos ? "" : arg.substr(delimiter + 1));
+    int value;
+
+    status_check_t type;
+    if (action == "eq") {
+        // Deprecated; use exit instead.  TODO: Remove after 0.10.
+        type = sc_exit;
+        if (negated)
+            throw atf::application::usage_error("Cannot negate eq checker");
+        negated = false;
+        value = parse_exit_code(value_str);
+    } else if (action == "exit") {
+        type = sc_exit;
+        if (value_str.empty())
+            value = INT_MIN;
+        else
+            value = parse_exit_code(value_str);
+    } else if (action == "ignore") {
+        if (negated)
+            throw atf::application::usage_error("Cannot negate ignore checker");
+        type = sc_ignore;
+        value = INT_MIN;
+    } else if (action == "ne") {
+        // Deprecated; use not-exit instead.  TODO: Remove after 0.10.
+        type = sc_exit;
+        if (negated)
+            throw atf::application::usage_error("Cannot negate ne checker");
+        negated = true;
+        value = parse_exit_code(value_str);
+    } else if (action == "signal") {
+        type = sc_signal;
+        if (value_str.empty())
+            value = INT_MIN;
+        else
+            value = parse_signal(value_str);
+    } else
+        throw atf::application::usage_error("Invalid status checker");
+
+    return status_check(type, negated, value);
+}
+
+static
+output_check
+parse_output_check_arg(const std::string& arg)
+{
+    const std::string::size_type delimiter = arg.find(':');
+    const bool negated = (arg.compare(0, 4, "not-") == 0);
+    const std::string action_str = arg.substr(0, delimiter);
+    const std::string action = negated ? action_str.substr(4) : action_str;
+
+    output_check_t type;
+    if (action == "empty")
+        type = oc_empty;
+    else if (action == "file")
+        type = oc_file;
+    else if (action == "ignore") {
+        if (negated)
+            throw atf::application::usage_error("Cannot negate ignore checker");
+        type = oc_ignore;
+    } else if (action == "inline")
+        type = oc_inline;
+    else if (action == "match")
+        type = oc_match;
+    else if (action == "save") {
+        if (negated)
+            throw atf::application::usage_error("Cannot negate save checker");
+        type = oc_save;
+    } else
+        throw atf::application::usage_error("Invalid output checker");
+
+    return output_check(type, negated, arg.substr(delimiter + 1));
+}
+
+static
+std::string
+flatten_argv(char* const* argv)
+{
+    std::string cmdline;
+
+    char* const* arg = &argv[0];
+    while (*arg != NULL) {
+        if (arg != &argv[0])
+            cmdline += ' ';
+
+        cmdline += *arg;
+
+        arg++;
+    }
+
+    return cmdline;
+}
+
+static
+std::auto_ptr< atf::check::check_result >
+execute(const char* const* argv)
+{
+    // TODO: This should go to stderr... but fixing it now may be hard as test
+    // cases out there might be relying on stderr being silent.
+    std::cout << "Executing command [ ";
+    for (int i = 0; argv[i] != NULL; ++i)
+        std::cout << argv[i] << " ";
+    std::cout << "]\n";
+    std::cout.flush();
+
+    atf::process::argv_array argva(argv);
+    return atf::check::exec(argva);
+}
+
+static
+std::auto_ptr< atf::check::check_result >
+execute_with_shell(char* const* argv)
+{
+    const std::string cmd = flatten_argv(argv);
+
+    const char* sh_argv[4];
+    sh_argv[0] = atf::env::get("ATF_SHELL", ATF_SHELL).c_str();
+    sh_argv[1] = "-c";
+    sh_argv[2] = cmd.c_str();
+    sh_argv[3] = NULL;
+    return execute(sh_argv);
+}
+
+static
+void
+cat_file(const atf::fs::path& path)
+{
+    std::ifstream stream(path.c_str());
+    if (!stream)
+        throw std::runtime_error("Failed to open " + path.str());
+
+    stream >> std::noskipws;
+    std::istream_iterator< char > begin(stream), end;
+    std::ostream_iterator< char > out(std::cerr);
+    std::copy(begin, end, out);
+
+    stream.close();
+}
+
+static
+bool
+grep_file(const atf::fs::path& path, const std::string& regexp)
+{
+    std::ifstream stream(path.c_str());
+    if (!stream)
+        throw std::runtime_error("Failed to open " + path.str());
+
+    bool found = false;
+
+    std::string line;
+    while (!found && !std::getline(stream, line).fail()) {
+        if (atf::text::match(line, regexp))
+            found = true;
+    }
+
+    stream.close();
+
+    return found;
+}
+
+static
+bool
+file_empty(const atf::fs::path& p)
+{
+    atf::fs::file_info f(p);
+
+    return (f.get_size() == 0);
+}
+
+static bool
+compare_files(const atf::fs::path& p1, const atf::fs::path& p2)
+{
+    bool equal = false;
+
+    std::ifstream f1(p1.c_str());
+    if (!f1)
+        throw std::runtime_error("Failed to open " + p1.str());
+
+    std::ifstream f2(p2.c_str());
+    if (!f2)
+        throw std::runtime_error("Failed to open " + p1.str());
+
+    for (;;) {
+        char buf1[512], buf2[512];
+
+        f1.read(buf1, sizeof(buf1));
+        if (f1.bad())
+            throw std::runtime_error("Failed to read from " + p1.str());
+
+        f2.read(buf2, sizeof(buf2));
+        if (f2.bad())
+            throw std::runtime_error("Failed to read from " + p1.str());
+
+        if ((f1.gcount() == 0) && (f2.gcount() == 0)) {
+            equal = true;
+            break;
+        }
+
+        if ((f1.gcount() != f2.gcount()) ||
+            (std::memcmp(buf1, buf2, f1.gcount()) != 0)) {
+            break;
+        }
+    }
+
+    return equal;
+}
+
+static
+void
+print_diff(const atf::fs::path& p1, const atf::fs::path& p2)
+{
+    const atf::process::status s =
+        atf::process::exec(atf::fs::path("diff"),
+                           atf::process::argv_array("diff", "-u", p1.c_str(),
+                                                    p2.c_str(), NULL),
+                           atf::process::stream_connect(STDOUT_FILENO,
+                                                        STDERR_FILENO),
+                           atf::process::stream_inherit());
+
+    if (!s.exited())
+        std::cerr << "Failed to run diff(3)\n";
+
+    if (s.exitstatus() != 1)
+        std::cerr << "Error while running diff(3)\n";
+}
+
+static
+std::string
+decode(const std::string& s)
+{
+    size_t i;
+    std::string res;
+
+    res.reserve(s.length());
+
+    i = 0;
+    while (i < s.length()) {
+        char c = s[i++];
+
+        if (c == '\\') {
+            switch (s[i++]) {
+            case 'a': c = '\a'; break;
+            case 'b': c = '\b'; break;
+            case 'c': break;
+            case 'e': c = 033; break;
+            case 'f': c = '\f'; break;
+            case 'n': c = '\n'; break;
+            case 'r': c = '\r'; break;
+            case 't': c = '\t'; break;
+            case 'v': c = '\v'; break;
+            case '\\': break;
+            case '0':
+                {
+                    int count = 3;
+                    c = 0;
+                    while (--count >= 0 && (unsigned)(s[i] - '0') < 8)
+                        c = (c << 3) + (s[i++] - '0');
+                    break;
+                }
+            default:
+                --i;
+                break;
+            }
+        }
+
+        res.push_back(c);
+    }
+
+    return res;
+}
+
+static
+bool
+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) {
+            const int status = cr.exitcode();
+
+            if (!sc.negated && sc.value != status) {
+                std::cerr << "Fail: incorrect exit status: "
+                          << status << ", expected: "
+                          << sc.value << "\n";
+                result = false;
+            } else if (sc.negated && sc.value == status) {
+                std::cerr << "Fail: incorrect exit status: "
+                          << status << ", expected: "
+                          << "anything else\n";
+                result = false;
+            } else
+                result = true;
+        } else if (cr.exited() && sc.value == INT_MIN) {
+            result = true;
+        } else {
+            std::cerr << "Fail: program did not exit cleanly\n";
+            result = false;
+        }
+    } else if (sc.type == sc_ignore) {
+        result = true;
+    } else if (sc.type == sc_signal) {
+        if (cr.signaled() && sc.value != INT_MIN) {
+            const int status = cr.termsig();
+
+            if (!sc.negated && sc.value != status) {
+                std::cerr << "Fail: incorrect signal received: "
+                          << status << ", expected: " << sc.value << "\n";
+                result = false;
+            } else if (sc.negated && sc.value == status) {
+                std::cerr << "Fail: incorrect signal received: "
+                          << status << ", expected: "
+                          << "anything else\n";
+                result = false;
+            } else
+                result = true;
+        } else if (cr.signaled() && sc.value == INT_MIN) {
+            result = true;
+        } else {
+            std::cerr << "Fail: program did not receive a signal\n";
+            result = false;
+        }
+    } else {
+        UNREACHABLE;
+        result = false;
+    }
+
+    if (result == false) {
+        std::cerr << "stdout:\n";
+        cat_file(atf::fs::path(cr.stdout_path()));
+        std::cerr << "\n";
+
+        std::cerr << "stderr:\n";
+        cat_file(atf::fs::path(cr.stderr_path()));
+        std::cerr << "\n";
+    }
+
+    return result;
+}
+
+static
+bool
+run_status_checks(const std::vector< status_check >& checks,
+                  const atf::check::check_result& result)
+{
+    bool ok = false;
+
+    for (std::vector< status_check >::const_iterator iter = checks.begin();
+         !ok && iter != checks.end(); iter++) {
+         ok |= run_status_check(*iter, result);
+    }
+
+    return ok;
+}
+
+static
+bool
+run_output_check(const output_check oc, const atf::fs::path& path,
+                 const std::string& stdxxx)
+{
+    bool result;
+
+    if (oc.type == oc_empty) {
+        const bool is_empty = file_empty(path);
+        if (!oc.negated && !is_empty) {
+            std::cerr << "Fail: " << stdxxx << " not empty\n";
+            print_diff(atf::fs::path("/dev/null"), path);
+            result = false;
+        } else if (oc.negated && is_empty) {
+            std::cerr << "Fail: " << stdxxx << " is empty\n";
+            result = false;
+        } else
+            result = true;
+    } else if (oc.type == oc_file) {
+        const bool equals = compare_files(path, atf::fs::path(oc.value));
+        if (!oc.negated && !equals) {
+            std::cerr << "Fail: " << stdxxx << " does not match golden "
+                "output\n";
+            print_diff(atf::fs::path(oc.value), path);
+            result = false;
+        } else if (oc.negated && equals) {
+            std::cerr << "Fail: " << stdxxx << " matches golden output\n";
+            cat_file(atf::fs::path(oc.value));
+            result = false;
+        } else
+            result = true;
+    } else if (oc.type == oc_ignore) {
+        result = true;
+    } else if (oc.type == oc_inline) {
+        temp_file temp("atf-check.XXXXXX");
+        temp.write(decode(oc.value));
+        temp.close();
+
+        const bool equals = compare_files(path, temp.get_path());
+        if (!oc.negated && !equals) {
+            std::cerr << "Fail: " << stdxxx << " does not match expected "
+                "value\n";
+            print_diff(temp.get_path(), path);
+            result = false;
+        } else if (oc.negated && equals) {
+            std::cerr << "Fail: " << stdxxx << " matches expected value\n";
+            cat_file(temp.get_path());
+            result = false;
+        } else
+            result = true;
+    } else if (oc.type == oc_match) {
+        const bool matches = grep_file(path, oc.value);
+        if (!oc.negated && !matches) {
+            std::cerr << "Fail: regexp " + oc.value + " not in " << stdxxx
+                      << "\n";
+            cat_file(path);
+            result = false;
+        } else if (oc.negated && matches) {
+            std::cerr << "Fail: regexp " + oc.value + " is in " << stdxxx
+                      << "\n";
+            cat_file(path);
+            result = false;
+        } else
+            result = true;
+    } else if (oc.type == oc_save) {
+        INV(!oc.negated);
+        std::ifstream ifs(path.c_str(), std::fstream::binary);
+        ifs >> std::noskipws;
+        std::istream_iterator< char > begin(ifs), end;
+
+        std::ofstream ofs(oc.value.c_str(), std::fstream::binary
+                                     | std::fstream::trunc);
+        std::ostream_iterator <char> obegin(ofs);
+
+        std::copy(begin, end, obegin);
+        result = true;
+    } else {
+        UNREACHABLE;
+        result = false;
+    }
+
+    return result;
+}
+
+static
+bool
+run_output_checks(const std::vector< output_check >& checks,
+                  const atf::fs::path& path, const std::string& stdxxx)
+{
+    bool ok = true;
+
+    for (std::vector< output_check >::const_iterator iter = checks.begin();
+         iter != checks.end(); iter++) {
+         ok &= run_output_check(*iter, path, stdxxx);
+    }
+
+    return ok;
+}
+
+// ------------------------------------------------------------------------
+// The "atf_check" application.
+// ------------------------------------------------------------------------
+
+namespace {
+
+class atf_check : public atf::application::app {
+    bool m_xflag;
+
+    std::vector< status_check > m_status_checks;
+    std::vector< output_check > m_stdout_checks;
+    std::vector< output_check > m_stderr_checks;
+
+    static const char* m_description;
+
+    bool run_output_checks(const atf::check::check_result&,
+                           const std::string&) const;
+
+    std::string specific_args(void) const;
+    options_set specific_options(void) const;
+    void process_option(int, const char*);
+    void process_option_s(const std::string&);
+
+public:
+    atf_check(void);
+    int main(void);
+};
+
+} // anonymous namespace
+
+const char* atf_check::m_description =
+    "atf-check executes given command and analyzes its results.";
+
+atf_check::atf_check(void) :
+    app(m_description, "atf-check(1)"),
+    m_xflag(false)
+{
+}
+
+bool
+atf_check::run_output_checks(const atf::check::check_result& r,
+                             const std::string& stdxxx)
+    const
+{
+    if (stdxxx == "stdout") {
+        return ::run_output_checks(m_stdout_checks,
+            atf::fs::path(r.stdout_path()), "stdout");
+    } else if (stdxxx == "stderr") {
+        return ::run_output_checks(m_stderr_checks,
+            atf::fs::path(r.stderr_path()), "stderr");
+    } else {
+        UNREACHABLE;
+        return false;
+    }
+}
+
+std::string
+atf_check::specific_args(void)
+    const
+{
+    return "<command>";
+}
+
+atf_check::options_set
+atf_check::specific_options(void)
+    const
+{
+    using atf::application::option;
+    options_set opts;
+
+    opts.insert(option('s', "qual:value", "Handle status. Qualifier "
+                "must be one of: ignore exit:<num> signal:<name|num>"));
+    opts.insert(option('o', "action:arg", "Handle stdout. Action must be "
+                "one of: empty ignore file:<path> inline:<val> match:regexp "
+                "save:<path>"));
+    opts.insert(option('e', "action:arg", "Handle stderr. Action must be "
+                "one of: empty ignore file:<path> inline:<val> match:regexp "
+                "save:<path>"));
+    opts.insert(option('x', "", "Execute command as a shell command"));
+
+    return opts;
+}
+
+void
+atf_check::process_option(int ch, const char* arg)
+{
+    switch (ch) {
+    case 's':
+        m_status_checks.push_back(parse_status_check_arg(arg));
+        break;
+
+    case 'o':
+        m_stdout_checks.push_back(parse_output_check_arg(arg));
+        break;
+
+    case 'e':
+        m_stderr_checks.push_back(parse_output_check_arg(arg));
+        break;
+
+    case 'x':
+        m_xflag = true;
+        break;
+
+    default:
+        UNREACHABLE;
+    }
+}
+
+int
+atf_check::main(void)
+{
+    if (m_argc < 1)
+        throw atf::application::usage_error("No command specified");
+
+    int status = EXIT_FAILURE;
+
+    std::auto_ptr< atf::check::check_result > r =
+        m_xflag ? execute_with_shell(m_argv) : execute(m_argv);
+
+    if (m_status_checks.empty())
+        m_status_checks.push_back(status_check(sc_exit, false, EXIT_SUCCESS));
+    else if (m_status_checks.size() > 1) {
+        // TODO: Remove this restriction.
+        throw atf::application::usage_error("Cannot specify -s more than once");
+    }
+
+    if (m_stdout_checks.empty())
+        m_stdout_checks.push_back(output_check(oc_empty, false, ""));
+    if (m_stderr_checks.empty())
+        m_stderr_checks.push_back(output_check(oc_empty, false, ""));
+
+    if ((run_status_checks(m_status_checks, *r) == false) ||
+        (run_output_checks(*r, "stderr") == false) ||
+        (run_output_checks(*r, "stdout") == false))
+        status = EXIT_FAILURE;
+    else
+        status = EXIT_SUCCESS;
+
+    return status;
+}
+
+int
+main(int argc, char* const* argv)
+{
+    return atf_check().run(argc, argv);
+}

Added: vendor/atf/dist/atf-sh/atf-check_test.sh
===================================================================
--- vendor/atf/dist/atf-sh/atf-check_test.sh	                        (rev 0)
+++ vendor/atf/dist/atf-sh/atf-check_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,441 @@
+# Copyright (c) 2008 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.
+
+# The Atf_Check and Atf-Shell variables are set by atf-sh.
+
+h_pass()
+{
+    cmd="$1"; shift
+
+    echo "Running [atf-check $*] against [${cmd}]"
+
+    cat >script.sh <<EOF
+#! ${Atf_Shell}
+${cmd}
+EOF
+    chmod +x script.sh
+
+    if ! ${Atf_Check} "${@}" ./script.sh >tmp; then
+        cat tmp
+        atf_fail "atf-check failed"
+    fi
+}
+
+h_fail()
+{
+    cmd="$1"; shift
+
+    echo "Running [atf-check $*] against [${cmd}]"
+
+    cat >script.sh <<EOF
+#! ${Atf_Shell}
+${cmd}
+EOF
+    chmod +x script.sh
+
+    if ${Atf_Check} "${@}" ./script.sh 2>tmp; then
+        cat tmp
+        atf_fail "atf-check succeeded but should fail"
+    fi
+}
+
+atf_test_case sflag_eq_ne
+sflag_eq_ne_head()
+{
+    atf_set "descr" "Tests for the -s option using the 'eq' and 'ne' qualifiers"
+}
+sflag_eq_ne_body()
+{
+    h_pass "true" -s eq:0
+    h_pass "false" -s ne:0
+    h_pass "exit 255" -s eq:255
+    h_pass "exit 0" -s ne:255
+
+    h_fail "exit 256" -s eq:256
+    h_fail "exit -1" -s eq:-1
+    h_fail "true" -s ne:256
+    h_fail "true" -s ne:-1
+}
+
+atf_test_case sflag_exit
+sflag_exit_head()
+{
+    atf_set "descr" "Tests for the -s option using the 'exit' qualifier"
+}
+sflag_exit_body()
+{
+    h_pass 'true' -s exit:0
+    h_pass 'false' -s not-exit:0
+    h_pass 'exit 255' -s exit:255
+    h_pass 'exit 0' -s not-exit:255
+
+    h_fail 'exit 256' -s exit:256
+    h_fail 'exit -1' -s exit:-1
+    h_fail 'true' -s not-exit:256
+    h_fail 'true' -s not-exit:-1
+
+    h_pass 'true' -s exit
+    h_pass 'false' -s exit
+    if ${Atf_Check} -s exit -x 'kill $$'; then
+        atf_fail "Signal detected as clean exit"
+    fi
+}
+
+atf_test_case sflag_ignore
+sflag_ignore_head()
+{
+    atf_set "descr" "Tests for the -s option using the 'ignore' qualifier"
+}
+sflag_ignore_body()
+{
+    h_pass 'true' -s ignore
+    h_pass 'false' -s ignore
+    if ${Atf_Check} -s ignored -x 'kill $$'; then
+        atf_fail "Signal not ignored"
+    fi
+}
+
+atf_test_case sflag_signal
+sflag_signal_head()
+{
+    atf_set "descr" "Tests for the -s option using the 'signal' qualifier"
+}
+sflag_signal_body()
+{
+    ${Atf_Check} -s signal:hup -x 'kill -1 $$' || atf_fail "Signal not detected"
+    ${Atf_Check} -s signal:sighup -x 'kill -1 $$' || atf_fail "Signal not" \
+        "detected"
+    ${Atf_Check} -s signal:1 -x 'kill -1 $$' || atf_fail "Signal not detected"
+    ${Atf_Check} -s signal -x 'kill -1 $$' || atf_fail "Signal not detected"
+
+    ${Atf_Check} -s not-signal:kill -x 'kill -9 $$' && \
+        atf_fail "not-signal:kill matched kill -9"
+    ${Atf_Check} -s not-signal:kill -x 'kill -1 $$' || \
+        atf_fail "not-signal:kill did not match kill -1"
+
+    h_fail 'true' -s signal
+    h_fail 'false' -s signal
+}
+
+atf_test_case xflag
+xflag_head()
+{
+    atf_set "descr" "Tests for the -x option"
+}
+xflag_body()
+{
+    ${Atf_Check} -s ne:0 -o ignore -e ignore "echo foo 2>&1" || \
+        atf_fail "Shell command succeeded without -x"
+
+    ${Atf_Check} -e inline:"foo\n" -x "echo foo 1>&2" || \
+        atf_fail "Cannot run command with -x"
+
+    ${Atf_Check} -o inline:"foo\n" -x echo foo || \
+        atf_fail "Using -x does not respect all provided arguments"
+}
+
+atf_test_case oflag_empty
+oflag_empty_head()
+{
+    atf_set "descr" "Tests for the -o option using the 'empty' argument"
+}
+oflag_empty_body()
+{
+    h_pass "true" -o empty
+    h_fail "echo foo" -o empty
+}
+
+atf_test_case oflag_ignore
+oflag_ignore_head()
+{
+    atf_set "descr" "Tests for the -o option using the 'ignore' argument"
+}
+oflag_ignore_body()
+{
+    h_pass "true" -o ignore
+    h_pass "echo foo" -o ignore
+}
+
+atf_test_case oflag_file
+oflag_file_head()
+{
+    atf_set "descr" "Tests for the -o option using the 'file:' argument"
+}
+oflag_file_body()
+{
+    touch empty
+    h_pass "true" -o file:empty
+
+    echo foo >text
+    h_pass "echo foo" -o file:text
+    h_fail "echo bar" -o file:text
+
+    dd if=/dev/urandom of=bin bs=1k count=10
+    h_pass "cat bin" -o file:bin
+}
+
+atf_test_case oflag_inline
+oflag_inline_head()
+{
+    atf_set "descr" "Tests for the -o option using the 'inline:' argument"
+}
+oflag_inline_body()
+{
+    h_pass "true" -o inline:
+    h_pass "echo foo bar" -o inline:"foo bar\n"
+    h_pass "printf 'foo bar'" -o inline:"foo bar"
+    h_pass "printf '\t\n\t\n'" -o inline:"\t\n\t\n"
+    h_pass "printf '\a\b\033\f\n\r\t\v'" -o inline:"\a\b\e\f\n\r\t\v"
+    h_pass "printf '\011\022\033\012'" -o inline:"\011\022\033\012"
+
+    h_fail "echo foo bar" -o inline:"foo bar"
+    h_fail "echo -n foo bar" -o inline:"foo bar\n"
+}
+
+atf_test_case oflag_match
+oflag_match_head()
+{
+    atf_set "descr" "Tests for the -o option using the 'match:' argument"
+}
+oflag_match_body()
+{
+    h_pass "printf no-newline" -o "match:^no-newline"
+    h_pass "echo line1; echo foo bar" -o "match:^foo"
+    h_pass "echo foo bar" -o "match:o b"
+    h_fail "echo foo bar" -o "match:baz"
+    h_fail "echo foo bar" -o "match:^bar"
+}
+
+atf_test_case oflag_save
+oflag_save_head()
+{
+    atf_set "descr" "Tests for the -o option using the 'save:' argument"
+}
+oflag_save_body()
+{
+    h_pass "echo foo" -o save:out
+    echo foo >exp
+    cmp -s out exp || atf_fail "Saved output does not match expected results"
+}
+
+atf_test_case oflag_multiple
+oflag_multiple_head()
+{
+    atf_set "descr" "Tests for multiple occurrences of the -o option"
+}
+oflag_multiple_body()
+{
+    h_pass "echo foo bar" -o match:foo -o match:bar
+    h_pass "echo foo; echo bar" -o match:foo -o match:bar
+    h_fail "echo foo baz" -o match:bar -o match:foo
+    h_fail "echo foo; echo baz" -o match:bar -o match:foo
+}
+
+atf_test_case oflag_negated
+oflag_negated_head()
+{
+    atf_set "descr" "Tests for negated occurrences of the -o option"
+}
+oflag_negated_body()
+{
+    h_fail "echo foo" -o empty
+    h_pass "echo foo" -o not-empty
+
+    h_pass "echo foo bar" -o match:foo
+    h_fail "echo foo bar" -o not-match:foo
+}
+
+atf_test_case eflag_empty
+eflag_empty_head()
+{
+    atf_set "descr" "Tests for the -e option using the 'empty' argument"
+}
+eflag_empty_body()
+{
+    h_pass "true 1>&2" -e empty
+    h_fail "echo foo 1>&2" -e empty
+}
+
+atf_test_case eflag_ignore
+eflag_ignore_head()
+{
+    atf_set "descr" "Tests for the -e option using the 'ignore' argument"
+}
+eflag_ignore_body()
+{
+    h_pass "true 1>&2" -e ignore
+    h_pass "echo foo 1>&2" -e ignore
+}
+
+atf_test_case eflag_file
+eflag_file_head()
+{
+    atf_set "descr" "Tests for the -e option using the 'file:' argument"
+}
+eflag_file_body()
+{
+    touch empty
+    h_pass "true 1>&2" -e file:empty
+
+    echo foo >text
+    h_pass "echo foo 1>&2" -e file:text
+    h_fail "echo bar 1>&2" -e file:text
+
+    dd if=/dev/urandom of=bin bs=1k count=10
+    h_pass "cat bin 1>&2" -e file:bin
+}
+
+atf_test_case eflag_inline
+eflag_inline_head()
+{
+    atf_set "descr" "Tests for the -e option using the 'inline:' argument"
+}
+eflag_inline_body()
+{
+    h_pass "true 1>&2" -e inline:
+    h_pass "echo foo bar 1>&2" -e inline:"foo bar\n"
+    h_pass "printf 'foo bar' 1>&2" -e inline:"foo bar"
+    h_pass "printf '\t\n\t\n' 1>&2" -e inline:"\t\n\t\n"
+    h_pass "printf '\a\b\033\f\n\r\t\v' 1>&2" -e inline:"\a\b\e\f\n\r\t\v"
+    h_pass "printf '\011\022\033\012' 1>&2" -e inline:"\011\022\033\012"
+
+    h_fail "echo foo bar 1>&2" -e inline:"foo bar"
+    h_fail "echo -n foo bar 1>&2" -e inline:"foo bar\n"
+}
+
+atf_test_case eflag_save
+eflag_save_head()
+{
+    atf_set "descr" "Tests for the -e option using the 'save:' argument"
+}
+eflag_save_body()
+{
+    h_pass "echo foo 1>&2" -e save:out
+    echo foo >exp
+    cmp -s out exp || atf_fail "Saved output does not match expected results"
+}
+
+atf_test_case eflag_match
+eflag_match_head()
+{
+    atf_set "descr" "Tests for the -e option using the 'match:' argument"
+}
+eflag_match_body()
+{
+    h_pass "printf no-newline 1>&2" -e "match:^no-newline"
+    h_pass "echo line1 1>&2; echo foo bar 1>&2" -e "match:^foo"
+    h_pass "echo foo bar 1>&2" -e "match:o b"
+    h_fail "echo foo bar 1>&2" -e "match:baz"
+    h_fail "echo foo bar 1>&2" -e "match:^bar"
+}
+
+atf_test_case eflag_multiple
+eflag_multiple_head()
+{
+    atf_set "descr" "Tests for multiple occurrences of the -e option"
+}
+eflag_multiple_body()
+{
+    h_pass "echo foo bar 1>&2" -e match:foo -e match:bar
+    h_pass "echo foo 1>&2; echo bar 1>&2" -e match:foo -e match:bar
+    h_fail "echo foo baz 1>&2" -e match:bar -e match:foo
+    h_fail "echo foo 1>&2; echo baz 1>&2" -e match:bar -e match:foo
+}
+
+atf_test_case eflag_negated
+eflag_negated_head()
+{
+    atf_set "descr" "Tests for negated occurrences of the -e option"
+}
+eflag_negated_body()
+{
+    h_fail "echo foo 1>&2" -e empty
+    h_pass "echo foo 1>&2" -e not-empty
+
+    h_pass "echo foo bar 1>&2" -e match:foo
+    h_fail "echo foo bar 1>&2" -e not-match:foo
+}
+
+atf_test_case stdin
+stdin_head()
+{
+    atf_set "descr" "Tests that stdin is preserved"
+}
+stdin_body()
+{
+    echo "hello" | ${Atf_Check} -o match:"hello" cat || \
+        atf_fail "atf-check does not seem to respect stdin"
+}
+
+atf_test_case invalid_umask
+invalid_umask_head()
+{
+    atf_set "descr" "Tests for a correct error condition if the umask is" \
+            "too restrictive"
+}
+invalid_umask_body()
+{
+    umask 0222
+    ${Atf_Check} false 2>stderr && \
+        atf_fail "atf-check returned 0 but it should have failed"
+    cat stderr
+    grep 'temporary.*current umask.*0222' stderr >/dev/null || \
+        atf_fail "atf-check did not report an error related to the" \
+                 "current umask"
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case sflag_eq_ne
+    atf_add_test_case sflag_exit
+    atf_add_test_case sflag_ignore
+    atf_add_test_case sflag_signal
+
+    atf_add_test_case xflag
+
+    atf_add_test_case oflag_empty
+    atf_add_test_case oflag_ignore
+    atf_add_test_case oflag_file
+    atf_add_test_case oflag_inline
+    atf_add_test_case oflag_match
+    atf_add_test_case oflag_save
+    atf_add_test_case oflag_multiple
+    atf_add_test_case oflag_negated
+
+    atf_add_test_case eflag_empty
+    atf_add_test_case eflag_ignore
+    atf_add_test_case eflag_file
+    atf_add_test_case eflag_inline
+    atf_add_test_case eflag_match
+    atf_add_test_case eflag_save
+    atf_add_test_case eflag_multiple
+    atf_add_test_case eflag_negated
+
+    atf_add_test_case stdin
+
+    atf_add_test_case invalid_umask
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/atf-sh/atf-sh.1
===================================================================
--- vendor/atf/dist/atf-sh/atf-sh.1	                        (rev 0)
+++ vendor/atf/dist/atf-sh/atf-sh.1	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,104 @@
+.\" Copyright (c) 2010 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.
+.Dd March 6, 2017
+.Dt ATF-SH 1
+.Os
+.Sh NAME
+.Nm atf-sh
+.Nd interpreter for shell-based test programs
+.Sh SYNOPSIS
+.Nm
+.Op Fl s Ar shell
+.Ar script
+.Sh DESCRIPTION
+.Nm
+is an interpreter that runs the test program given in
+.Ar script
+after loading the
+.Xr atf-sh 3
+library.
+.Pp
+.Nm
+is not a real interpreter though: it is just a wrapper around
+the system-wide shell defined by
+.Va ATF_SHELL .
+.Nm
+executes the interpreter, loads the
+.Xr atf-sh 3
+library and then runs the script.
+You must consider
+.Nm atf-sh
+to be a POSIX shell by default and thus should not use any non-standard
+extensions.
+.Pp
+The following options are available:
+.Bl -tag -width XsXshellXXX
+.It Fl s Ar shell
+Specifies the shell to use instead of the value provided by
+.Va ATF_SHELL .
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width ATFXLIBEXECDIRXX -compact
+.It Va ATF_LIBEXECDIR
+Overrides the builtin directory where
+.Nm
+is located.
+Should not be overridden other than for testing purposes.
+.It Va ATF_PKGDATADIR
+Overrides the builtin directory where
+.Pa libatf-sh.subr
+is located.
+Should not be overridden other than for testing purposes.
+.It Va ATF_SHELL
+Path to the system shell to be used in the generated scripts.
+Scripts must not rely on this variable being set to select a specific
+interpreter.
+.It Va ATF_SHELL
+Path to the system shell to be used in the generated scripts.
+.El
+.Sh EXAMPLES
+Scripts using
+.Xr atf-sh 3
+should start with:
+.Bd -literal -offset indent
+#! /usr/bin/env atf-sh
+.Ed
+.Pp
+Alternatively, if you want to explicitly choose a shell interpreter, you cannot
+rely on
+.Xr env 1
+to find
+.Nm .
+Instead, you have to hardcode the path to
+.Nm
+in the script and then use the
+.Fl s
+option afterwards as a
+.Em single parameter :
+.Bd -literal -offset indent
+#! /path/to/bin/atf-sh -s/bin/bash
+.Ed
+.Sh SEE ALSO
+.Xr atf-sh 3

Added: vendor/atf/dist/atf-sh/atf-sh.3
===================================================================
--- vendor/atf/dist/atf-sh/atf-sh.3	                        (rev 0)
+++ vendor/atf/dist/atf-sh/atf-sh.3	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,375 @@
+.\" Copyright (c) 2008 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.
+.Dd March 6, 2017
+.Dt ATF-SH 3
+.Os
+.Sh NAME
+.Nm atf_add_test_case ,
+.Nm atf_check ,
+.Nm atf_check_equal ,
+.Nm atf_config_get ,
+.Nm atf_config_has ,
+.Nm atf_expect_death ,
+.Nm atf_expect_exit ,
+.Nm atf_expect_fail ,
+.Nm atf_expect_pass ,
+.Nm atf_expect_signal ,
+.Nm atf_expect_timeout ,
+.Nm atf_fail ,
+.Nm atf_get ,
+.Nm atf_get_srcdir ,
+.Nm atf_init_test_cases ,
+.Nm atf_pass ,
+.Nm atf_require_prog ,
+.Nm atf_set ,
+.Nm atf_skip ,
+.Nm atf_test_case
+.Nd POSIX shell API to write ATF-based test programs
+.Sh SYNOPSIS
+.Nm atf_add_test_case
+.Qq name
+.Nm atf_check
+.Qq command
+.Nm atf_check_equal
+.Qq expected_expression
+.Qq actual_expression
+.Nm atf_config_get
+.Qq var_name
+.Nm atf_config_has
+.Qq var_name
+.Nm atf_expect_death
+.Qq reason
+.Qq ...
+.Nm atf_expect_exit
+.Qq exitcode
+.Qq reason
+.Qq ...
+.Nm atf_expect_fail
+.Qq reason
+.Qq ...
+.Nm atf_expect_pass
+.Qq
+.Nm atf_expect_signal
+.Qq signo
+.Qq reason
+.Qq ...
+.Nm atf_expect_timeout
+.Qq reason
+.Qq ...
+.Nm atf_fail
+.Qq reason
+.Nm atf_get
+.Qq var_name
+.Nm atf_get_srcdir
+.Nm atf_init_test_cases
+.Qq name
+.Nm atf_pass
+.Nm atf_require_prog
+.Qq prog_name
+.Nm atf_set
+.Qq var_name
+.Qq value
+.Nm atf_skip
+.Qq reason
+.Nm atf_test_case
+.Qq name
+.Qq cleanup
+.Sh DESCRIPTION
+ATF
+provides a simple but powerful interface to easily write test programs in
+the POSIX shell language.
+These are extremely helpful given that they are trivial to write due to the
+language simplicity and the great deal of available external tools, so they
+are often ideal to test other applications at the user level.
+.Pp
+Test programs written using this library must be run using the
+.Xr atf-sh 1
+interpreter by putting the following on their very first line:
+.Bd -literal -offset indent
+#! /usr/bin/env atf-sh
+.Ed
+.Pp
+Shell-based test programs always follow this template:
+.Bd -literal -offset indent
+atf_test_case tc1
+tc1_head() {
+    ... first test case's header ...
+}
+tc1_body() {
+    ... first test case's body ...
+}
+
+atf_test_case tc2 cleanup
+tc2_head() {
+    ... second test case's header ...
+}
+tc2_body() {
+    ... second test case's body ...
+}
+tc2_cleanup() {
+    ... second test case's cleanup ...
+}
+
+\&... additional test cases ...
+
+atf_init_test_cases() {
+    atf_add_test_case tc1
+    atf_add_test_case tc2
+    ... add additional test cases ...
+}
+.Ed
+.Ss Definition of test cases
+Test cases have an identifier and are composed of three different parts:
+the header, the body and an optional cleanup routine, all of which are
+described in
+.Xr atf-test-case 4 .
+To define test cases, one can use the
+.Nm atf_test_case
+function, which takes a first parameter specifying the test case's
+name and instructs the library to set things up to accept it as a valid
+test case.
+The second parameter is optional and, if provided, must be
+.Sq cleanup ;
+providing this parameter allows defining a cleanup routine for the test
+case.
+It is important to note that this function
+.Em does not
+set the test case up for execution when the program is run.
+In order to do so, a later registration is needed through the
+.Nm atf_add_test_case
+function detailed in
+.Sx Program initialization .
+.Pp
+Later on, one must define the three parts of the body by providing two
+or three functions (remember that the cleanup routine is optional).
+These functions are named after the test case's identifier, and are
+.Nm \*(Ltid\*(Gt_head ,
+.Nm \*(Ltid\*(Gt_body
+and
+.Nm \*(Ltid\*(Gt_cleanup .
+None of these take parameters when executed.
+.Ss Program initialization
+The test program must define an
+.Nm atf_init_test_cases
+function, which is in charge of registering the test cases that will be
+executed at run time by using the
+.Nm atf_add_test_case
+function, which takes the name of a test case as its single parameter.
+This main function should not do anything else, except maybe sourcing
+auxiliary source files that define extra variables and functions.
+.Ss Configuration variables
+The test case has read-only access to the current configuration variables
+through the
+.Nm atf_config_has
+and
+.Nm atf_config_get
+methods.
+The former takes a single parameter specifying a variable name and returns
+a boolean indicating whether the variable is defined or not.
+The latter can take one or two parameters.
+If it takes only one, it specifies the variable from which to get the
+value, and this variable must be defined.
+If it takes two, the second one specifies a default value to be returned
+if the variable is not available.
+.Ss Access to the source directory
+It is possible to get the path to the test case's source directory from
+anywhere in the test program by using the
+.Nm atf_get_srcdir
+function.
+It is interesting to note that this can be used inside
+.Nm atf_init_test_cases
+to silently include additional helper files from the source directory.
+.Ss Requiring programs
+Aside from the
+.Va require.progs
+meta-data variable available in the header only, one can also check for
+additional programs in the test case's body by using the
+.Nm atf_require_prog
+function, which takes the base name or full path of a single binary.
+Relative paths are forbidden.
+If it is not found, the test case will be automatically skipped.
+.Ss Test case finalization
+The test case finalizes either when the body reaches its end, at which
+point the test is assumed to have
+.Em passed ,
+or at any explicit call to
+.Nm atf_pass ,
+.Nm atf_fail
+or
+.Nm atf_skip .
+These three functions terminate the execution of the test case immediately.
+The cleanup routine will be processed afterwards in a completely automated
+way, regardless of the test case's termination reason.
+.Pp
+.Nm atf_pass
+does not take any parameters.
+.Nm atf_fail
+and
+.Nm atf_skip
+take a single string parameter that describes why the test case failed or
+was skipped, respectively.
+It is very important to provide a clear error message in both cases so that
+the user can quickly know why the test did not pass.
+.Ss Expectations
+Everything explained in the previous section changes when the test case
+expectations are redefined by the programmer.
+.Pp
+Each test case has an internal state called
+.Sq expect
+that describes what the test case expectations are at any point in time.
+The value of this property can change during execution by any of:
+.Bl -tag -width indent
+.It Nm atf_expect_death Qo reason Qc Qo ... Qc
+Expects the test case to exit prematurely regardless of the nature of the
+exit.
+.It Nm atf_expect_exit Qo exitcode Qc Qo reason Qc Qo ... Qc
+Expects the test case to exit cleanly.
+If
+.Va exitcode
+is not
+.Sq -1 ,
+the runtime engine will validate that the exit code of the test case
+matches the one provided in this call.
+Otherwise, the exact value will be ignored.
+.It Nm atf_expect_fail Qo reason Qc
+Any failure raised in this mode is recorded, but such failures do not report
+the test case as failed; instead, the test case finalizes cleanly and is
+reported as
+.Sq expected failure ;
+this report includes the provided
+.Fa reason
+as part of it.
+If no error is raised while running in this mode, then the test case is
+reported as
+.Sq failed .
+.Pp
+This mode is useful to reproduce actual known bugs in tests.
+Whenever the developer fixes the bug later on, the test case will start
+reporting a failure, signaling the developer that the test case must be
+adjusted to the new conditions.
+In this situation, it is useful, for example, to set
+.Fa reason
+as the bug number for tracking purposes.
+.It Nm atf_expect_pass
+This is the normal mode of execution.
+In this mode, any failure is reported as such to the user and the test case
+is marked as
+.Sq failed .
+.It Nm atf_expect_signal Qo signo Qc Qo reason Qc Qo ... Qc
+Expects the test case to terminate due to the reception of a signal.
+If
+.Va signo
+is not
+.Sq -1 ,
+the runtime engine will validate that the signal that terminated the test
+case matches the one provided in this call.
+Otherwise, the exact value will be ignored.
+.It Nm atf_expect_timeout Qo reason Qc Qo ... Qc
+Expects the test case to execute for longer than its timeout.
+.El
+.Ss Helper functions for common checks
+.Bl -tag -width indent
+.It Nm atf_check Qo [options] Qc Qo command Qc Qo [args] Qc
+Executes a command, performs checks on its exit code and its output, and
+fails the test case if any of the checks is not successful.
+This function is particularly useful in integration tests that verify the
+correct functioning of a binary.
+.Pp
+Internally, this function is just a wrapper over the
+.Xr atf-check 1
+tool (whose manual page provides all details on the calling syntax).
+You should always use the
+.Nm atf_check
+function instead of the
+.Xr atf-check 1
+tool in your scripts; the latter is not even in the path.
+.It Nm atf_check_equal Qo expected_expression Qc Qo actual_expression Qc
+This function takes two expressions, evaluates them and, if their
+results differ, aborts the test case with an appropriate failure message.
+The common style is to put the expected value in the first parameter and the
+actual value in the second parameter.
+.El
+.Sh EXAMPLES
+The following shows a complete test program with a single test case that
+validates the addition operator:
+.Bd -literal -offset indent
+atf_test_case addition
+addition_head() {
+    atf_set "descr" "Sample tests for the addition operator"
+}
+addition_body() {
+    atf_check_equal 0 $((0 + 0))
+    atf_check_equal 1 $((0 + 1))
+    atf_check_equal 1 $((1 + 0))
+
+    atf_check_equal 2 $((1 + 1))
+
+    atf_check_equal 300 $((100 + 200))
+}
+
+atf_init_test_cases() {
+    atf_add_test_case addition
+}
+.Ed
+.Pp
+This other example shows how to include a file with extra helper functions
+in the test program:
+.Bd -literal -offset indent
+\&... definition of test cases ...
+
+atf_init_test_cases() {
+    . $(atf_get_srcdir)/helper_functions.sh
+
+    atf_add_test_case foo1
+    atf_add_test_case foo2
+}
+.Ed
+.Pp
+This example demonstrates the use of the very useful
+.Nm atf_check
+function:
+.Bd -literal -offset indent
+# Check for silent output
+atf_check -s exit:0 -o empty -e empty 'true'
+
+# Check for silent output and failure
+atf_check -s exit:1 -o empty -e empty 'false'
+
+# Check for known stdout and silent stderr
+echo foo >expout
+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"
+
+# Or just do the match along the way
+atf_check -s exit:0 -o match:"^foo$" -e empty 'ls'
+.Ed
+.Sh SEE ALSO
+.Xr atf-check 1 ,
+.Xr atf-sh 1 ,
+.Xr atf-test-program 1 ,
+.Xr atf-test-case 4

Added: vendor/atf/dist/atf-sh/atf-sh.cpp
===================================================================
--- vendor/atf/dist/atf-sh/atf-sh.cpp	                        (rev 0)
+++ vendor/atf/dist/atf-sh/atf-sh.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,185 @@
+// Copyright (c) 2010 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.
+
+extern "C" {
+#include <unistd.h>
+}
+
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+
+#include "atf-c++/detail/application.hpp"
+#include "atf-c++/detail/env.hpp"
+#include "atf-c++/detail/fs.hpp"
+#include "atf-c++/detail/sanity.hpp"
+
+// ------------------------------------------------------------------------
+// Auxiliary functions.
+// ------------------------------------------------------------------------
+
+namespace {
+
+static
+std::string
+fix_plain_name(const char *filename)
+{
+    const atf::fs::path filepath(filename);
+    if (filepath.branch_path().str() == ".")
+        return std::string("./") + filename;
+    else
+        return std::string(filename);
+}
+
+static
+std::string*
+construct_script(const char* filename)
+{
+    const std::string libexecdir = atf::env::get(
+        "ATF_LIBEXECDIR", ATF_LIBEXECDIR);
+    const std::string pkgdatadir = atf::env::get(
+        "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 \"${@}\"");
+    return command;
+}
+
+static
+const char**
+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]);
+
+    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];
+
+    for (int i = 1; i < interpreter_argc; i++)
+        argv[4 + i - 1] = interpreter_argv[i];
+
+    argv[count - 1] = NULL;
+
+    return argv;
+}
+
+} // anonymous namespace
+
+// ------------------------------------------------------------------------
+// The "atf_sh" class.
+// ------------------------------------------------------------------------
+
+class atf_sh : public atf::application::app {
+    static const char* m_description;
+
+    atf::fs::path m_shell;
+
+    options_set specific_options(void) const;
+    void process_option(int, const char*);
+
+public:
+    atf_sh(void);
+
+    int main(void);
+};
+
+const char* atf_sh::m_description =
+    "atf-sh is a shell interpreter that extends the functionality of the "
+    "system sh(1) with the atf-sh library.";
+
+atf_sh::atf_sh(void) :
+    app(m_description, "atf-sh(1)"),
+    m_shell(atf::fs::path(atf::env::get("ATF_SHELL", ATF_SHELL)))
+{
+}
+
+atf_sh::options_set
+atf_sh::specific_options(void)
+    const
+{
+    using atf::application::option;
+    options_set opts;
+
+    INV(m_shell == atf::fs::path(atf::env::get("ATF_SHELL", ATF_SHELL)));
+    opts.insert(option('s', "shell", "Path to the shell interpreter to use; "
+                       "default: " + m_shell.str()));
+
+    return opts;
+}
+
+void
+atf_sh::process_option(int ch, const char* arg)
+{
+    switch (ch) {
+    case 's':
+        m_shell = atf::fs::path(arg);
+        break;
+
+    default:
+        UNREACHABLE;
+    }
+}
+
+int
+atf_sh::main(void)
+{
+    if (m_argc < 1)
+        throw atf::application::usage_error("No test program provided");
+
+    const atf::fs::path script(m_argv[0]);
+    if (!atf::fs::exists(script))
+        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.
+
+    const int ret = execv(m_shell.c_str(), const_cast< char** >(argv));
+    INV(ret == -1);
+    std::cerr << "Failed to execute " << m_shell.str() << ": "
+              << std::strerror(errno) << "\n";
+    return EXIT_FAILURE;
+}
+
+int
+main(int argc, char* const* argv)
+{
+    return atf_sh().run(argc, argv);
+}

Added: vendor/atf/dist/atf-sh/atf_check_test.sh
===================================================================
--- vendor/atf/dist/atf-sh/atf_check_test.sh	                        (rev 0)
+++ vendor/atf/dist/atf-sh/atf_check_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,197 @@
+# 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.
+
+# TODO: Bring in the checks in the bootstrap testsuite for atf_check.
+
+atf_test_case info_ok
+info_ok_head()
+{
+    atf_set "descr" "Verifies that atf_check prints an informative" \
+                    "message even when the command is successful"
+}
+info_ok_body()
+{
+    h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+    atf_check -s eq:0 -o save:stdout -e save:stderr -x \
+              "${h} atf_check_info_ok"
+    grep 'Executing command.*true' stdout >/dev/null || \
+        atf_fail "atf_check does not print an informative message"
+
+    atf_check -s eq:0 -o save:stdout -e save:stderr -x \
+              "${h} atf_check_info_fail"
+    grep 'Executing command.*false' stdout >/dev/null || \
+        atf_fail "atf_check does not print an informative message"
+}
+
+atf_test_case expout_mismatch
+expout_mismatch_head()
+{
+    atf_set "descr" "Verifies that atf_check prints a diff of the" \
+                    "stdout and the expected stdout if the two do not" \
+                    "match"
+}
+expout_mismatch_body()
+{
+    h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+    atf_check -s eq:1 -o save:stdout -e save:stderr -x \
+              "${h} atf_check_expout_mismatch"
+    grep 'Executing command.*echo bar' stdout >/dev/null || \
+        atf_fail "atf_check does not print an informative message"
+    grep 'stdout does not match golden output' stderr >/dev/null || \
+        atf_fail "atf_check does not print the stdout header"
+    grep 'stderr' stderr >/dev/null && \
+        atf_fail "atf_check prints the stderr header"
+    grep '^-foo' stderr >/dev/null || \
+        atf_fail "atf_check does not print the stdout's diff"
+    grep '^+bar' stderr >/dev/null || \
+        atf_fail "atf_check does not print the stdout's diff"
+}
+
+atf_test_case experr_mismatch
+experr_mismatch_head()
+{
+    atf_set "descr" "Verifies that atf_check prints a diff of the" \
+                    "stderr and the expected stderr if the two do not" \
+                    "match"
+}
+experr_mismatch_body()
+{
+    h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+    atf_check -s eq:1 -o save:stdout -e save:stderr -x \
+              "${h} atf_check_experr_mismatch"
+    grep 'Executing command.*echo bar' stdout >/dev/null || \
+        atf_fail "atf_check does not print an informative message"
+    grep 'stdout' stderr >/dev/null && \
+        atf_fail "atf_check prints the stdout header"
+    grep 'stderr does not match golden output' stderr >/dev/null || \
+        atf_fail "atf_check does not print the stderr header"
+    grep '^-foo' stderr >/dev/null || \
+        atf_fail "atf_check does not print the stderr's diff"
+    grep '^+bar' stderr >/dev/null || \
+        atf_fail "atf_check does not print the stderr's diff"
+}
+
+atf_test_case null_stdout
+null_stdout_head()
+{
+    atf_set "descr" "Verifies that atf_check prints a the stdout it got" \
+                    "when it was supposed to be null"
+}
+null_stdout_body()
+{
+    h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+    atf_check -s eq:1 -o save:stdout -e save:stderr -x \
+              "${h} atf_check_null_stdout"
+    grep 'Executing command.*echo.*These.*contents' stdout >/dev/null || \
+        atf_fail "atf_check does not print an informative message"
+    grep 'stdout not empty' stderr >/dev/null || \
+        atf_fail "atf_check does not print the stdout header"
+    grep 'stderr' stderr >/dev/null && \
+        atf_fail "atf_check prints the stderr header"
+    grep 'These are the contents' stderr >/dev/null || \
+        atf_fail "atf_check does not print stdout's contents"
+}
+
+atf_test_case null_stderr
+null_stderr_head()
+{
+    atf_set "descr" "Verifies that atf_check prints a the stderr it got" \
+                    "when it was supposed to be null"
+}
+null_stderr_body()
+{
+    h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+    atf_check -s eq:1 -o save:stdout -e save:stderr -x \
+              "${h} atf_check_null_stderr"
+    grep 'Executing command.*echo.*These.*contents' stdout >/dev/null || \
+        atf_fail "atf_check does not print an informative message"
+    grep 'stdout' stderr >/dev/null && \
+        atf_fail "atf_check prints the stdout header"
+    grep 'stderr not empty' stderr >/dev/null || \
+        atf_fail "atf_check does not print the stderr header"
+    grep 'These are the contents' stderr >/dev/null || \
+        atf_fail "atf_check does not print stderr's contents"
+}
+
+atf_test_case equal
+equal_head()
+{
+    atf_set "descr" "Verifies that atf_check_equal works"
+}
+equal_body()
+{
+    h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+    atf_check -s eq:0 -o ignore -e ignore -x "${h} atf_check_equal_ok"
+
+    atf_check -s eq:1 -o ignore -e ignore -x \
+        "${h} -r resfile atf_check_equal_fail"
+    atf_check -s eq:0 -o ignore -e empty grep '^failed: a != b (a != b)$' \
+        resfile
+
+    atf_check -s eq:0 -o ignore -e ignore -x "${h} atf_check_equal_eval_ok"
+
+    atf_check -s eq:1 -o ignore -e ignore -x \
+        "${h} -r resfile atf_check_equal_eval_fail"
+    atf_check -s eq:0 -o ignore -e empty \
+        grep '^failed: \${x} != \${y} (a != b)$' resfile
+}
+
+atf_test_case flush_stdout_on_death
+flush_stdout_on_death_body()
+{
+    CONTROL_FILE="$(pwd)/done" "$(atf_get_srcdir)/misc_helpers" \
+        -s "$(atf_get_srcdir)" atf_check_flush_stdout >out 2>err &
+    pid="${!}"
+    while [ ! -f ./done ]; do
+        echo "Still waiting for helper to create control file"
+        ls
+        sleep 1
+    done
+    kill -9 "${pid}"
+
+    grep 'Executing command.*true' out \
+        || atf_fail 'First command not in output'
+    grep 'Executing command.*false' out \
+        || atf_fail 'Second command not in output'
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case info_ok
+    atf_add_test_case expout_mismatch
+    atf_add_test_case experr_mismatch
+    atf_add_test_case null_stdout
+    atf_add_test_case null_stderr
+    atf_add_test_case equal
+    atf_add_test_case flush_stdout_on_death
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/atf-sh/config_test.sh
===================================================================
--- vendor/atf/dist/atf-sh/config_test.sh	                        (rev 0)
+++ vendor/atf/dist/atf-sh/config_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,79 @@
+# 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.
+
+atf_test_case has
+has_head()
+{
+    atf_set "descr" "Verifies that atf_config_has works"
+}
+has_body()
+{
+    h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+    atf_check -s eq:0 -o match:'foo not found' -e ignore -x \
+              "TEST_VARIABLE=foo ${h} config_has"
+
+    atf_check -s eq:0 -o match:'foo found' -e ignore -x \
+              "TEST_VARIABLE=foo ${h} -v foo=bar config_has"
+
+    echo "Checking for deprecated variables"
+    atf_check -s eq:0 -o match:'workdir not found' -e ignore -x \
+              "TEST_VARIABLE=workdir ${h} config_has"
+}
+
+atf_test_case get
+get_head()
+{
+    atf_set "descr" "Verifies that atf_config_get works"
+}
+get_body()
+{
+    h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+
+    echo "Querying an undefined variable"
+    ( atf_config_get "undefined" ) >out 2>err && \
+        atf_fail "Getting an undefined variable succeeded"
+    grep 'not find' err || \
+        atf_fail "Getting an undefined variable did not report an error"
+
+    echo "Querying an undefined variable using a default value"
+    v=$(atf_config_get "undefined" "the default value")
+    [ "${v}" = "the default value" ] || \
+        atf_fail "Default value does not work"
+
+    atf_check -s eq:0 -o match:'foo = bar' -e ignore -x \
+              "TEST_VARIABLE=foo ${h} -v foo=bar config_get"
+
+    atf_check -s eq:0 -o match:'foo = baz' -e ignore -x \
+              "TEST_VARIABLE=foo ${h} -v foo=baz config_get"
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case has
+    atf_add_test_case get
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/atf-sh/integration_test.sh
===================================================================
--- vendor/atf/dist/atf-sh/integration_test.sh	                        (rev 0)
+++ vendor/atf/dist/atf-sh/integration_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,160 @@
+# Copyright (c) 2010 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.
+
+: ${ATF_SH:="__ATF_SH__"}
+
+create_test_program() {
+    local output="${1}"; shift
+    echo "#! ${ATF_SH} ${*}" >"${output}"
+    cat >>"${output}"
+    chmod +x "${output}"
+}
+
+atf_test_case no_args
+no_args_body()
+{
+    cat >experr <<EOF
+atf-sh: ERROR: No test program provided
+atf-sh: See atf-sh(1) for usage details.
+EOF
+    atf_check -s eq:1 -o ignore -e file:experr "${ATF_SH}"
+}
+
+atf_test_case missing_script
+missing_script_body()
+{
+    cat >experr <<EOF
+atf-sh: ERROR: The test program 'non-existent' does not exist
+EOF
+    atf_check -s eq:1 -o ignore -e file:experr "${ATF_SH}" non-existent
+}
+
+atf_test_case arguments
+arguments_body()
+{
+    create_test_program tp <<EOF
+main() {
+    echo ">>>\${0}<<<"
+    while test \${#} -gt 0; do
+        echo ">>>\${1}<<<"
+        shift
+    done
+    true
+}
+EOF
+
+    cat >expout <<EOF
+>>>./tp<<<
+>>> a b <<<
+>>>foo<<<
+EOF
+    atf_check -s eq:0 -o file:expout -e empty ./tp ' a b ' foo
+
+    cat >expout <<EOF
+>>>tp<<<
+>>> hello bye <<<
+>>>foo bar<<<
+EOF
+    atf_check -s eq:0 -o file:expout -e empty "${ATF_SH}" tp \
+        ' hello bye ' 'foo bar'
+}
+
+atf_test_case custom_shell__command_line
+custom_shell__command_line_body()
+{
+    cat >expout <<EOF
+This is the custom shell
+This is the test program
+EOF
+
+    cat >custom-shell <<EOF
+#! /bin/sh
+echo "This is the custom shell"
+exec /bin/sh "\${@}"
+EOF
+    chmod +x custom-shell
+
+    echo 'main() { echo "This is the test program"; }' | create_test_program tp
+    atf_check -s eq:0 -o file:expout -e empty "${ATF_SH}" -s ./custom-shell tp
+}
+
+atf_test_case custom_shell__shebang
+custom_shell__shebang_body()
+{
+    cat >expout <<EOF
+This is the custom shell
+This is the test program
+EOF
+
+    cat >custom-shell <<EOF
+#! /bin/sh
+echo "This is the custom shell"
+exec /bin/sh "\${@}"
+EOF
+    chmod +x custom-shell
+
+    echo 'main() { echo "This is the test program"; }' | create_test_program \
+        tp "-s$(pwd)/custom-shell"
+    atf_check -s eq:0 -o file:expout -e empty ./tp
+}
+
+atf_test_case set_e
+set_e_head()
+{
+    atf_set "descr" "Simple test to validate that atf-sh works even when" \
+        "set -e is enabled"
+}
+set_e_body()
+{
+    cat >custom-shell <<EOF
+#! /bin/sh
+exec /bin/sh -e "\${@}"
+EOF
+    chmod +x custom-shell
+
+    cat >tp <<EOF
+atf_test_case helper
+helper_body() {
+    atf_skip "reached"
+}
+atf_init_test_cases() {
+    atf_add_test_case helper
+}
+EOF
+    atf_check -s eq:0 -o match:skipped.*reached \
+        "${ATF_SH}" -s ./custom-shell tp helper
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case no_args
+    atf_add_test_case missing_script
+    atf_add_test_case arguments
+    atf_add_test_case custom_shell__command_line
+    atf_add_test_case custom_shell__shebang
+    atf_add_test_case set_e
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/atf-sh/libatf-sh.subr
===================================================================
--- vendor/atf/dist/atf-sh/libatf-sh.subr	                        (rev 0)
+++ vendor/atf/dist/atf-sh/libatf-sh.subr	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,770 @@
+# 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.
+
+# ------------------------------------------------------------------------
+# GLOBAL VARIABLES
+# ------------------------------------------------------------------------
+
+# Values for the expect property.
+Expect=pass
+Expect_Reason=
+
+# A boolean variable that indicates whether we are parsing a test case's
+# head or not.
+Parsing_Head=false
+
+# The program name.
+Prog_Name=${0##*/}
+
+# The file to which the test case will print its result.
+Results_File=
+
+# The test program's source directory: i.e. where its auxiliary data files
+# and helper utilities can be found.  Can be overriden through the '-s' flag.
+Source_Dir="$(dirname ${0})"
+
+# Indicates the test case we are currently processing.
+Test_Case=
+
+# List of meta-data variables for the current test case.
+Test_Case_Vars=
+
+# The list of all test cases provided by the test program.
+Test_Cases=
+
+# ------------------------------------------------------------------------
+# PUBLIC INTERFACE
+# ------------------------------------------------------------------------
+
+#
+# atf_add_test_case tc-name
+#
+#   Adds the given test case to the list of test cases that form the test
+#   program.  The name provided here must be accompanied by two functions
+#   named after it: <tc-name>_head and <tc-name>_body, and optionally by
+#   a <tc-name>_cleanup function.
+#
+atf_add_test_case()
+{
+    Test_Cases="${Test_Cases} ${1}"
+}
+
+#
+# atf_check cmd expcode expout experr
+#
+#   Executes atf-check with given arguments and automatically calls
+#   atf_fail in case of failure.
+#
+atf_check()
+{
+    ${Atf_Check} "${@}" || \
+        atf_fail "atf-check failed; see the output of the test for details"
+}
+
+#
+# atf_check_equal expected_expression actual_expression
+#
+#   Checks that expected_expression's value matches actual_expression's
+#   and, if not, raises an error.  Ideally expected_expression and
+#   actual_expression should be provided quoted (not expanded) so that
+#   the error message is helpful; otherwise it will only show the values,
+#   not the expressions themselves.
+#
+atf_check_equal()
+{
+    eval _val1=\"${1}\"
+    eval _val2=\"${2}\"
+    test "${_val1}" = "${_val2}" || \
+        atf_fail "${1} != ${2} (${_val1} != ${_val2})"
+}
+
+#
+# atf_config_get varname [defvalue]
+#
+#   Prints the value of a configuration variable.  If it is not
+#   defined, prints the given default value.
+#
+atf_config_get()
+{
+    _varname="__tc_config_var_$(_atf_normalize ${1})"
+    if [ ${#} -eq 1 ]; then
+        eval _value=\"\${${_varname}-__unset__}\"
+        [ "${_value}" = __unset__ ] && \
+            _atf_error 1 "Could not find configuration variable \`${1}'"
+        echo ${_value}
+    elif [ ${#} -eq 2 ]; then
+        eval echo \${${_varname}-${2}}
+    else
+        _atf_error 1 "Incorrect number of parameters for atf_config_get"
+    fi
+}
+
+#
+# atf_config_has varname
+#
+#   Returns a boolean indicating if the given configuration variable is
+#   defined or not.
+#
+atf_config_has()
+{
+    _varname="__tc_config_var_$(_atf_normalize ${1})"
+    eval _value=\"\${${_varname}-__unset__}\"
+    [ "${_value}" != __unset__ ]
+}
+
+#
+# atf_expect_death reason
+#
+#   Sets the expectations to 'death'.
+#
+atf_expect_death()
+{
+    _atf_validate_expect
+
+    Expect=death
+    _atf_create_resfile "expected_death: ${*}"
+}
+
+#
+# atf_expect_timeout reason
+#
+#   Sets the expectations to 'timeout'.
+#
+atf_expect_timeout()
+{
+    _atf_validate_expect
+
+    Expect=timeout
+    _atf_create_resfile "expected_timeout: ${*}"
+}
+
+#
+# atf_expect_exit exitcode reason
+#
+#   Sets the expectations to 'exit'.
+#
+atf_expect_exit()
+{
+    _exitcode="${1}"; shift
+
+    _atf_validate_expect
+
+    Expect=exit
+    if [ "${_exitcode}" = "-1" ]; then
+        _atf_create_resfile "expected_exit: ${*}"
+    else
+        _atf_create_resfile "expected_exit(${_exitcode}): ${*}"
+    fi
+}
+
+#
+# atf_expect_fail reason
+#
+#   Sets the expectations to 'fail'.
+#
+atf_expect_fail()
+{
+    _atf_validate_expect
+
+    Expect=fail
+    Expect_Reason="${*}"
+}
+
+#
+# atf_expect_pass
+#
+#   Sets the expectations to 'pass'.
+#
+atf_expect_pass()
+{
+    _atf_validate_expect
+
+    Expect=pass
+    Expect_Reason=
+}
+
+#
+# atf_expect_signal signo reason
+#
+#   Sets the expectations to 'signal'.
+#
+atf_expect_signal()
+{
+    _signo="${1}"; shift
+
+    _atf_validate_expect
+
+    Expect=signal
+    if [ "${_signo}" = "-1" ]; then
+        _atf_create_resfile "expected_signal: ${*}"
+    else
+        _atf_create_resfile "expected_signal(${_signo}): ${*}"
+    fi
+}
+
+#
+# atf_expected_failure msg1 [.. msgN]
+#
+#   Makes the test case report an expected failure with the given error
+#   message.  Multiple words can be provided, which are concatenated with
+#   a single blank space.
+#
+atf_expected_failure()
+{
+    _atf_create_resfile "expected_failure: ${Expect_Reason}: ${*}"
+    exit 0
+}
+
+#
+# atf_fail msg1 [.. msgN]
+#
+#   Makes the test case fail with the given error message.  Multiple
+#   words can be provided, in which case they are joined by a single
+#   blank space.
+#
+atf_fail()
+{
+    case "${Expect}" in
+        fail)
+            atf_expected_failure "${@}"
+            ;;
+        pass)
+            _atf_create_resfile "failed: ${*}"
+            exit 1
+            ;;
+        *)
+            _atf_error 128 "Unreachable"
+            ;;
+    esac
+}
+
+#
+# atf_get varname
+#
+#   Prints the value of a test case-specific variable.  Given that one
+#   should not get the value of non-existent variables, it is fine to
+#   always use this function as 'val=$(atf_get var)'.
+#
+atf_get()
+{
+    eval echo \${__tc_var_${Test_Case}_$(_atf_normalize ${1})}
+}
+
+#
+# atf_get_srcdir
+#
+#   Prints the value of the test case's source directory.
+#
+atf_get_srcdir()
+{
+    echo ${Source_Dir}
+}
+
+#
+# atf_pass
+#
+#   Makes the test case pass.  Shouldn't be used in general, as a test
+#   case that does not explicitly fail is assumed to pass.
+#
+atf_pass()
+{
+    case "${Expect}" in
+        fail)
+            Expect=pass
+            atf_fail "Test case was expecting a failure but got a pass instead"
+            ;;
+        pass)
+            _atf_create_resfile passed
+            exit 0
+            ;;
+        *)
+            _atf_error 128 "Unreachable"
+            ;;
+    esac
+}
+
+#
+# atf_require_prog prog
+#
+#   Checks that the given program name (either provided as an absolute
+#   path or as a plain file name) can be found.  If it is not available,
+#   automatically skips the test case with an appropriate message.
+#
+#   Relative paths are not allowed because the test case cannot predict
+#   where it will be executed from.
+#
+atf_require_prog()
+{
+    _prog=
+    case ${1} in
+    /*)
+        _prog="${1}"
+        [ -x ${_prog} ] || \
+            atf_skip "The required program ${1} could not be found"
+        ;;
+    */*)
+        atf_fail "atf_require_prog does not accept relative path names \`${1}'"
+        ;;
+    *)
+        _prog=$(_atf_find_in_path "${1}")
+        [ -n "${_prog}" ] || \
+            atf_skip "The required program ${1} could not be found" \
+                     "in the PATH"
+        ;;
+    esac
+}
+
+#
+# atf_set varname val1 [.. valN]
+#
+#   Sets the test case's variable 'varname' to the specified values
+#   which are concatenated using a single blank space.  This function
+#   is supposed to be called form the test case's head only.
+#
+atf_set()
+{
+    ${Parsing_Head} || \
+        _atf_error 128 "atf_set called from the test case's body"
+
+    Test_Case_Vars="${Test_Case_Vars} ${1}"
+    _var=$(_atf_normalize ${1}); shift
+    eval __tc_var_${Test_Case}_${_var}=\"\${*}\"
+}
+
+#
+# atf_skip msg1 [.. msgN]
+#
+#   Skips the test case because of the reason provided.  Multiple words
+#   can be given, in which case they are joined by a single blank space.
+#
+atf_skip()
+{
+    _atf_create_resfile "skipped: ${*}"
+    exit 0
+}
+
+#
+# atf_test_case tc-name cleanup
+#
+#   Defines a new test case named tc-name.  The name provided here must be
+#   accompanied by two functions named after it: <tc-name>_head and
+#   <tc-name>_body.  If cleanup is set to 'cleanup', then this also expects
+#   a <tc-name>_cleanup function to be defined.
+#
+atf_test_case()
+{
+    eval "${1}_head() { :; }"
+    eval "${1}_body() { atf_fail 'Test case not implemented'; }"
+    if [ "${2}" = cleanup ]; then
+        eval __has_cleanup_${1}=true
+        eval "${1}_cleanup() { :; }"
+    else
+        eval "${1}_cleanup() {
+            _atf_error 1 'Test case ${1} declared without a cleanup routine'; }"
+    fi
+}
+
+# ------------------------------------------------------------------------
+# PRIVATE INTERFACE
+# ------------------------------------------------------------------------
+
+#
+# _atf_config_set varname val1 [.. valN]
+#
+#   Sets the test case's private variable 'varname' to the specified
+#   values which are concatenated using a single blank space.
+#
+_atf_config_set()
+{
+    _var=$(_atf_normalize ${1}); shift
+    eval __tc_config_var_${_var}=\"\${*}\"
+    Config_Vars="${Config_Vars} __tc_config_var_${_var}"
+}
+
+#
+# _atf_config_set_str varname=val
+#
+#   Sets the test case's private variable 'varname' to the specified
+#   value.  The parameter is of the form 'varname=val'.
+#
+_atf_config_set_from_str()
+{
+    _oldifs=${IFS}
+    IFS='='
+    set -- ${*}
+    _var=${1}
+    shift
+    _val="${@}"
+    IFS=${_oldifs}
+    _atf_config_set "${_var}" "${_val}"
+}
+
+#
+# _atf_create_resfile contents
+#
+#   Creates the results file.
+#
+_atf_create_resfile()
+{
+    if [ -n "${Results_File}" ]; then
+        echo "${*}" >"${Results_File}" || \
+            _atf_error 128 "Cannot create results file '${Results_File}'"
+    else
+        echo "${*}"
+    fi
+}
+
+#
+# _atf_error error_code [msg1 [.. msgN]]
+#
+#   Prints the given error message (which can be composed of multiple
+#   arguments, in which case are joined by a single space) and exits
+#   with the specified error code.
+#
+#   This must not be used by test programs themselves (hence making
+#   the function private) to indicate a test case's failure.  They
+#   have to use the atf_fail function.
+#
+_atf_error()
+{
+    _error_code="${1}"; shift
+
+    echo "${Prog_Name}: ERROR:" "$@" 1>&2
+    exit ${_error_code}
+}
+
+#
+# _atf_warning msg1 [.. msgN]
+#
+#   Prints the given warning message (which can be composed of multiple
+#   arguments, in which case are joined by a single space).
+#
+_atf_warning()
+{
+    echo "${Prog_Name}: WARNING:" "$@" 1>&2
+}
+
+#
+# _atf_find_in_path program
+#
+#   Looks for a program in the path and prints the full path to it or
+#   nothing if it could not be found.  It also returns true in case of
+#   success.
+#
+_atf_find_in_path()
+{
+    _prog="${1}"
+
+    _oldifs=${IFS}
+    IFS=:
+    for _dir in ${PATH}
+    do
+        if [ -x ${_dir}/${_prog} ]; then
+            IFS=${_oldifs}
+            echo ${_dir}/${_prog}
+            return 0
+        fi
+    done
+    IFS=${_oldifs}
+
+    return 1
+}
+
+#
+# _atf_has_tc name
+#
+#   Returns true if the given test case exists.
+#
+_atf_has_tc()
+{
+    for _tc in ${Test_Cases}; do
+        [ "${_tc}" != "${1}" ] || return 0
+    done
+    return 1
+}
+
+#
+# _atf_list_tcs
+#
+#   Describes all test cases and prints the list to the standard output.
+#
+_atf_list_tcs()
+{
+    echo 'Content-Type: application/X-atf-tp; version="1"'
+    echo
+
+    set -- ${Test_Cases}
+    while [ ${#} -gt 0 ]; do
+        _atf_parse_head ${1}
+
+        echo "ident: $(atf_get ident)"
+        for _var in ${Test_Case_Vars}; do
+            [ "${_var}" != "ident" ] && echo "${_var}: $(atf_get ${_var})"
+        done
+
+        [ ${#} -gt 1 ] && echo
+        shift
+    done
+}
+
+#
+# _atf_normalize str
+#
+#   Normalizes a string so that it is a valid shell variable name.
+#
+_atf_normalize()
+{
+    echo ${1} | tr .- __
+}
+
+#
+# _atf_parse_head tcname
+#
+#   Evaluates a test case's head to gather its variables and prepares the
+#   test program to run it.
+#
+_atf_parse_head()
+{
+    Parsing_Head=true
+
+    Test_Case="${1}"
+    Test_Case_Vars=
+
+    if _atf_has_cleanup "${1}"; then
+        atf_set has.cleanup "true"
+    fi
+
+    ${1}_head
+    atf_set ident "${1}"
+
+    Parsing_Head=false
+}
+
+#
+# _atf_run_tc tc
+#
+#   Runs the specified test case.  Prints its exit status to the
+#   standard output and returns a boolean indicating if the test was
+#   successful or not.
+#
+_atf_run_tc()
+{
+    case ${1} in
+    *:*)
+        _tcname=${1%%:*}
+        _tcpart=${1#*:}
+
+        if [ "${_tcpart}" != body -a "${_tcpart}" != cleanup ]; then
+            _atf_syntax_error "Unknown test case part \`${_tcpart}'"
+        fi
+        ;;
+
+    *)
+        _tcname=${1}
+        _tcpart=body
+        ;;
+    esac
+
+    _atf_has_tc "${_tcname}" || _atf_syntax_error "Unknown test case \`${1}'"
+
+    if [ "${__RUNNING_INSIDE_ATF_RUN}" != "internal-yes-value" ]; then
+        _atf_warning "Running test cases outside of kyua(1) is unsupported"
+        _atf_warning "No isolation nor timeout control is being applied;" \
+            "you may get unexpected failures; see atf-test-case(4)"
+    fi
+
+    _atf_parse_head ${_tcname}
+
+    case ${_tcpart} in
+    body)
+        if ${_tcname}_body; then
+            _atf_validate_expect
+            _atf_create_resfile passed
+        else
+            Expect=pass
+            atf_fail "Test case body returned a non-ok exit code, but" \
+                "this is not allowed"
+        fi
+        ;;
+    cleanup)
+        if _atf_has_cleanup "${_tcname}"; then
+            ${_tcname}_cleanup || _atf_error 128 "The test case cleanup" \
+                "returned a non-ok exit code, but this is not allowed"
+        fi
+        ;;
+    *)
+        _atf_error 128 "Unknown test case part"
+        ;;
+    esac
+}
+
+#
+# _atf_syntax_error msg1 [.. msgN]
+#
+#   Formats and prints a syntax error message and terminates the
+#   program prematurely.
+#
+_atf_syntax_error()
+{
+    echo "${Prog_Name}: ERROR: ${@}" 1>&2
+    echo "${Prog_Name}: See atf-test-program(1) for usage details." 1>&2
+    exit 1
+}
+
+#
+# _atf_has_cleanup tc-name
+#
+#   Returns a boolean indicating if the given test case has a cleanup
+#   routine or not.
+#
+_atf_has_cleanup()
+{
+    _found=true
+    eval "[ x\"\${__has_cleanup_${1}}\" = xtrue ] || _found=false"
+    [ "${_found}" = true ]
+}
+
+#
+# _atf_validate_expect
+#
+#   Ensures that the current test case state is correct regarding the expect
+#   status.
+#
+_atf_validate_expect()
+{
+    case "${Expect}" in
+        death)
+            Expect=pass
+            atf_fail "Test case was expected to terminate abruptly but it" \
+                "continued execution"
+            ;;
+        exit)
+            Expect=pass
+            atf_fail "Test case was expected to exit cleanly but it continued" \
+                "execution"
+            ;;
+        fail)
+            Expect=pass
+            atf_fail "Test case was expecting a failure but none were raised"
+            ;;
+        pass)
+            ;;
+        signal)
+            Expect=pass
+            atf_fail "Test case was expected to receive a termination signal" \
+                "but it continued execution"
+            ;;
+        timeout)
+            Expect=pass
+            atf_fail "Test case was expected to hang but it continued execution"
+            ;;
+        *)
+            _atf_error 128 "Unreachable"
+            ;;
+    esac
+}
+
+#
+# _atf_warning [msg1 [.. msgN]]
+#
+#   Prints the given warning message (which can be composed of multiple
+#   arguments, in which case are joined by a single space).
+#
+#   This must not be used by test programs themselves (hence making
+#   the function private).
+#
+_atf_warning()
+{
+    echo "${Prog_Name}: WARNING:" "$@" 1>&2
+}
+
+#
+# main [options] test_case
+#
+#   Test program's entry point.
+#
+main()
+{
+    # Process command-line options first.
+    _numargs=${#}
+    _lflag=false
+    while getopts :lr:s:v: arg; do
+        case ${arg} in
+        l)
+            _lflag=true
+            ;;
+
+        r)
+            Results_File=${OPTARG}
+            ;;
+
+        s)
+            Source_Dir=${OPTARG}
+            ;;
+
+        v)
+            _atf_config_set_from_str "${OPTARG}"
+            ;;
+
+        \?)
+            _atf_syntax_error "Unknown option -${OPTARG}."
+            # NOTREACHED
+            ;;
+        esac
+    done
+    shift `expr ${OPTIND} - 1`
+
+    case ${Source_Dir} in
+        /*)
+            ;;
+        *)
+            Source_Dir=$(pwd)/${Source_Dir}
+            ;;
+    esac
+    [ -f ${Source_Dir}/${Prog_Name} ] || \
+        _atf_error 1 "Cannot find the test program in the source" \
+                     "directory \`${Source_Dir}'"
+
+    # Call the test program's hook to register all available test cases.
+    atf_init_test_cases
+
+    # Run or list test cases.
+    if `${_lflag}`; then
+        if [ ${#} -gt 0 ]; then
+            _atf_syntax_error "Cannot provide test case names with -l"
+        fi
+        _atf_list_tcs
+    else
+        if [ ${#} -eq 0 ]; then
+            _atf_syntax_error "Must provide a test case name"
+        elif [ ${#} -gt 1 ]; then
+            _atf_syntax_error "Cannot provide more than one test case name"
+        else
+            _atf_run_tc "${1}"
+        fi
+    fi
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/atf-sh/misc_helpers.sh
===================================================================
--- vendor/atf/dist/atf-sh/misc_helpers.sh	                        (rev 0)
+++ vendor/atf/dist/atf-sh/misc_helpers.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,309 @@
+# 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.
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_atf_check".
+# -------------------------------------------------------------------------
+
+atf_test_case atf_check_info_ok
+atf_check_info_ok_head()
+{
+    atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_info_ok_body()
+{
+    atf_check -s eq:0 -o empty -e empty true
+}
+
+atf_test_case atf_check_info_fail
+atf_check_info_fail_head()
+{
+    atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_info_fail_body()
+{
+    # In Solaris, /usr/bin/false returns 255 rather than 1.  Use the
+    # built-in version for the check.
+    atf_check -s eq:1 -o empty -e empty sh -c "false"
+}
+
+atf_test_case atf_check_expout_mismatch
+atf_check_expout_mismatch_head()
+{
+    atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_expout_mismatch_body()
+{
+    cat >expout <<SECONDEOF
+foo
+SECONDEOF
+    atf_check -s eq:0 -o file:expout -e empty echo bar
+}
+
+atf_test_case atf_check_experr_mismatch
+atf_check_experr_mismatch_head()
+{
+    atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_experr_mismatch_body()
+{
+    cat >experr <<SECONDEOF
+foo
+SECONDEOF
+    atf_check -s eq:0 -o empty -e file:experr -x 'echo bar 1>&2'
+}
+
+atf_test_case atf_check_null_stdout
+atf_check_null_stdout_head()
+{
+    atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_null_stdout_body()
+{
+    atf_check -s eq:0 -o empty -e empty echo "These are the contents"
+}
+
+atf_test_case atf_check_null_stderr
+atf_check_null_stderr_head()
+{
+    atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_null_stderr_body()
+{
+    atf_check -s eq:0 -o empty -e empty -x 'echo "These are the contents" 1>&2'
+}
+
+atf_test_case atf_check_equal_ok
+atf_check_equal_ok_head()
+{
+    atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_equal_ok_body()
+{
+    atf_check_equal a a
+}
+
+atf_test_case atf_check_equal_fail
+atf_check_equal_fail_head()
+{
+    atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_equal_fail_body()
+{
+    atf_check_equal a b
+}
+
+atf_test_case atf_check_equal_eval_ok
+atf_check_equal_eval_ok_head()
+{
+    atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_equal_eval_ok_body()
+{
+    x=a
+    y=a
+    atf_check_equal '${x}' '${y}'
+}
+
+atf_test_case atf_check_equal_eval_fail
+atf_check_equal_eval_fail_head()
+{
+    atf_set "descr" "Helper test case for the t_atf_check test program"
+}
+atf_check_equal_eval_fail_body()
+{
+    x=a
+    y=b
+    atf_check_equal '${x}' '${y}'
+}
+
+atf_test_case atf_check_flush_stdout
+atf_check_flush_stdout_head()
+{
+    atf_set "descr" "Helper test case for the t_atf_check test program"
+    atf_set "timeout" "30"
+}
+atf_check_flush_stdout_body()
+{
+    atf_check true
+    atf_check -s exit:1 false
+    touch "${CONTROL_FILE:-done}"
+    while :; do
+        sleep 1
+    done
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_config".
+# -------------------------------------------------------------------------
+
+atf_test_case config_get
+config_get_head()
+{
+    atf_set "descr" "Helper test case for the t_config test program"
+}
+config_get_body()
+{
+    if atf_config_has ${TEST_VARIABLE}; then
+        echo "${TEST_VARIABLE} = $(atf_config_get ${TEST_VARIABLE})"
+    fi
+}
+
+atf_test_case config_has
+config_has_head()
+{
+    atf_set "descr" "Helper test case for the t_config test program"
+}
+config_has_body()
+{
+    if atf_config_has ${TEST_VARIABLE}; then
+        echo "${TEST_VARIABLE} found"
+    else
+        echo "${TEST_VARIABLE} not found"
+    fi
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_normalize".
+# -------------------------------------------------------------------------
+
+atf_test_case normalize
+normalize_head()
+{
+    atf_set "descr" "Helper test case for the t_normalize test program"
+    atf_set "a.b" "test value 1"
+    atf_set "c-d" "test value 2"
+}
+normalize_body()
+{
+    echo "a.b: $(atf_get a.b)"
+    echo "c-d: $(atf_get c-d)"
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_tc".
+# -------------------------------------------------------------------------
+
+atf_test_case tc_pass_true
+tc_pass_true_head()
+{
+    atf_set "descr" "Helper test case for the t_tc test program"
+}
+tc_pass_true_body()
+{
+    true
+}
+
+atf_test_case tc_pass_false
+tc_pass_false_head()
+{
+    atf_set "descr" "Helper test case for the t_tc test program"
+}
+tc_pass_false_body()
+{
+    false
+}
+
+atf_test_case tc_pass_return_error
+tc_pass_return_error_head()
+{
+    atf_set "descr" "Helper test case for the t_tc test program"
+}
+tc_pass_return_error_body()
+{
+    return 1
+}
+
+atf_test_case tc_fail
+tc_fail_head()
+{
+    atf_set "descr" "Helper test case for the t_tc test program"
+}
+tc_fail_body()
+{
+    echo "An error" 1>&2
+    exit 1
+}
+
+atf_test_case tc_missing_body
+tc_missing_body_head()
+{
+    atf_set "descr" "Helper test case for the t_tc test program"
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_tp".
+# -------------------------------------------------------------------------
+
+atf_test_case tp_srcdir
+tp_srcdir_head()
+{
+    atf_set "descr" "Helper test case for the t_tp test program"
+}
+tp_srcdir_body()
+{
+    echo "Calling helper"
+    helper_subr || atf_fail "Could not call helper subroutine"
+}
+
+# -------------------------------------------------------------------------
+# Main.
+# -------------------------------------------------------------------------
+
+atf_init_test_cases()
+{
+    # Add helper tests for t_atf_check.
+    atf_add_test_case atf_check_info_ok
+    atf_add_test_case atf_check_info_fail
+    atf_add_test_case atf_check_expout_mismatch
+    atf_add_test_case atf_check_experr_mismatch
+    atf_add_test_case atf_check_null_stdout
+    atf_add_test_case atf_check_null_stderr
+    atf_add_test_case atf_check_equal_ok
+    atf_add_test_case atf_check_equal_fail
+    atf_add_test_case atf_check_equal_eval_ok
+    atf_add_test_case atf_check_equal_eval_fail
+    atf_add_test_case atf_check_flush_stdout
+
+    # Add helper tests for t_config.
+    atf_add_test_case config_get
+    atf_add_test_case config_has
+
+    # Add helper tests for t_normalize.
+    atf_add_test_case normalize
+
+    # Add helper tests for t_tc.
+    atf_add_test_case tc_pass_true
+    atf_add_test_case tc_pass_false
+    atf_add_test_case tc_pass_return_error
+    atf_add_test_case tc_fail
+    atf_add_test_case tc_missing_body
+
+    # Add helper tests for t_tp.
+    [ -f $(atf_get_srcdir)/subrs ] && . $(atf_get_srcdir)/subrs
+    atf_add_test_case tp_srcdir
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/atf-sh/normalize_test.sh
===================================================================
--- vendor/atf/dist/atf-sh/normalize_test.sh	                        (rev 0)
+++ vendor/atf/dist/atf-sh/normalize_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,44 @@
+# 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.
+
+atf_test_case main
+main_head()
+{
+    atf_set "descr" "Verifies that variable names with symbols not" \
+                    "allowed as part of shell variable names work"
+}
+main_body()
+{
+    h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+    atf_check -s eq:0 -o match:'a.b: test value 1' \
+        -o match:'c-d: test value 2' -e ignore ${h} normalize
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case main
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/atf-sh/tc_test.sh
===================================================================
--- vendor/atf/dist/atf-sh/tc_test.sh	                        (rev 0)
+++ vendor/atf/dist/atf-sh/tc_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,60 @@
+# 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.
+
+atf_test_case default_status
+default_status_head()
+{
+    atf_set "descr" "Verifies that test cases get the correct default" \
+                    "status if they did not provide any"
+}
+default_status_body()
+{
+    h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+    atf_check -s eq:0 -o ignore -e ignore ${h} tc_pass_true
+    atf_check -s eq:1 -o ignore -e ignore ${h} tc_pass_false
+    atf_check -s eq:1 -o match:'failed:.*body.*non-ok exit code' -e ignore \
+        ${h} tc_pass_return_error
+    atf_check -s eq:1 -o ignore -e match:'An error' ${h} tc_fail
+}
+
+atf_test_case missing_body
+missing_body_head()
+{
+    atf_set "descr" "Verifies that test cases without a body are reported" \
+                    "as failed"
+}
+missing_body_body()
+{
+    h="$(atf_get_srcdir)/misc_helpers -s $(atf_get_srcdir)"
+    atf_check -s eq:1 -o ignore -e ignore ${h} tc_missing_body
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case default_status
+    atf_add_test_case missing_body
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/atf-sh/tp_test.sh
===================================================================
--- vendor/atf/dist/atf-sh/tp_test.sh	                        (rev 0)
+++ vendor/atf/dist/atf-sh/tp_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,52 @@
+# 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.
+
+atf_test_case srcdir
+srcdir_head()
+{
+    atf_set "descr" "Verifies that the source directory can be queried" \
+                    "from the initialization function"
+}
+srcdir_body()
+{
+    mkdir work
+    atf_check -s eq:0 -o empty -e empty cp "$(atf_get_srcdir)/misc_helpers" work
+    cat >work/subrs <<EOF
+helper_subr() {
+    echo "This is a helper subroutine"
+}
+EOF
+
+    atf_check -s eq:0 -o match:'Calling helper' \
+        -o match:'This is a helper subroutine' -e ignore ./work/misc_helpers \
+        -s "$(pwd)"/work tp_srcdir
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case srcdir
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/config.h
===================================================================
--- vendor/atf/dist/config.h	                        (rev 0)
+++ vendor/atf/dist/config.h	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,92 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if basename takes a constant pointer */
+#define HAVE_CONST_BASENAME 1
+
+/* Define to 1 if dirname takes a constant pointer */
+#define HAVE_CONST_DIRNAME 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if getcwd(NULL, 0) works */
+#define HAVE_GETCWD_DYN 1
+
+/* Define to 1 if getopt allows a + sign for POSIX behavior */
+/* #undef HAVE_GNU_GETOPT */
+
+/* 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 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 <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* 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 the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "atf"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "atf-discuss at googlegroups.com"
+
+/* Define to the copyright string applicable to this package. */
+#define PACKAGE_COPYRIGHT "Copyright (c) 2007-2012 The NetBSD Foundation, Inc."
+
+/* Define to the full name of this package. */
+#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 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 to the version of this package. */
+#define PACKAGE_VERSION "0.21"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.21"

Added: vendor/atf/dist/doc/atf-test-case.4
===================================================================
--- vendor/atf/dist/doc/atf-test-case.4	                        (rev 0)
+++ vendor/atf/dist/doc/atf-test-case.4	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,321 @@
+.\" 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.
+.Dd March 6, 2017
+.Dt ATF-TEST-CASE 4
+.Os
+.Sh NAME
+.Nm atf-test-case
+.Nd generic description of test cases
+.Sh DESCRIPTION
+A
+.Em test case
+is a piece of code that stress-tests a specific feature of the software.
+This feature is typically self-contained enough, either in the amount of
+code that implements it or in the general idea that describes it, to
+warrant its independent testing.
+Given this, test cases are very fine-grained, but they attempt to group
+similar smaller tests which are semantically related.
+.Pp
+A test case is defined by three components regardless of the language it is
+implemented in: a header, a body and a cleanup routine.
+The
+.Em header
+is, basically, a declarative piece of code that defines several
+properties to describe what the test case does and how it behaves.
+In other words: it defines the test case's
+.Em meta-data ,
+further described in the
+.Sx Meta-data
+section.
+The
+.Em body
+is the test case itself.
+It executes all actions needed to reproduce the test, and checks for
+failures.
+This body is only executed if the abstract conditions specified by the
+header are met.
+The
+.Em cleanup
+routine is a piece of code always executed after the body, regardless of
+the exit status of the test case.
+It can be used to undo side-effects of the test case.
+Note that almost all side-effects of a test case are automatically cleaned
+up by the library; this is explained in more detail in the rest of this
+document.
+.Pp
+It is extremely important to keep the separation between a test case's
+header and body well-defined, because the header is
+.Em always
+parsed, whereas the body is only executed when the conditions defined in
+the header are met and when the user specifies that test case.
+.Pp
+At last, test cases are always contained into test programs.
+The test programs act as a front-end to them, providing a consistent
+interface to the user and several APIs to ease their implementation.
+.Ss Results
+Upon termination, a test case reports a status and, optionally, a textual
+reason describing why the test reported such status.
+The caller must ensure that the test case really performed the task that its
+status describes, as the test program may be bogus and therefore providing a
+misleading result, e.g., providing a result that indicates success but the
+error code of the program says otherwise.
+.Pp
+The possible exit status of a test case are one of the following:
+.Bl -tag -width expectedXfailureXX
+.It expected_death
+The test case expects to terminate abruptly.
+.It expected_exit
+The test case expects to exit cleanly.
+.It expected_failure
+The test case expects to exit with a controller fatal/non-fatal failure.
+If this happens, the test program exits with a success error code.
+.It expected_signal
+The test case expects to receive a signal that makes it terminate.
+.It expected_timeout
+The test case expects to execute for longer than its timeout.
+.It passed
+The test case was executed successfully.
+The test program exits with a success error code.
+.It skipped
+The test case could not be executed because some preconditions were not
+met.
+This is not a failure because it can typically be resolved by adjusting
+the system to meet the necessary conditions.
+This is always accompanied by a
+.Em reason ,
+a message describing why the test was skipped.
+The test program exits with a success error code.
+.It failed
+An error appeared during the execution of the test case.
+This is always accompanied by a
+.Em reason ,
+a message describing why the test failed.
+The test program exits with a failure error code.
+.El
+.Pp
+The usefulness of the
+.Sq expected_*
+results comes when writing test cases that verify known failures caused,
+in general, due to programming errors (aka bugs).
+Whenever the faulty condition that the
+.Sq expected_*
+result is trying to cover is fixed, then the test case will be reported as
+.Sq failed
+and the developer will have to adjust it to match its new condition.
+.Pp
+It is important to note that all
+.Sq expected_*
+results are only provided as a
+.Em hint
+to the caller; the caller must verify that the test case did actually terminate
+as the expected condition says.
+.Ss Input/output
+Test cases are free to print whatever they want to their
+.Xr stdout 4
+and
+.Xr stderr 4
+file descriptors.
+They are, in fact, encouraged to print status information as they execute
+to keep the user informed of their actions.
+This is specially important for long test cases.
+.Pp
+Test cases will log their results to an auxiliary file, which is then
+collected by the test program they are contained in.
+The developer need not care about this as long as he uses the correct
+APIs to implement the test cases.
+.Pp
+The standard input of the test cases is unconditionally connected to
+.Sq /dev/zero .
+.Ss Meta-data
+The following list describes all meta-data properties interpreted
+internally by ATF.
+You are free to define new properties in your test cases and use them as
+you wish, but non-standard properties must be prefixed by
+.Sq X- .
+.Bl -tag -width requireXmachineXX
+.It descr
+Type: textual.
+Required.
+.Pp
+A brief textual description of the test case's purpose.
+Will be shown to the user in reports.
+Also good for documentation purposes.
+.It has.cleanup
+Type: boolean.
+Optional.
+.Pp
+If set to true, specifies that the test case has a cleanup routine that has
+to be executed by the runtime engine during the cleanup phase of the execution.
+This property is automatically set by the framework when defining a test case
+with a cleanup routine, so it should never be set by hand.
+.It ident
+Type: textual.
+Required.
+.Pp
+The test case's identifier.
+Must be unique inside the test program and should be short but descriptive.
+.It require.arch
+Type: textual.
+Optional.
+.Pp
+A whitespace separated list of architectures that the test case can be run
+under without causing errors due to an architecture mismatch.
+.It require.config
+Type: textual.
+Optional.
+.Pp
+A whitespace separated list of configuration variables that must be defined
+to execute the test case.
+If any of the required variables is not defined, the test case is
+.Em skipped .
+.It require.diskspace
+Type: integer.
+Optional.
+Specifies the minimum amount of available disk space needed by the test.
+The value can have a size suffix such as
+.Sq K ,
+.Sq M ,
+.Sq G
+or
+.Sq T
+to make the amount of bytes easier to type and read.
+.It require.files
+Type: textual.
+Optional.
+.Pp
+A whitespace separated list of files that must be present to execute the
+test case.
+The names of these files must be absolute paths.
+If any of the required files is not found, the test case is
+.Em skipped .
+.It require.machine
+Type: textual.
+Optional.
+.Pp
+A whitespace separated list of machine types that the test case can be run
+under without causing errors due to a machine type mismatch.
+.It require.memory
+Type: integer.
+Optional.
+Specifies the minimum amount of physical memory needed by the test.
+The value can have a size suffix such as
+.Sq K ,
+.Sq M ,
+.Sq G
+or
+.Sq T
+to make the amount of bytes easier to type and read.
+.It require.progs
+Type: textual.
+Optional.
+.Pp
+A whitespace separated list of programs that must be present to execute
+the test case.
+These can be given as plain names, in which case they are looked in the
+user's
+.Ev PATH ,
+or as absolute paths.
+If any of the required programs is not found, the test case is
+.Em skipped .
+.It require.user
+Type: textual.
+Optional.
+.Pp
+The required privileges to execute the test case.
+Can be one of
+.Sq root
+or
+.Sq unprivileged .
+.Pp
+If the test case is running as a regular user and this property is
+.Sq root ,
+the test case is
+.Em skipped .
+.Pp
+If the test case is running as root and this property is
+.Sq unprivileged ,
+the runtime engine will automatically drop the privileges if the
+.Sq unprivileged-user
+configuration property is set; otherwise the test case is
+.Em skipped .
+.It timeout
+Type: integral.
+Optional; defaults to
+.Sq 300 .
+.Pp
+Specifies the maximum amount of time the test case can run.
+This is particularly useful because some tests can stall either because they
+are incorrectly coded or because they trigger an anomalous behavior of the
+program.
+It is not acceptable for these tests to stall the whole execution of the
+test program.
+.Pp
+Can optionally be set to zero, in which case the test case has no run-time
+limit.
+This is discouraged.
+.El
+.Ss Environment
+Every time a test case is executed, several environment variables are
+cleared or reseted to sane values to ensure they do not make the test fail
+due to unexpected conditions.
+These variables are:
+.Bl -tag -width LCXMESSAGESXX
+.It Ev HOME
+Set to the work directory's path.
+.It Ev LANG
+Undefined.
+.It Ev LC_ALL
+Undefined.
+.It Ev LC_COLLATE
+Undefined.
+.It Ev LC_CTYPE
+Undefined.
+.It Ev LC_MESSAGES
+Undefined.
+.It Ev LC_MONETARY
+Undefined.
+.It Ev LC_NUMERIC
+Undefined.
+.It Ev LC_TIME
+Undefined.
+.It Ev TZ
+Hardcoded to
+.Sq UTC .
+.El
+.Ss Work directories
+The test program always creates a temporary directory
+and switches to it before running the test case's body.
+This way the test case is free to modify its current directory as it
+wishes, and the runtime engine will be able to clean it up later on in a
+safe way, removing any traces of its execution from the system.
+To do so, the runtime engine will perform a recursive removal of the work
+directory without crossing mount points; if a mount point is found, the
+file system will be unmounted (if possible).
+.Ss File creation mode mask (umask)
+Test cases are always executed with a file creation mode mask (umask) of
+.Sq 0022 .
+The test case's code is free to change this during execution.
+.Sh SEE ALSO
+.Xr atf-test-program 1

Added: vendor/atf/dist/doc/atf-test-program.1
===================================================================
--- vendor/atf/dist/doc/atf-test-program.1	                        (rev 0)
+++ vendor/atf/dist/doc/atf-test-program.1	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,99 @@
+.\" 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.
+.Dd March 2, 2014
+.Dt ATF-TEST-PROGRAM 1
+.Os
+.Sh NAME
+.Nm atf-test-program
+.Nd common interface to ATF test programs
+.Sh SYNOPSIS
+.Nm
+.Op Fl r Ar resfile
+.Op Fl s Ar srcdir
+.Op Fl v Ar var1=value1 Op .. Fl v Ar varN=valueN
+.Ar test_case
+.Nm
+.Fl l
+.Sh DESCRIPTION
+Test programs written using the ATF libraries all share a common user
+interface, which is what this manual page describes.
+.Em NOTE: There is no binary known as
+.Nm ;
+.Em what is described in this manual page is the command-line interface
+.Em exposed by the atf-c, atf-c++ and atf-sh bindings .
+.Pp
+In the first synopsis form, the test program will execute the provided
+test case and print its results to the standard output, unless otherwise
+stated by the
+.Fl r
+flag.
+Optionally, the test case name can be suffixed by
+.Sq :cleanup ,
+in which case the cleanup routine of the test case will be executed
+instead of the test case body; see
+.Xr atf-test-case 4 .
+Note that the test case is
+.Em executed without isolation ,
+so it can and probably will create and modify files in the current directory.
+To execute test cases in a controller manner, you need a runtime engine
+that understands the ATF interface.
+The recommended runtime engine is
+.Xr kyua 1 .
+You should only execute test cases by hand for debugging purposes.
+.Pp
+In the second synopsis form, the test program will list all available
+test cases alongside their meta-data properties in a format that is
+machine parseable.
+This list is processed by
+.Xr kyua 1
+to know how to execute the test cases of a given test program.
+.Pp
+The following options are available:
+.Bl -tag -width XvXvarXvalueXX
+.It Fl l
+Lists available test cases alongside a brief description for each of them.
+.It Fl r Ar resfile
+Specifies the file that will receive the test case result.
+If not specified, the test case prints its results to stdout.
+If the result of a test case needs to be parsed by another program, you must
+use this option to redirect the result to a file and then read the resulting
+file from the other program.
+Note:
+.Em do not try to process the stdout of the test case
+because your program may break in the future.
+.It Fl s Ar srcdir
+The path to the directory where the test program is located.
+This is needed in all cases, except when the test program is being executed
+from the current directory.
+The test program will use this path to locate any helper data files or
+utilities.
+.It Fl v Ar var=value
+Sets the configuration variable
+.Ar var
+to the value
+.Ar value .
+.El
+.Sh SEE ALSO
+.Xr kyua 1

Added: vendor/atf/dist/doc/atf.7.in
===================================================================
--- vendor/atf/dist/doc/atf.7.in	                        (rev 0)
+++ vendor/atf/dist/doc/atf.7.in	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,120 @@
+.\" 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.
+.Dd September 14, 2014
+.Dt ATF 7
+.Os
+.Sh NAME
+.Nm ATF
+.Nd introduction to the Automated Testing Framework
+.Sh DESCRIPTION
+The Automated Testing Framework
+.Pf ( Nm )
+is a
+.Em collection of libraries
+to implement test programs in a variety of languages.
+These libraries all offer similar functionality and any test program
+written with them exposes a consistent user interface.
+.Pp
+Test programs using the
+.Nm
+libraries rely on a separate runtime engine to execute them in a
+deterministic fashion.
+The runtime engine isolates the test programs from the rest of the system
+and ensures some common side-effects are cleaned up.
+The runtime engine is also responsible for gathering the results of all
+tests and composing reports.
+The current runtime of choice is Kyua, described in
+.Xr kyua 1 .
+.Pp
+If your operating systems distributes
+.Nm ,
+it should also provide an introductory
+.Xr tests 7
+manual page.
+You are encouraged to read it now.
+.Pp
+The rest of this manual page serves as a cross-reference to all the other
+documentation shipped with
+.Nm .
+.Ss Language bindings
+.Bl -tag -width atfXtestXprogramXXXXX
+.It Xr atf-c 3
+C programming interface.
+.It Xr atf-c++ 3
+C++ programming interface.
+.It Xr atf-sh 3
+.Xr sh 1
+programming interface.
+.El
+.Ss Miscellaneous pages
+.Bl -tag -width atfXtestXprogramXXXXX
+.It Xr atf-test-case 4
+Generic description of test cases, independent of the language they are
+implemented in.
+.It Xr atf-test-program 1
+Common interface provided by the test programs written using the
+.Nm
+libraries.
+.El
+.Sh SEE ALSO
+.Xr kyua 1 ,
+.Xr tests 7
+.Sh HISTORY
+.Nm
+started as a Google Summer of Code 2007 project mentored by The NetBSD
+Foundation.
+Its original goal was to provide a testing framework for the
+.Nx
+operating system, but it grew as an independent project because the
+framework itself did not need to be tied to a specific operating system.
+.Pp
+Originally,
+.Nm
+shipped the collection of libraries described in this manual page as well
+as a runtime engine.
+The runtime engine has since been replaced by Kyua and the old tools were
+removed in
+.Nm 0.20 ,
+which shipped in early 2014.
+.Pp
+As of late 2014, both
+.Fx
+and
+.Nx
+ship
+.Nm
+in their base systems and provide extensive test suites based on it.
+.Pp
+For more details on historical changes, refer to:
+.Bd -literal -offset indent
+.Pa __DOCDIR__/NEWS
+.Ed
+.Sh AUTHORS
+For more details on the people that made
+.Nm
+possible, refer to:
+.Bd -literal -offset indent
+.Pa __DOCDIR__/AUTHORS
+.Ed

Added: vendor/atf/dist/test-programs/Kyuafile
===================================================================
--- vendor/atf/dist/test-programs/Kyuafile	                        (rev 0)
+++ vendor/atf/dist/test-programs/Kyuafile	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,9 @@
+syntax("kyuafile", 1)
+
+test_suite("atf")
+
+atf_test_program{name="config_test"}
+atf_test_program{name="expect_test"}
+atf_test_program{name="meta_data_test"}
+atf_test_program{name="srcdir_test"}
+atf_test_program{name="result_test"}

Added: vendor/atf/dist/test-programs/c_helpers.c
===================================================================
--- vendor/atf/dist/test-programs/c_helpers.c	                        (rev 0)
+++ vendor/atf/dist/test-programs/c_helpers.c	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,503 @@
+/* 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 <sys/types.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "atf-c/detail/env.h"
+#include "atf-c/detail/fs.h"
+#include "atf-c/detail/test_helpers.h"
+#include "atf-c/detail/text.h"
+#include "atf-c/error.h"
+
+/* ---------------------------------------------------------------------
+ * Auxiliary functions.
+ * --------------------------------------------------------------------- */
+
+static
+void
+safe_remove(const char* path)
+{
+    if (unlink(path) == -1)
+        atf_tc_fail("unlink(2) of %s failed", path);
+}
+
+static
+void
+touch(const char *path)
+{
+    int fd;
+    fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, 0644);
+    if (fd == -1)
+        atf_tc_fail("Could not create file %s", path);
+    close(fd);
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_cleanup".
+ * --------------------------------------------------------------------- */
+
+ATF_TC_WITH_CLEANUP(cleanup_pass);
+ATF_TC_HEAD(cleanup_pass, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
+               "program");
+}
+ATF_TC_BODY(cleanup_pass, tc)
+{
+    touch(atf_tc_get_config_var(tc, "tmpfile"));
+}
+ATF_TC_CLEANUP(cleanup_pass, tc)
+{
+    if (atf_tc_get_config_var_as_bool(tc, "cleanup"))
+        safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
+}
+
+ATF_TC_WITH_CLEANUP(cleanup_fail);
+ATF_TC_HEAD(cleanup_fail, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
+                      "program");
+}
+ATF_TC_BODY(cleanup_fail, tc)
+{
+    touch(atf_tc_get_config_var(tc, "tmpfile"));
+    atf_tc_fail("On purpose");
+}
+ATF_TC_CLEANUP(cleanup_fail, tc)
+{
+    if (atf_tc_get_config_var_as_bool(tc, "cleanup"))
+        safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
+}
+
+ATF_TC_WITH_CLEANUP(cleanup_skip);
+ATF_TC_HEAD(cleanup_skip, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
+                      "program");
+}
+ATF_TC_BODY(cleanup_skip, tc)
+{
+    touch(atf_tc_get_config_var(tc, "tmpfile"));
+    atf_tc_skip("On purpose");
+}
+ATF_TC_CLEANUP(cleanup_skip, tc)
+{
+    if (atf_tc_get_config_var_as_bool(tc, "cleanup"))
+        safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
+}
+
+ATF_TC_WITH_CLEANUP(cleanup_curdir);
+ATF_TC_HEAD(cleanup_curdir, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
+                      "program");
+}
+ATF_TC_BODY(cleanup_curdir, tc)
+{
+    FILE *f;
+
+    f = fopen("oldvalue", "w");
+    if (f == NULL)
+        atf_tc_fail("Failed to create oldvalue file");
+    fprintf(f, "1234");
+    fclose(f);
+}
+ATF_TC_CLEANUP(cleanup_curdir, tc)
+{
+    FILE *f;
+
+    f = fopen("oldvalue", "r");
+    if (f != NULL) {
+        int i;
+        if (fscanf(f, "%d", &i) != 1)
+            fprintf(stderr, "Failed to read old value\n");
+        else
+            printf("Old value: %d", i);
+        fclose(f);
+    }
+}
+
+ATF_TC_WITH_CLEANUP(cleanup_sigterm);
+ATF_TC_HEAD(cleanup_sigterm, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_cleanup test "
+                      "program");
+}
+ATF_TC_BODY(cleanup_sigterm, tc)
+{
+    char *nofile;
+
+    touch(atf_tc_get_config_var(tc, "tmpfile"));
+    kill(getpid(), SIGTERM);
+
+    RE(atf_text_format(&nofile, "%s.no",
+                       atf_tc_get_config_var(tc, "tmpfile")));
+    touch(nofile);
+    free(nofile);
+}
+ATF_TC_CLEANUP(cleanup_sigterm, tc)
+{
+    safe_remove(atf_tc_get_config_var(tc, "tmpfile"));
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_config".
+ * --------------------------------------------------------------------- */
+
+ATF_TC(config_unset);
+ATF_TC_HEAD(config_unset, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
+                      "program");
+}
+ATF_TC_BODY(config_unset, tc)
+{
+    ATF_REQUIRE(!atf_tc_has_config_var(tc, "test"));
+}
+
+ATF_TC(config_empty);
+ATF_TC_HEAD(config_empty, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
+                      "program");
+}
+ATF_TC_BODY(config_empty, tc)
+{
+    ATF_REQUIRE(atf_tc_has_config_var(tc, "test"));
+    ATF_REQUIRE(strlen(atf_tc_get_config_var(tc, "test")) == 0);
+}
+
+ATF_TC(config_value);
+ATF_TC_HEAD(config_value, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
+                      "program");
+}
+ATF_TC_BODY(config_value, tc)
+{
+    ATF_REQUIRE(atf_tc_has_config_var(tc, "test"));
+    ATF_REQUIRE(strcmp(atf_tc_get_config_var(tc, "test"), "foo") == 0);
+}
+
+ATF_TC(config_multi_value);
+ATF_TC_HEAD(config_multi_value, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_config test "
+                      "program");
+}
+ATF_TC_BODY(config_multi_value, tc)
+{
+    ATF_REQUIRE(atf_tc_has_config_var(tc, "test"));
+    ATF_REQUIRE(strcmp(atf_tc_get_config_var(tc, "test"), "foo bar") == 0);
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_expect".
+ * --------------------------------------------------------------------- */
+
+ATF_TC_WITHOUT_HEAD(expect_pass_and_pass);
+ATF_TC_BODY(expect_pass_and_pass, tc)
+{
+    atf_tc_expect_pass();
+
+}
+
+ATF_TC_WITHOUT_HEAD(expect_pass_but_fail_requirement);
+ATF_TC_BODY(expect_pass_but_fail_requirement, tc)
+{
+    atf_tc_expect_pass();
+    atf_tc_fail("Some reason");
+}
+
+ATF_TC_WITHOUT_HEAD(expect_pass_but_fail_check);
+ATF_TC_BODY(expect_pass_but_fail_check, tc)
+{
+    atf_tc_expect_pass();
+    atf_tc_fail_nonfatal("Some reason");
+}
+
+ATF_TC_WITHOUT_HEAD(expect_fail_and_fail_requirement);
+ATF_TC_BODY(expect_fail_and_fail_requirement, tc)
+{
+    atf_tc_expect_fail("Fail %s", "reason");
+    atf_tc_fail("The failure");
+    atf_tc_expect_pass();
+}
+
+ATF_TC_WITHOUT_HEAD(expect_fail_and_fail_check);
+ATF_TC_BODY(expect_fail_and_fail_check, tc)
+{
+    atf_tc_expect_fail("Fail first");
+    atf_tc_fail_nonfatal("abc");
+    atf_tc_expect_pass();
+
+    atf_tc_expect_fail("And fail again");
+    atf_tc_fail_nonfatal("def");
+    atf_tc_expect_pass();
+}
+
+ATF_TC_WITHOUT_HEAD(expect_fail_but_pass);
+ATF_TC_BODY(expect_fail_but_pass, tc)
+{
+    atf_tc_expect_fail("Fail first");
+    atf_tc_fail_nonfatal("abc");
+    atf_tc_expect_pass();
+
+    atf_tc_expect_fail("Will not fail");
+    atf_tc_expect_pass();
+
+    atf_tc_expect_fail("And fail again");
+    atf_tc_fail_nonfatal("def");
+    atf_tc_expect_pass();
+}
+
+ATF_TC_WITHOUT_HEAD(expect_exit_any_and_exit);
+ATF_TC_BODY(expect_exit_any_and_exit, tc)
+{
+    atf_tc_expect_exit(-1, "Call will exit");
+    exit(EXIT_SUCCESS);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_exit_code_and_exit);
+ATF_TC_BODY(expect_exit_code_and_exit, tc)
+{
+    atf_tc_expect_exit(123, "Call will exit");
+    exit(123);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_exit_but_pass);
+ATF_TC_BODY(expect_exit_but_pass, tc)
+{
+    atf_tc_expect_exit(-1, "Call won't exit");
+}
+
+ATF_TC_WITHOUT_HEAD(expect_signal_any_and_signal);
+ATF_TC_BODY(expect_signal_any_and_signal, tc)
+{
+    atf_tc_expect_signal(-1, "Call will signal");
+    kill(getpid(), SIGKILL);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_signal_no_and_signal);
+ATF_TC_BODY(expect_signal_no_and_signal, tc)
+{
+    atf_tc_expect_signal(SIGHUP, "Call will signal");
+    kill(getpid(), SIGHUP);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_signal_but_pass);
+ATF_TC_BODY(expect_signal_but_pass, tc)
+{
+    atf_tc_expect_signal(-1, "Call won't signal");
+}
+
+ATF_TC_WITHOUT_HEAD(expect_death_and_exit);
+ATF_TC_BODY(expect_death_and_exit, tc)
+{
+    atf_tc_expect_death("Exit case");
+    exit(123);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_death_and_signal);
+ATF_TC_BODY(expect_death_and_signal, tc)
+{
+    atf_tc_expect_death("Signal case");
+    kill(getpid(), SIGKILL);
+}
+
+ATF_TC_WITHOUT_HEAD(expect_death_but_pass);
+ATF_TC_BODY(expect_death_but_pass, tc)
+{
+    atf_tc_expect_death("Call won't die");
+}
+
+ATF_TC(expect_timeout_and_hang);
+ATF_TC_HEAD(expect_timeout_and_hang, tc)
+{
+    atf_tc_set_md_var(tc, "timeout", "1");
+}
+ATF_TC_BODY(expect_timeout_and_hang, tc)
+{
+    atf_tc_expect_timeout("Will overrun");
+    sleep(5);
+}
+
+ATF_TC(expect_timeout_but_pass);
+ATF_TC_HEAD(expect_timeout_but_pass, tc)
+{
+    atf_tc_set_md_var(tc, "timeout", "1");
+}
+ATF_TC_BODY(expect_timeout_but_pass, tc)
+{
+    atf_tc_expect_timeout("Will just exit");
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_meta_data".
+ * --------------------------------------------------------------------- */
+
+ATF_TC_WITHOUT_HEAD(metadata_no_descr);
+ATF_TC_BODY(metadata_no_descr, tc)
+{
+}
+
+ATF_TC_WITHOUT_HEAD(metadata_no_head);
+ATF_TC_BODY(metadata_no_head, tc)
+{
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_srcdir".
+ * --------------------------------------------------------------------- */
+
+ATF_TC(srcdir_exists);
+ATF_TC_HEAD(srcdir_exists, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_srcdir test "
+                      "program");
+}
+ATF_TC_BODY(srcdir_exists, tc)
+{
+    atf_fs_path_t p;
+    bool b;
+
+    RE(atf_fs_path_init_fmt(&p, "%s/datafile",
+                            atf_tc_get_config_var(tc, "srcdir")));
+    RE(atf_fs_exists(&p, &b));
+    atf_fs_path_fini(&p);
+    if (!b)
+        atf_tc_fail("Cannot find datafile");
+}
+
+/* ---------------------------------------------------------------------
+ * Helper tests for "t_result".
+ * --------------------------------------------------------------------- */
+
+ATF_TC_WITHOUT_HEAD(result_pass);
+ATF_TC_BODY(result_pass, tc)
+{
+    printf("msg\n");
+}
+
+ATF_TC_WITHOUT_HEAD(result_fail);
+ATF_TC_BODY(result_fail, tc)
+{
+    printf("msg\n");
+    atf_tc_fail("Failure reason");
+}
+
+ATF_TC_WITHOUT_HEAD(result_skip);
+ATF_TC_BODY(result_skip, tc)
+{
+    printf("msg\n");
+    atf_tc_skip("Skipped reason");
+}
+
+ATF_TC(result_newlines_fail);
+ATF_TC_HEAD(result_newlines_fail, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_result test "
+                      "program");
+}
+ATF_TC_BODY(result_newlines_fail, tc)
+{
+    atf_tc_fail("First line\nSecond line");
+}
+
+ATF_TC(result_newlines_skip);
+ATF_TC_HEAD(result_newlines_skip, tc)
+{
+    atf_tc_set_md_var(tc, "descr", "Helper test case for the t_result test "
+                      "program");
+}
+ATF_TC_BODY(result_newlines_skip, tc)
+{
+    atf_tc_skip("First line\nSecond line");
+}
+
+/* ---------------------------------------------------------------------
+ * Main.
+ * --------------------------------------------------------------------- */
+
+ATF_TP_ADD_TCS(tp)
+{
+    /* Add helper tests for t_cleanup. */
+    ATF_TP_ADD_TC(tp, cleanup_pass);
+    ATF_TP_ADD_TC(tp, cleanup_fail);
+    ATF_TP_ADD_TC(tp, cleanup_skip);
+    ATF_TP_ADD_TC(tp, cleanup_curdir);
+    ATF_TP_ADD_TC(tp, cleanup_sigterm);
+
+    /* Add helper tests for t_config. */
+    ATF_TP_ADD_TC(tp, config_unset);
+    ATF_TP_ADD_TC(tp, config_empty);
+    ATF_TP_ADD_TC(tp, config_value);
+    ATF_TP_ADD_TC(tp, config_multi_value);
+
+    /* Add helper tests for t_expect. */
+    ATF_TP_ADD_TC(tp, expect_pass_and_pass);
+    ATF_TP_ADD_TC(tp, expect_pass_but_fail_requirement);
+    ATF_TP_ADD_TC(tp, expect_pass_but_fail_check);
+    ATF_TP_ADD_TC(tp, expect_fail_and_fail_requirement);
+    ATF_TP_ADD_TC(tp, expect_fail_and_fail_check);
+    ATF_TP_ADD_TC(tp, expect_fail_but_pass);
+    ATF_TP_ADD_TC(tp, expect_exit_any_and_exit);
+    ATF_TP_ADD_TC(tp, expect_exit_code_and_exit);
+    ATF_TP_ADD_TC(tp, expect_exit_but_pass);
+    ATF_TP_ADD_TC(tp, expect_signal_any_and_signal);
+    ATF_TP_ADD_TC(tp, expect_signal_no_and_signal);
+    ATF_TP_ADD_TC(tp, expect_signal_but_pass);
+    ATF_TP_ADD_TC(tp, expect_death_and_exit);
+    ATF_TP_ADD_TC(tp, expect_death_and_signal);
+    ATF_TP_ADD_TC(tp, expect_death_but_pass);
+    ATF_TP_ADD_TC(tp, expect_timeout_and_hang);
+    ATF_TP_ADD_TC(tp, expect_timeout_but_pass);
+
+    /* Add helper tests for t_meta_data. */
+    ATF_TP_ADD_TC(tp, metadata_no_descr);
+    ATF_TP_ADD_TC(tp, metadata_no_head);
+
+    /* Add helper tests for t_srcdir. */
+    ATF_TP_ADD_TC(tp, srcdir_exists);
+
+    /* Add helper tests for t_result. */
+    ATF_TP_ADD_TC(tp, result_pass);
+    ATF_TP_ADD_TC(tp, result_fail);
+    ATF_TP_ADD_TC(tp, result_skip);
+    ATF_TP_ADD_TC(tp, result_newlines_fail);
+    ATF_TP_ADD_TC(tp, result_newlines_skip);
+
+    return atf_no_error();
+}

Added: vendor/atf/dist/test-programs/common.sh
===================================================================
--- vendor/atf/dist/test-programs/common.sh	                        (rev 0)
+++ vendor/atf/dist/test-programs/common.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,39 @@
+# Copyright (c) 2008 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.
+
+get_helpers()
+{
+    srcdir=$(atf_get_srcdir)
+
+    if [ ${#} -eq 0 ]; then
+        set -- c_helpers cpp_helpers sh_helpers
+    fi
+
+    for h_name in "${@}"; do
+        echo ${srcdir}/${h_name}
+    done
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/test-programs/config_test.sh
===================================================================
--- vendor/atf/dist/test-programs/config_test.sh	                        (rev 0)
+++ vendor/atf/dist/test-programs/config_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,58 @@
+# 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.
+
+atf_test_case vflag
+vflag_head()
+{
+    atf_set "descr" "Tests that the -v flag works correctly to set" \
+                    "configuration variables"
+}
+vflag_body()
+{
+    for h in $(get_helpers); do
+        atf_check -s eq:0 -o ignore -e ignore ${h} -s $(atf_get_srcdir) \
+            -r resfile config_unset
+        atf_check -s eq:0 -o ignore -e empty grep 'passed' resfile
+
+        atf_check -s eq:0 -o ignore -e ignore ${h} -s $(atf_get_srcdir) \
+            -r resfile -v 'test=' config_empty
+        atf_check -s eq:0 -o ignore -e empty grep 'passed' resfile
+
+        atf_check -s eq:0 -o ignore -e ignore ${h} -s $(atf_get_srcdir) \
+            -r resfile -v 'test=foo' config_value
+        atf_check -s eq:0 -o ignore -e empty grep 'passed' resfile
+
+        atf_check -s eq:0 -o ignore -e ignore -x ${h} -s $(atf_get_srcdir) \
+            -r resfile -v \'test=foo bar\' config_multi_value
+        atf_check -s eq:0 -o ignore -e empty grep 'passed' resfile
+    done
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case vflag
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/test-programs/cpp_helpers.cpp
===================================================================
--- vendor/atf/dist/test-programs/cpp_helpers.cpp	                        (rev 0)
+++ vendor/atf/dist/test-programs/cpp_helpers.cpp	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,355 @@
+// 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.
+
+extern "C" {
+#include <signal.h>
+#include <unistd.h>
+}
+
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+
+#include <atf-c++.hpp>
+
+#include "atf-c++/detail/fs.hpp"
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_config".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(config_unset);
+ATF_TEST_CASE_HEAD(config_unset)
+{
+    set_md_var("descr", "Helper test case for the t_config test program");
+}
+ATF_TEST_CASE_BODY(config_unset)
+{
+    ATF_REQUIRE(!has_config_var("test"));
+}
+
+ATF_TEST_CASE(config_empty);
+ATF_TEST_CASE_HEAD(config_empty)
+{
+    set_md_var("descr", "Helper test case for the t_config test program");
+}
+ATF_TEST_CASE_BODY(config_empty)
+{
+    ATF_REQUIRE_EQ(get_config_var("test"), "");
+}
+
+ATF_TEST_CASE(config_value);
+ATF_TEST_CASE_HEAD(config_value)
+{
+    set_md_var("descr", "Helper test case for the t_config test program");
+}
+ATF_TEST_CASE_BODY(config_value)
+{
+    ATF_REQUIRE_EQ(get_config_var("test"), "foo");
+}
+
+ATF_TEST_CASE(config_multi_value);
+ATF_TEST_CASE_HEAD(config_multi_value)
+{
+    set_md_var("descr", "Helper test case for the t_config test program");
+}
+ATF_TEST_CASE_BODY(config_multi_value)
+{
+    ATF_REQUIRE_EQ(get_config_var("test"), "foo bar");
+}
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_expect".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_pass_and_pass);
+ATF_TEST_CASE_BODY(expect_pass_and_pass)
+{
+    expect_pass();
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_pass_but_fail_requirement);
+ATF_TEST_CASE_BODY(expect_pass_but_fail_requirement)
+{
+    expect_pass();
+    fail("Some reason");
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_pass_but_fail_check);
+ATF_TEST_CASE_BODY(expect_pass_but_fail_check)
+{
+    expect_pass();
+    fail_nonfatal("Some reason");
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_fail_and_fail_requirement);
+ATF_TEST_CASE_BODY(expect_fail_and_fail_requirement)
+{
+    expect_fail("Fail reason");
+    fail("The failure");
+    expect_pass();
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_fail_and_fail_check);
+ATF_TEST_CASE_BODY(expect_fail_and_fail_check)
+{
+    expect_fail("Fail first");
+    fail_nonfatal("abc");
+    expect_pass();
+
+    expect_fail("And fail again");
+    fail_nonfatal("def");
+    expect_pass();
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_fail_but_pass);
+ATF_TEST_CASE_BODY(expect_fail_but_pass)
+{
+    expect_fail("Fail first");
+    fail_nonfatal("abc");
+    expect_pass();
+
+    expect_fail("Will not fail");
+    expect_pass();
+
+    expect_fail("And fail again");
+    fail_nonfatal("def");
+    expect_pass();
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_exit_any_and_exit);
+ATF_TEST_CASE_BODY(expect_exit_any_and_exit)
+{
+    expect_exit(-1, "Call will exit");
+    std::exit(EXIT_SUCCESS);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_exit_code_and_exit);
+ATF_TEST_CASE_BODY(expect_exit_code_and_exit)
+{
+    expect_exit(123, "Call will exit");
+    std::exit(123);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_exit_but_pass);
+ATF_TEST_CASE_BODY(expect_exit_but_pass)
+{
+    expect_exit(-1, "Call won't exit");
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_signal_any_and_signal);
+ATF_TEST_CASE_BODY(expect_signal_any_and_signal)
+{
+    expect_signal(-1, "Call will signal");
+    ::kill(getpid(), SIGKILL);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_signal_no_and_signal);
+ATF_TEST_CASE_BODY(expect_signal_no_and_signal)
+{
+    expect_signal(SIGHUP, "Call will signal");
+    ::kill(getpid(), SIGHUP);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_signal_but_pass);
+ATF_TEST_CASE_BODY(expect_signal_but_pass)
+{
+    expect_signal(-1, "Call won't signal");
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_death_and_exit);
+ATF_TEST_CASE_BODY(expect_death_and_exit)
+{
+    expect_death("Exit case");
+    std::exit(123);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_death_and_signal);
+ATF_TEST_CASE_BODY(expect_death_and_signal)
+{
+    expect_death("Signal case");
+    kill(getpid(), SIGKILL);
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(expect_death_but_pass);
+ATF_TEST_CASE_BODY(expect_death_but_pass)
+{
+    expect_death("Call won't die");
+}
+
+ATF_TEST_CASE(expect_timeout_and_hang);
+ATF_TEST_CASE_HEAD(expect_timeout_and_hang)
+{
+    set_md_var("timeout", "1");
+}
+ATF_TEST_CASE_BODY(expect_timeout_and_hang)
+{
+    expect_timeout("Will overrun");
+    ::sleep(5);
+}
+
+ATF_TEST_CASE(expect_timeout_but_pass);
+ATF_TEST_CASE_HEAD(expect_timeout_but_pass)
+{
+    set_md_var("timeout", "1");
+}
+ATF_TEST_CASE_BODY(expect_timeout_but_pass)
+{
+    expect_timeout("Will just exit");
+}
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_meta_data".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(metadata_no_descr);
+ATF_TEST_CASE_HEAD(metadata_no_descr)
+{
+}
+ATF_TEST_CASE_BODY(metadata_no_descr)
+{
+}
+
+ATF_TEST_CASE_WITHOUT_HEAD(metadata_no_head);
+ATF_TEST_CASE_BODY(metadata_no_head)
+{
+}
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_srcdir".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(srcdir_exists);
+ATF_TEST_CASE_HEAD(srcdir_exists)
+{
+    set_md_var("descr", "Helper test case for the t_srcdir test program");
+}
+ATF_TEST_CASE_BODY(srcdir_exists)
+{
+    if (!atf::fs::exists(atf::fs::path(get_config_var("srcdir")) /
+        "datafile"))
+        ATF_FAIL("Cannot find datafile");
+}
+
+// ------------------------------------------------------------------------
+// Helper tests for "t_result".
+// ------------------------------------------------------------------------
+
+ATF_TEST_CASE(result_pass);
+ATF_TEST_CASE_HEAD(result_pass) { }
+ATF_TEST_CASE_BODY(result_pass)
+{
+    std::cout << "msg\n";
+}
+
+ATF_TEST_CASE(result_fail);
+ATF_TEST_CASE_HEAD(result_fail) { }
+ATF_TEST_CASE_BODY(result_fail)
+{
+    std::cout << "msg\n";
+    ATF_FAIL("Failure reason");
+}
+
+ATF_TEST_CASE(result_skip);
+ATF_TEST_CASE_HEAD(result_skip) { }
+ATF_TEST_CASE_BODY(result_skip)
+{
+    std::cout << "msg\n";
+    ATF_SKIP("Skipped reason");
+}
+
+ATF_TEST_CASE(result_newlines_fail);
+ATF_TEST_CASE_HEAD(result_newlines_fail)
+{
+    set_md_var("descr", "Helper test case for the t_result test program");
+}
+ATF_TEST_CASE_BODY(result_newlines_fail)
+{
+    ATF_FAIL("First line\nSecond line");
+}
+
+ATF_TEST_CASE(result_newlines_skip);
+ATF_TEST_CASE_HEAD(result_newlines_skip)
+{
+    set_md_var("descr", "Helper test case for the t_result test program");
+}
+ATF_TEST_CASE_BODY(result_newlines_skip)
+{
+    ATF_SKIP("First line\nSecond line");
+}
+
+ATF_TEST_CASE(result_exception);
+ATF_TEST_CASE_HEAD(result_exception) { }
+ATF_TEST_CASE_BODY(result_exception)
+{
+    throw std::runtime_error("This is unhandled");
+}
+
+// ------------------------------------------------------------------------
+// Main.
+// ------------------------------------------------------------------------
+
+ATF_INIT_TEST_CASES(tcs)
+{
+    // Add helper tests for t_config.
+    ATF_ADD_TEST_CASE(tcs, config_unset);
+    ATF_ADD_TEST_CASE(tcs, config_empty);
+    ATF_ADD_TEST_CASE(tcs, config_value);
+    ATF_ADD_TEST_CASE(tcs, config_multi_value);
+
+    // Add helper tests for t_expect.
+    ATF_ADD_TEST_CASE(tcs, expect_pass_and_pass);
+    ATF_ADD_TEST_CASE(tcs, expect_pass_but_fail_requirement);
+    ATF_ADD_TEST_CASE(tcs, expect_pass_but_fail_check);
+    ATF_ADD_TEST_CASE(tcs, expect_fail_and_fail_requirement);
+    ATF_ADD_TEST_CASE(tcs, expect_fail_and_fail_check);
+    ATF_ADD_TEST_CASE(tcs, expect_fail_but_pass);
+    ATF_ADD_TEST_CASE(tcs, expect_exit_any_and_exit);
+    ATF_ADD_TEST_CASE(tcs, expect_exit_code_and_exit);
+    ATF_ADD_TEST_CASE(tcs, expect_exit_but_pass);
+    ATF_ADD_TEST_CASE(tcs, expect_signal_any_and_signal);
+    ATF_ADD_TEST_CASE(tcs, expect_signal_no_and_signal);
+    ATF_ADD_TEST_CASE(tcs, expect_signal_but_pass);
+    ATF_ADD_TEST_CASE(tcs, expect_death_and_exit);
+    ATF_ADD_TEST_CASE(tcs, expect_death_and_signal);
+    ATF_ADD_TEST_CASE(tcs, expect_death_but_pass);
+    ATF_ADD_TEST_CASE(tcs, expect_timeout_and_hang);
+    ATF_ADD_TEST_CASE(tcs, expect_timeout_but_pass);
+
+    // Add helper tests for t_meta_data.
+    ATF_ADD_TEST_CASE(tcs, metadata_no_descr);
+    ATF_ADD_TEST_CASE(tcs, metadata_no_head);
+
+    // Add helper tests for t_srcdir.
+    ATF_ADD_TEST_CASE(tcs, srcdir_exists);
+
+    // Add helper tests for t_result.
+    ATF_ADD_TEST_CASE(tcs, result_pass);
+    ATF_ADD_TEST_CASE(tcs, result_fail);
+    ATF_ADD_TEST_CASE(tcs, result_skip);
+    ATF_ADD_TEST_CASE(tcs, result_newlines_fail);
+    ATF_ADD_TEST_CASE(tcs, result_newlines_skip);
+    ATF_ADD_TEST_CASE(tcs, result_exception);
+}

Added: vendor/atf/dist/test-programs/expect_test.sh
===================================================================
--- vendor/atf/dist/test-programs/expect_test.sh	                        (rev 0)
+++ vendor/atf/dist/test-programs/expect_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,151 @@
+# 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.
+
+check_result() {
+    file="${1}"; shift
+
+    atf_check -s eq:0 -o match:"${*}" -e empty cat "${file}"
+    rm "${file}"
+}
+
+atf_test_case expect_pass
+expect_pass_body() {
+    for h in $(get_helpers); do
+        atf_check -s eq:0 -e ignore "${h}" -r result expect_pass_and_pass
+        check_result result "passed"
+
+        atf_check -s eq:1 -e ignore "${h}" -r result \
+            expect_pass_but_fail_requirement
+        check_result result "failed: Some reason"
+
+        # atf-sh does not support non-fatal failures yet; skip checks for
+        # such conditions.
+        case "${h}" in *sh_helpers*) continue ;; esac
+
+        atf_check -s eq:1 -o empty -e match:"Some reason" \
+            "${h}" -r result expect_pass_but_fail_check
+        check_result result "failed: 1 checks failed"
+    done
+}
+
+atf_test_case expect_fail
+expect_fail_body() {
+    for h in $(get_helpers c_helpers cpp_helpers); do
+        atf_check -s eq:0 "${h}" -r result expect_fail_and_fail_requirement
+        check_result result "expected_failure: Fail reason: The failure"
+
+        atf_check -s eq:1 -e match:"Expected check failure: Fail first: abc" \
+            -e not-match:"And fail again" "${h}" -r result expect_fail_but_pass
+        check_result result "failed: .*expecting a failure"
+
+        # atf-sh does not support non-fatal failures yet; skip checks for
+        # such conditions.
+        case "${h}" in *sh_helpers*) continue ;; esac
+
+        atf_check -s eq:0 -e match:"Expected check failure: Fail first: abc" \
+            -e match:"Expected check failure: And fail again: def" \
+            "${h}" -r result expect_fail_and_fail_check
+        check_result result "expected_failure: And fail again: 2 checks" \
+            "failed as expected"
+    done
+
+    # atf-sh does not support non-fatal failures yet; skip checks for
+    # such conditions.
+    for h in $(get_helpers sh_helpers); do
+        atf_check -s eq:0 -e ignore "${h}" -r result \
+            expect_fail_and_fail_requirement
+        check_result result "expected_failure: Fail reason: The failure"
+
+        atf_check -s eq:1 -e ignore "${h}" -r result expect_fail_but_pass
+        check_result result "failed: .*expecting a failure"
+    done
+}
+
+atf_test_case expect_exit
+expect_exit_body() {
+    for h in $(get_helpers); do
+        atf_check -s eq:0 -e ignore "${h}" -r result expect_exit_any_and_exit
+        check_result result "expected_exit: Call will exit"
+
+        atf_check -s eq:123 -e ignore "${h}" -r result expect_exit_code_and_exit
+        check_result result "expected_exit\(123\): Call will exit"
+
+        atf_check -s eq:1 -e ignore "${h}" -r result expect_exit_but_pass
+        check_result result "failed: .*expected to exit"
+    done
+}
+
+atf_test_case expect_signal
+expect_signal_body() {
+    for h in $(get_helpers); do
+        atf_check -s signal:9 -e ignore "${h}" -r result \
+            expect_signal_any_and_signal
+        check_result result "expected_signal: Call will signal"
+
+        atf_check -s signal:hup -e ignore "${h}" -r result \
+            expect_signal_no_and_signal
+        check_result result "expected_signal\(1\): Call will signal"
+
+        atf_check -s eq:1 -e ignore "${h}" -r result \
+            expect_signal_but_pass
+        check_result result "failed: .*termination signal"
+    done
+}
+
+atf_test_case expect_death
+expect_death_body() {
+    for h in $(get_helpers); do
+        atf_check -s eq:123 -e ignore "${h}" -r result expect_death_and_exit
+        check_result result "expected_death: Exit case"
+
+        atf_check -s signal:kill -e ignore "${h}" -r result \
+            expect_death_and_signal
+        check_result result "expected_death: Signal case"
+
+        atf_check -s eq:1 -e ignore "${h}" -r result expect_death_but_pass
+        check_result result "failed: .*terminate abruptly"
+    done
+}
+
+atf_test_case expect_timeout
+expect_timeout_body() {
+    for h in $(get_helpers); do
+        atf_check -s eq:1 -e ignore "${h}" -r result expect_timeout_but_pass
+        check_result result "failed: Test case was expected to hang but it" \
+            "continued execution"
+    done
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case expect_pass
+    atf_add_test_case expect_fail
+    atf_add_test_case expect_exit
+    atf_add_test_case expect_signal
+    atf_add_test_case expect_death
+    atf_add_test_case expect_timeout
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/test-programs/meta_data_test.sh
===================================================================
--- vendor/atf/dist/test-programs/meta_data_test.sh	                        (rev 0)
+++ vendor/atf/dist/test-programs/meta_data_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,60 @@
+# Copyright (c) 2010 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.
+
+atf_test_case no_descr
+no_descr_head()
+{
+    atf_set "descr" "Tests that the description may not be present"
+}
+no_descr_body()
+{
+    for h in $(get_helpers); do
+        atf_check -s eq:0 -o ignore -e ignore ${h} -s $(atf_get_srcdir) -l
+        atf_check -s eq:0 -o match:passed -e ignore ${h} -s $(atf_get_srcdir) \
+            metadata_no_descr
+    done
+}
+
+atf_test_case no_head
+no_head_head()
+{
+    atf_set "descr" "Tests that the head may not be present"
+}
+no_head_body()
+{
+    for h in $(get_helpers); do
+        atf_check -s eq:0 -o ignore -e ignore ${h} -s $(atf_get_srcdir) -l
+        atf_check -s eq:0 -o match:passed -e ignore ${h} -s $(atf_get_srcdir) \
+            metadata_no_head
+    done
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case no_descr
+    atf_add_test_case no_head
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/test-programs/result_test.sh
===================================================================
--- vendor/atf/dist/test-programs/result_test.sh	                        (rev 0)
+++ vendor/atf/dist/test-programs/result_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,135 @@
+# 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.
+
+atf_test_case runtime_warnings
+runtime_warnings_head()
+{
+    # The fact that this test case is in this test program is an abuse.
+    atf_set "descr" "Tests that the test case prints a warning because" \
+                    "it is being run outside of a runtime engine"
+}
+runtime_warnings_body()
+{
+    unset __RUNNING_INSIDE_ATF_RUN
+    srcdir="$(atf_get_srcdir)"
+    for h in $(get_helpers); do
+        atf_check -s eq:0 -o match:"passed" -e match:"WARNING.*kyua" \
+            "${h}" -s "${srcdir}" result_pass
+    done
+}
+
+atf_test_case result_on_stdout
+result_on_stdout_head()
+{
+    atf_set "descr" "Tests that the test case result is printed on stdout" \
+                    "by default"
+}
+result_on_stdout_body()
+{
+    srcdir="$(atf_get_srcdir)"
+    for h in $(get_helpers); do
+        atf_check -s eq:0 -o match:"passed" -o match:"msg" \
+            -e ignore "${h}" -s "${srcdir}" result_pass
+        atf_check -s eq:1 -o match:"failed: Failure reason" -o match:"msg" \
+            -e ignore "${h}" -s "${srcdir}" result_fail
+        atf_check -s eq:0 -o match:"skipped: Skipped reason" -o match:"msg" \
+            -e ignore "${h}" -s "${srcdir}" result_skip
+    done
+}
+
+atf_test_case result_to_file
+result_to_file_head()
+{
+    atf_set "descr" "Tests that the test case result is sent to a file if -r" \
+                    "is used"
+}
+result_to_file_body()
+{
+    srcdir="$(atf_get_srcdir)"
+    for h in $(get_helpers); do
+        atf_check -s eq:0 -o inline:"msg\n" -e ignore "${h}" -s "${srcdir}" \
+            -r resfile result_pass
+        atf_check -o inline:"passed\n" cat resfile
+
+        atf_check -s eq:1 -o inline:"msg\n" -e ignore "${h}" -s "${srcdir}" \
+            -r resfile result_fail
+        atf_check -o inline:"failed: Failure reason\n" cat resfile
+
+        atf_check -s eq:0 -o inline:"msg\n" -e ignore "${h}" -s "${srcdir}" \
+            -r resfile result_skip
+        atf_check -o inline:"skipped: Skipped reason\n" cat resfile
+    done
+}
+
+atf_test_case result_to_file_fail
+result_to_file_fail_head()
+{
+    atf_set "descr" "Tests controlled failure if the test program fails to" \
+        "create the results file"
+    atf_set "require.user" "unprivileged"
+}
+result_to_file_fail_body()
+{
+    mkdir dir
+    chmod 444 dir
+
+    srcdir="$(atf_get_srcdir)"
+
+    for h in $(get_helpers c_helpers cpp_helpers); do
+        atf_check -s signal -o ignore \
+            -e match:"FATAL ERROR: Cannot create.*'dir/resfile'" \
+            "${h}" -s "${srcdir}" -r dir/resfile result_pass
+    done
+
+    for h in $(get_helpers sh_helpers); do
+        atf_check -s exit -o ignore \
+            -e match:"ERROR: Cannot create.*'dir/resfile'" \
+            "${h}" -s "${srcdir}" -r dir/resfile result_pass
+    done
+}
+
+atf_test_case result_exception
+result_exception_head()
+{
+    atf_set "descr" "Tests that an unhandled exception is correctly captured"
+}
+result_exception_body()
+{
+    for h in $(get_helpers cpp_helpers); do
+        atf_check -s signal -o not-match:'failed: .*This is unhandled' \
+            -e ignore "${h}" -s "${srcdir}" result_exception
+    done
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case runtime_warnings
+    atf_add_test_case result_on_stdout
+    atf_add_test_case result_to_file
+    atf_add_test_case result_to_file_fail
+    atf_add_test_case result_exception
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/test-programs/sh_helpers.sh
===================================================================
--- vendor/atf/dist/test-programs/sh_helpers.sh	                        (rev 0)
+++ vendor/atf/dist/test-programs/sh_helpers.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,390 @@
+# 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.
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_cleanup".
+# -------------------------------------------------------------------------
+
+atf_test_case cleanup_pass cleanup
+cleanup_pass_head()
+{
+    atf_set "descr" "Helper test case for the t_cleanup test program"
+}
+cleanup_pass_body()
+{
+    touch $(atf_config_get tmpfile)
+}
+cleanup_pass_cleanup()
+{
+    if [ $(atf_config_get cleanup no) = yes ]; then
+        rm $(atf_config_get tmpfile)
+    fi
+}
+
+atf_test_case cleanup_fail cleanup
+cleanup_fail_head()
+{
+    atf_set "descr" "Helper test case for the t_cleanup test program"
+}
+cleanup_fail_body()
+{
+    touch $(atf_config_get tmpfile)
+    atf_fail "On purpose"
+}
+cleanup_fail_cleanup()
+{
+    if [ $(atf_config_get cleanup no) = yes ]; then
+        rm $(atf_config_get tmpfile)
+    fi
+}
+
+atf_test_case cleanup_skip cleanup
+cleanup_skip_head()
+{
+    atf_set "descr" "Helper test case for the t_cleanup test program"
+}
+cleanup_skip_body()
+{
+    touch $(atf_config_get tmpfile)
+    atf_skip "On purpose"
+}
+cleanup_skip_cleanup()
+{
+    if [ $(atf_config_get cleanup no) = yes ]; then
+        rm $(atf_config_get tmpfile)
+    fi
+}
+
+atf_test_case cleanup_curdir cleanup
+cleanup_curdir_head()
+{
+    atf_set "descr" "Helper test case for the t_cleanup test program"
+}
+cleanup_curdir_body()
+{
+    echo 1234 >oldvalue
+}
+cleanup_curdir_cleanup()
+{
+    test -f oldvalue && echo "Old value: $(cat oldvalue)"
+}
+
+atf_test_case cleanup_sigterm cleanup
+cleanup_sigterm_head()
+{
+    atf_set "descr" "Helper test case for the t_cleanup test program"
+}
+cleanup_sigterm_body()
+{
+    touch $(atf_config_get tmpfile)
+    kill $$
+    touch $(atf_config_get tmpfile).no
+}
+cleanup_sigterm_cleanup()
+{
+    rm $(atf_config_get tmpfile)
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_config".
+# -------------------------------------------------------------------------
+
+atf_test_case config_unset
+config_unset_head()
+{
+    atf_set "descr" "Helper test case for the t_config test program"
+}
+config_unset_body()
+{
+    if atf_config_has 'test'; then
+        atf_fail "Test variable already defined"
+    fi
+}
+
+atf_test_case config_empty
+config_empty_head()
+{
+    atf_set "descr" "Helper test case for the t_config test program"
+}
+config_empty_body()
+{
+    atf_check_equal "$(atf_config_get 'test')" ""
+}
+
+atf_test_case config_value
+config_value_head()
+{
+    atf_set "descr" "Helper test case for the t_config test program"
+}
+config_value_body()
+{
+    atf_check_equal "$(atf_config_get 'test')" "foo"
+}
+
+atf_test_case config_multi_value
+config_multi_value_head()
+{
+    atf_set "descr" "Helper test case for the t_config test program"
+}
+config_multi_value_body()
+{
+    atf_check_equal "$(atf_config_get 'test')" "foo bar"
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_expect".
+# -------------------------------------------------------------------------
+
+atf_test_case expect_pass_and_pass
+expect_pass_and_pass_body()
+{
+    atf_expect_pass
+}
+
+atf_test_case expect_pass_but_fail_requirement
+expect_pass_but_fail_requirement_body()
+{
+    atf_expect_pass
+    atf_fail "Some reason"
+}
+
+atf_test_case expect_pass_but_fail_check
+expect_pass_but_fail_check_body()
+{
+    atf_fail "Non-fatal failures not implemented"
+}
+
+atf_test_case expect_fail_and_fail_requirement
+expect_fail_and_fail_requirement_body()
+{
+    atf_expect_fail "Fail reason"
+    atf_fail "The failure"
+    atf_expect_pass
+}
+
+atf_test_case expect_fail_and_fail_check
+expect_fail_and_fail_check_body()
+{
+    atf_fail "Non-fatal failures not implemented"
+}
+
+atf_test_case expect_fail_but_pass
+expect_fail_but_pass_body()
+{
+    atf_expect_fail "Fail first"
+    atf_expect_pass
+}
+
+atf_test_case expect_exit_any_and_exit
+expect_exit_any_and_exit_body()
+{
+    atf_expect_exit -1 "Call will exit"
+    exit 0
+}
+
+atf_test_case expect_exit_code_and_exit
+expect_exit_code_and_exit_body()
+{
+    atf_expect_exit 123 "Call will exit"
+    exit 123
+}
+
+atf_test_case expect_exit_but_pass
+expect_exit_but_pass_body()
+{
+    atf_expect_exit -1 "Call won't exit"
+}
+
+atf_test_case expect_signal_any_and_signal
+expect_signal_any_and_signal_body()
+{
+    atf_expect_signal -1 "Call will signal"
+    kill -9 $$
+}
+
+atf_test_case expect_signal_no_and_signal
+expect_signal_no_and_signal_body()
+{
+    atf_expect_signal 1 "Call will signal"
+    kill -1 $$
+}
+
+atf_test_case expect_signal_but_pass
+expect_signal_but_pass_body()
+{
+    atf_expect_signal -1 "Call won't signal"
+}
+
+atf_test_case expect_death_and_exit
+expect_death_and_exit_body()
+{
+    atf_expect_death "Exit case"
+    exit 123
+}
+
+atf_test_case expect_death_and_signal
+expect_death_and_signal_body()
+{
+    atf_expect_death "Signal case"
+    kill -9 $$
+}
+
+atf_test_case expect_death_but_pass
+expect_death_but_pass_body()
+{
+    atf_expect_death "Call won't die"
+}
+
+atf_test_case expect_timeout_and_hang
+expect_timeout_and_hang_head()
+{
+    atf_set "timeout" "1"
+}
+expect_timeout_and_hang_body()
+{
+    atf_expect_timeout "Will overrun"
+    sleep 5
+}
+
+atf_test_case expect_timeout_but_pass
+expect_timeout_but_pass_head()
+{
+    atf_set "timeout" "1"
+}
+expect_timeout_but_pass_body()
+{
+    atf_expect_timeout "Will just exit"
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_meta_data".
+# -------------------------------------------------------------------------
+
+atf_test_case metadata_no_descr
+metadata_no_descr_head()
+{
+    :
+}
+metadata_no_descr_body()
+{
+    :
+}
+
+atf_test_case metadata_no_head
+metadata_no_head_body()
+{
+    :
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_srcdir".
+# -------------------------------------------------------------------------
+
+atf_test_case srcdir_exists
+srcdir_exists_head()
+{
+    atf_set "descr" "Helper test case for the t_srcdir test program"
+}
+srcdir_exists_body()
+{
+    [ -f "$(atf_get_srcdir)/datafile" ] || atf_fail "Cannot find datafile"
+}
+
+# -------------------------------------------------------------------------
+# Helper tests for "t_result".
+# -------------------------------------------------------------------------
+
+atf_test_case result_pass
+result_pass_body()
+{
+    echo "msg"
+}
+
+atf_test_case result_fail
+result_fail_body()
+{
+    echo "msg"
+    atf_fail "Failure reason"
+}
+
+atf_test_case result_skip
+result_skip_body()
+{
+    echo "msg"
+    atf_skip "Skipped reason"
+}
+
+# -------------------------------------------------------------------------
+# Main.
+# -------------------------------------------------------------------------
+
+atf_init_test_cases()
+{
+    # Add helper tests for t_cleanup.
+    atf_add_test_case cleanup_pass
+    atf_add_test_case cleanup_fail
+    atf_add_test_case cleanup_skip
+    atf_add_test_case cleanup_curdir
+    atf_add_test_case cleanup_sigterm
+
+    # Add helper tests for t_config.
+    atf_add_test_case config_unset
+    atf_add_test_case config_empty
+    atf_add_test_case config_value
+    atf_add_test_case config_multi_value
+
+    # Add helper tests for t_expect.
+    atf_add_test_case expect_pass_and_pass
+    atf_add_test_case expect_pass_but_fail_requirement
+    atf_add_test_case expect_pass_but_fail_check
+    atf_add_test_case expect_fail_and_fail_requirement
+    atf_add_test_case expect_fail_and_fail_check
+    atf_add_test_case expect_fail_but_pass
+    atf_add_test_case expect_exit_any_and_exit
+    atf_add_test_case expect_exit_code_and_exit
+    atf_add_test_case expect_exit_but_pass
+    atf_add_test_case expect_signal_any_and_signal
+    atf_add_test_case expect_signal_no_and_signal
+    atf_add_test_case expect_signal_but_pass
+    atf_add_test_case expect_death_and_exit
+    atf_add_test_case expect_death_and_signal
+    atf_add_test_case expect_death_but_pass
+    atf_add_test_case expect_timeout_and_hang
+    atf_add_test_case expect_timeout_but_pass
+
+    # Add helper tests for t_meta_data.
+    atf_add_test_case metadata_no_descr
+    atf_add_test_case metadata_no_head
+
+    # Add helper tests for t_srcdir.
+    atf_add_test_case srcdir_exists
+
+    # Add helper tests for t_result.
+    atf_add_test_case result_pass
+    atf_add_test_case result_fail
+    atf_add_test_case result_skip
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4

Added: vendor/atf/dist/test-programs/srcdir_test.sh
===================================================================
--- vendor/atf/dist/test-programs/srcdir_test.sh	                        (rev 0)
+++ vendor/atf/dist/test-programs/srcdir_test.sh	2018-06-27 00:27:29 UTC (rev 11143)
@@ -0,0 +1,145 @@
+# 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.
+
+create_files()
+{
+    mkdir tmp
+    touch tmp/datafile
+}
+
+atf_test_case default
+default_head()
+{
+    atf_set "descr" "Checks that the program can find its files if" \
+                    "executed from the same directory"
+}
+default_body()
+{
+    create_files
+
+    for hp in $(get_helpers); do
+        h=${hp##*/}
+        cp ${hp} tmp
+        atf_check -s eq:0 -o ignore -e ignore -x \
+                  "cd tmp && ./${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 libtool
+libtool_head()
+{
+    atf_set "descr" "Checks that the program can find its files if" \
+                    "executed from the source directory and if it" \
+                    "was built with libtool"
+}
+libtool_body()
+{
+    create_files
+    mkdir tmp/.libs
+
+    for hp in $(get_helpers c_helpers cpp_helpers); do
+        h=${hp##*/}
+        cp ${hp} tmp
+        cp ${hp} tmp/.libs
+        atf_check -s eq:0 -o ignore -e ignore -x \
+                  "cd tmp && ./.libs/${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
+
+    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
+sflag_head()
+{
+    atf_set "descr" "Checks that the program can find its files when" \
+                    "using the -s flag"
+}
+sflag_body()
+{
+    create_files
+
+    for hp in $(get_helpers); do
+        h=${hp##*/}
+        cp ${hp} tmp
+        atf_check -s eq:0 -o ignore -e ignore -x \
+                  "cd tmp && ./${h} -s $(pwd)/tmp \
+                   srcdir_exists"
+        atf_check -s eq:1 -o empty -e save:stderr "${hp}" -r res srcdir_exists
+        atf_check -s eq:0 -o ignore -e empty grep "Cannot find datafile" res
+        atf_check -s eq:0 -o ignore -e ignore \
+                  "${hp}" -s "$(pwd)"/tmp srcdir_exists
+    done
+}
+
+atf_test_case relative
+relative_head()
+{
+    atf_set "descr" "Checks that passing a relative path through -s" \
+                    "works"
+}
+relative_body()
+{
+    create_files
+
+    for hp in $(get_helpers); do
+        h=${hp##*/}
+        cp ${hp} tmp
+
+        for p in tmp tmp/. ./tmp; do
+            echo "Helper is: ${h}"
+            echo "Using source directory: ${p}"
+
+            atf_check -s eq:0 -o ignore -e ignore \
+                      "./tmp/${h}" -s "${p}" srcdir_exists
+            atf_check -s eq:1 -o empty -e save:stderr "${hp}" -r res \
+                srcdir_exists
+            atf_check -s eq:0 -o ignore -e empty grep "Cannot find datafile" res
+            atf_check -s eq:0 -o ignore -e ignore \
+                      "${hp}" -s "${p}" srcdir_exists
+        done
+    done
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case default
+    atf_add_test_case libtool
+    atf_add_test_case sflag
+    atf_add_test_case relative
+}
+
+# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4



More information about the Midnightbsd-cvs mailing list