summaryrefslogtreecommitdiffstats
path: root/contrib/netbsd-tests/lib
diff options
context:
space:
mode:
authorngie <ngie@FreeBSD.org>2014-12-31 20:13:31 +0000
committerngie <ngie@FreeBSD.org>2014-12-31 20:13:31 +0000
commitb429a2bfd1380c777b9d59e54e17886b3855073e (patch)
treef5eb9fb5c3b79a2f3a7cba500581d24f4676622d /contrib/netbsd-tests/lib
parent155ee9c2f7fcb97a502844e0ca346b9f919b8cb2 (diff)
downloadFreeBSD-src-b429a2bfd1380c777b9d59e54e17886b3855073e.zip
FreeBSD-src-b429a2bfd1380c777b9d59e54e17886b3855073e.tar.gz
MFC r272343,r272458,r272890,r272891,r272901,r272902,r272903,r272905,r272908,r272909,r272910,r272914,r272915,r272979,r272980,r273010,r273011,r273012,r273015,r273017,r273019,r273020,r273021,r273022,r273023,r273024,r273025,r273389,r273390,r273391,r273393,r273395,r273396,r273397,r273410,r273516,r273517,r273520,r273521,r273522,r273523,r273524,r273525,r273526,r273527,r273528,r273529,r273530,r273533,r273534,r273535,r273536,r273537,r273538,r273539,r273540,r273572,r273574,r273578,r273579,r273591,r273592,r273928,r273933,r273935,r273936,r273937,r273938,r273942,r273943,r273945,r273946,r273947,r273948,r273949,r273950,r273951,r273952,r274061,r274062,r274066,r274067,r274072,r274074,r274079,r274090,r274142,r274143,r274571,r274572,r274573,r274574,r274575,r274576,r274577,r274579,r274597,r274598,r274599,r274600,r274601,r274626,r275033,r276046,r276430:
r272343: r272458: Import the NetBSD test suite from ^/vendor/NetBSD/tests/09.30.2014_20.45 , minus the vendor Makefiles Provide directions for how to bootstrap the vendor sources in FREEBSD-upgrade MFC after 2 weeks Discussed with: rpaulo Sponsored by: EMC / Isilon Storage Division r272890: Only build/run hsearch_basic and hsearch_r_basic on NetBSD hdestroy1 is not present on FreeBSD Sponsored by: EMC / Isilon Storage Division r272891: Expect SIGSEGV in lib/libc/stdlib/t_getenv:setenv_basic See bin/189805 for more details In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r272901: Disable tests that don't pass on FreeBSD due to missing support in humanize_number(3). Bringing in additional revisions from NetBSD's humanize_number(3) will fix the tests Account for the fact that util.h on NetBSD is libutil.h on FreeBSD Submitted by: pho Sponsored by: EMC / Isilon Storage Division r272902: Add missing #include <sys/time.h> for gettimeofday Sponsored by: EMC / Isilon Storage Division r272903: FreeBSD returns ENOTTY instead of EBADF in ttyname_r; mark it as an expected failure PR: 191936 In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r272905: FreeBSD doesn't support strings greater than MAXHOSTNAMELEN-1 in {get,set}{domain,host}name. Adjust the tests to not exceed that value when testing out the code Add a positive and negative test for MAXHOSTNAMELEN-1 and MAXHOSTNAMELEN, respectively PR: 181127 In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r272908: Disable the invalid pointer test on FreeBSD FreeBSD segfaults on invalid pointers passed to getcwd because it throbs the address passed in in libc, whereas NetBSD just passes the information off to the syscall, which allows the kernel to return EFAULT on bad pointers. In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r272909: Handle getting/setting niceness/priority correctly on FreeBSD vs NetBSD This might be fallout from PR: 189821 Submitted by: pho Sponsored by: EMC / Isilon Storage Division r272910: SIGPWR does not exist on FreeBSD Sponsored by: EMC / Isilon Storage Division r272914: Skip over t_spawn_open_nonexistent_diag because it requires NetBSD specific additions to posix_spawn Sponsored by: EMC / Isilon Storage Division r272915: Port the testcase to FreeBSD - Make #include path to h_macros.h a non-relative path - __gl_stat_t is synonymous with struct stat on FreeBSD - FreeBSD doesn't have _DIRENT_RECLEN - Skip over glob_star on FreeBSD (testcase doesn't pass) In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r272979: Only #include <sys/tls.h> on NetBSD Sponsored by: EMC / Isilon Storage Division r272980: #include libutil.h for fparseln on FreeBSD Sponsored by: EMC / Isilon Storage Division r273010: Implement 64MB memory limit for test to ensure that it fails reliably in 600 seconds; it would previously fail inconsistently when run in some virtual machine configurations This patch might need to be reverted or revisited later (see the attached PR for more details) PR: 169302 Submitted by: pho Sponsored by: EMC / Isilon Storage Division r273011: Fix compilation errors with missing wide-type headers and fix compilation warnings with -Wformat In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r273012: - Add libutil #include for fparseln - Change ATF_REQUIRE_EQ_MSG to ATF_CHECK_EQ_MSG to gather all failing results possible (currently 12 with leftassoc) - Mark leftassoc "atf_tc_expect_fail" on FreeBSD (PR coming soon after further analysis is done on the code) In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r273015: Expect nice_err to fail on FreeBSD with unprivileged users PR: 189821 Sponsored by: EMC / Isilon Storage Division r273017: Add #include <stdio.h> for printf Sponsored by: EMC / Isilon Storage Division r273019: Do initial port of contrib/netbsd-tests/lib/libc/locale t_io: - Expect failures potentially related to implementation-specific knowledge of the zh_TW.Big5 locale [*] t_mbrtowc: - Handle unknown locales more gracefully (do not test if the locale doesn't exist) - Expect failure with mbrtowc_internal dealing with Japanese locales (potentially related to implementation detail knowledge of the ja_* locales) [*]. t_mbstowcs, t_mbtowc, t_wctomb: - Handle unknown locales more gracefully (do not test if the locale doesn't exist) t_wcstod: - Treat FreeBSD like NetBSD and Linux in the XXX: FIXME section [*] More investigation is required to determine the root cause of the failures Submitted by: pho Sponsored by: EMC / Isilon Storage Division r273020: memmem with NUL length "needle" (aka small) strings on FreeBSD/OSX returns NULL instead of the "haystack" value (aka big) Submitted by: pho Sponsored by: EMC / Isilon Storage Division r273021: Use 1 as a random seed, as recommended in srandom(3). Adjust the random values accordingly Submitted by: pho Sponsored by: EMC / Isilon Storage Division r273022: Add #include <stdio.h> to get sys_nerr definition Sponsored by: EMC / Isilon Storage Division r273023: __isnanl is automatically picked according to data type in <math.h>. There isn't a need for the explicit __isnanl test Sponsored by: EMC / Isilon Storage Division r273024: Only test the return value in mktime_negyear Testing for the errno is an optional requirement according to POSIX, and FreeBSD doesn't document that errno would be set on failure with mktime Submitted by: pho Sponsored by: EMC / Isilon Storage Division r273025: Change ATF_REQUIRE_MSG calls to ATF_CHECK_MSG to get as many errors as possible t_strptime:common.. - Expect the testcase body as a whole to fail. Multiple PRs will be filed to track the issues (there are 18 check failures) t_strptime:day.. - %EA and %OA seem to be case insensitive on FreeBSD r273389: Port lib/libc/gen/t_siginfo to FreeBSD - mcontext_t on FreeBSD doesn't have a __gregs field (it's split out on FreeBSD into separate fields). In order to avoid muddying the test code with MD code, the debugging trace info has not been implemented - FreeBSD does not implement the si_stime and si_utime fields in siginfo_t, so omit the debugging code that dumps the values - sys/inttypes.h doesn't exist on FreeBSD Sponsored by: EMC / Isilon Storage Division r273390: libutil.h is required for fparseln on FreeBSD Sponsored by: EMC / Isilon Storage Division r273391: Add missing #include for sys/stat.h for fchmod Sponsored by: EMC / Isilon Storage Division r273393: Port t_write to FreeBSD - Mark the signo variable for the signal handle __unused - Use limits.h instead of sys/syslimits.h (the latter does not exist on FreeBSD) Sponsored by: EMC / Isilon Storage Division r273395: Mark osi __unused so this compiles cleanly on FreeBSD Sponsored by: EMC / Isilon Storage Division r273396: unlink("/") fails with EISDIR instead of EBUSY on FreeBSD; test for that instead Sponsored by: EMC / Isilon Storage Division r273397: Port t_chroot to FreeBSD - Add missing #include sys/stat.h for mkdir(2) - Omit the fchroot(2) tests because the support is not present on FreeBSD Sponsored by: EMC / Isilon Storage Division r273410: Add sys/socket.h #include for bind(2), et al Sponsored by: EMC / Isilon Storage Division r273516: Add netinet/in.h for struct sockaddr_in Sponsored by: EMC / Isilon Storage Division r273517: Expect getgroups_err to fail on FreeBSD PR: 189941 Submitted by: pho Sponsored by: EMC / Isilon Storage Division r273520: Port t_pipe2.c to FreeBSD - Omit the pipe2_nosigpipe testcase on FreeBSD (FreeBSD doesn't have O_NOSIGPIPE). - Convert "fcntl(n, F_CLOSEM)" to "closefrom(n)". - Save and restore the resource limit on the number of files (RLIMIT_NOFILE). In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r273521: Convert "fcntl(n, F_CLOSEM)" to "closefrom(n)" Submitted by: pho Sponsored by: EMC / Isilon Storage Division r273522: - Mark unused parameters __unused in handler - Call sigqueue with getpid() instead of 0 -- the latter idiom appears to only be valid on NetBSD In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r273523: Add limits.h #include for LINE_MAX Sponsored by: EMC / Isilon Storage Division r273524: Add sys/socket.h #include for struct sockaddr_in Sponsored by: EMC / Isilon Storage Division r273525: Port t_mmap.c to FreeBSD - Add needed headers for the testcases - Omit mmap_block on non-NetBSD OSes - Use "security.bsd.map_at_zero" instead of "vm.user_va0_disable" Submitted by: pho Sponsored by: EMC / Isilon Storage Division r273526: Omit the pollts testcases on FreeBSD Sponsored by: EMC / Isilon Storage Division r273527: Omit all of the testcases as revoke(2) is only implemented on devfs(5) Submitted by: pho Sponsored by: EMC / Isilon Storage Division r273528: Mark signo __unused in handler(..) Sponsored by: EMC / Isilon Storage Division r273529: - Omit the poll testcases on FreeBSD (they require pollts) - Add necessary headers for the testcases Sponsored by: EMC / Isilon Storage Division r273530: Add limits.h #include for INT_MAX Sponsored by: EMC / Isilon Storage Division r273533: Use <atf_srcdir>/truncate_test.root_owned instead of /usr/bin/fpr as fpr does not exist on FreeBSD truncate_test.root_owned will be generated at build time and owned by root In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r273534: - Mark sig/signo __unused - Do not provide a relative path via #include "h_macros.h" Sponsored by: EMC / Isilon Storage Division r273535: - Omit setrlimit_nthr testcase on FreeBSD (requires lwp.h, et al) - Expect overflow with rlim_max at INT64_MAX, not UINT64_MAX (rlim_t is int64_t on FreeBSD) In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r273536: Add limits.h #include for SSIZE_MAX Sponsored by: EMC / Isilon Storage Division r273537: Add limits.h #include for SSIZE_MAX Sponsored by: EMC / Isilon Storage Division r273538: Fix a typo (__FreeBSD__ -> __NetBSD__ when omitting setrlimit_nthr) r273539: Mark signum __unused Sponsored by: EMC / Isilon Storage Division r273540: Omit the mprotect_exec testcase on FreeBSD Sponsored by: EMC / Isilon Storage Division r273572: - Ignore EINVAL check with mknod(path, S_IFCHR, -1) as the testcase is always executed on a non-devfs filesystem - Expect mknod(path, S_IFREG, 0) to fail on FreeBSD Submitted by: pho Sponsored by: EMC / Isilon Storage Division r273574: - Test for EINVAL requirement when passing an invalid flag in to msync(2) - Expect ENOMEM instead of EFAULT when msync'ing a previously munmap'ed region on FreeBSD Submitted by: pho Sponsored by: EMC / Isilon Storage Division r273578: - Add inttypes.h and stdint.h in lieu of int_limits.h from NetBSD - Use #include "h_macros.h" instead of relative path analog Sponsored by: EMC / Isilon Storage Division r273579: - Mark signo __unused in the signal handler function - Effectively #if 0 out some code that does not fail on FreeBSD In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r273591: Correct my previous commit: - getrusage_utime_back succeeds reliably on FreeBSD - getrusage_utime_zero passes/fails in a seemingly non-deterministic manner. Skip it for now (and fix it later) In the initial port of this testcase to FreeBSD, the results failed reliably in the same manner as it does on NetBSD Sponsored by: EMC / Isilon Storage Division r273592: - Add sys/types.h for the APIs in sys/sysctl.h - Poke at VM_MIN_ADDRESS in machine/vmparam.h because FreeBSD doesn't have a vm.minaddress sysctl analog - Expect ENOMEM instead of EAGAIN in mlock_limits - Provide mlock an mmap'ed page twice to simulate MAP_WIRED on NetBSD In collaboration with: pho Sponsored by: EMC / Isilon Storage Division r273928: Put mtree test files into a subdirectory. Kyua 0.11 points TMPDIR to the test's work directory, and atf_check creates auxiliary files in TMPDIR. This confuses a couple of mtree tests that were using the work directory's root to validate the contents of the directory. Fix the two affected tests by creating an auxiliary directory to use for the mtree tests. (Kyua should probably do this on its own; filed bug #133 upstream to take a look at this.) r273933: Don't prune duplicate services in the expected output from /etc/services on FreeBSD Submitted by: pho r273935: Port tests to FreeBSD/Linux Some of the testcases don't work outside of NetBSD, and the behavior of ether_aton_r differs between FreeBSD, Linux, and NetBSD, and the calls to the API need to be massaged for FreeBSD and Linux. Submitted by: pho r273936: Port lib/libc/net/h_dns_server to FreeBSD Submitted by: pho r273937: Port lib/libc/sys/t_dup to FreeBSD/Linux - The requirements differ between FreeBSD/Linux when dealing with oldd/newd being equal (both fail with EINVAL, not EBADF) - Add an EBADF testcase - Fix compilation issues on clang In collaboration with: pho r273938: getitimer on FreeBSD returns the last set time instead of the remaining time; test for that instead Submitted by: pho r273942: Skip :sethostname_basic because it messes up the test host's hostname Convert code from #if defined(__FreeBSD__) to #ifdef __FreeBSD__ r273943: Port t_kevent to FreeBSD Submitted by: pho r273945: Port t_mincore to FreeBSD Mark :mincore_resid as atf_tc_expect_fail on FreeBSD because of new bug discovered in running the tests (it succeeded from earlier on in the year to September/October on FreeBSD, at least) Submitted by: pho r273946: Port h_atexit to FreeBSD __cxa_atexit varies between FreeBSD and NetBSD, and thus we must use pointers instead of static fields in the BSS. More extensive discussion is included in the source code In collaboration with: kib Submitted by: pho r273947: Expect :snprintf_posarg_error to blow up with a SIGSEGV on !NetBSD OSes r273948: Disable testcases 12 and 15-22 on FreeBSD Submitted by: pho r273949: Add new atf_tc_expect_fail to fflush_err; this is a new (within the past couple months) bug r273950: Skip :fopen_regular on !NetBSD because it's a NetBSD specific test Submitted by: pho r273951: Expect :sscanf_whitespace to fail on !NetBSD OSes Submitted by: pho r273952: Port h_hash and t_sha2 to FreeBSD t_sha2 contains dirty copy-paste hacks that need to be fixed with the openssh OpenBSD compat layer Submitted by: pho r274061: Port t_db.sh to FreeBSD - The blocksize on FreeBSD is 32kB, not 64kB - Add some detection for MK_DICT == no; /nonexistent is echoed along with atf_skip to ensure that the test will fail if dict(..) is called in the non-final stage of the pipeline Submitted by: pho r274062: inet_network on FreeBSD returns NULL when provided "0x" to inet_network Submitted by: pho r274066: Port lib/libc/ssp to FreeBSD In most cases, the buffers and data were resized, but when dealing with the helpers, some of the code was adjusted to fail more reliably Submitted by: pho r274067: rpc_control on FreeBSD is a public-ish API (not prefixed with __), not private like NetBSD Submitted by: pho r274072: Finish off lib/libc/stdlib/t_strtod.c port by checking for "y" twice on FreeBSD, and always assume long long double exists on FreeBSD Submitted by: pho r274074: Add Makefile snippet to ease porting NetBSD testcases to FreeBSD from contrib/netbsd-tests This Makefile snippet handles polluting testcases with -lnetbsd, specific headers for ATF version differences, and does necessary rewriting for the testcases to match the format discussed on the TestSuite wiki page (t_<foo> -> <foo>_test) One must define SRCTOP (inspired by projects/bmake), OBJTOP, and TESTSRC (e.g. contrib/netbsd-tests/lib/libc/gen) to use the Makefile snippet Test programs are specific either via NETBSD_ATF_TESTS_C or NETBSD_ATF_TESTS_SH C++ analogs aren't currently implemented. The imported testcases will be cleaned up to use this Makefile snippet pseudo "API". r274079: Import proper fix for misc/49356 (/usr/include/atf-c/config.h) after atf-c/config.h was removed from the build Pointyhat to: me (again, for not running make delete-old after running test builds) r274090: Fix the Jenkins test run by skipping the negative testcases earlier The problem is that lib.libc.locale.t_io:bad_big5_wprintf was printing out illegal Unicode characters, which causes XML parsers to bail immediately, e.g. % kyua report-junit > ~/report.junit % python2 -c 'import xml.dom.minidom as md; md.parse("/home/ngie/report.junit")' Traceback (most recent call last): File "<string>", line 1, in <module> File "/usr/local/lib/python2.7/xml/dom/minidom.py", line 1918, in parse return expatbuilder.parse(file) File "/usr/local/lib/python2.7/xml/dom/expatbuilder.py", line 924, in parse result = builder.parseFile(fp) File "/usr/local/lib/python2.7/xml/dom/expatbuilder.py", line 207, in parseFile parser.Parse(buffer, 0) xml.parsers.expat.ExpatError: not well-formed (invalid token): line 27137, column 13 r274142: Remove expected failure from lib.libc.sys.t_mincore:mincore_resid The failure was added based on observation seen on 11.0-CURRENT @ r273153, not based on internal testing at EMC/Isilon PR: 194829 Tested with the following configuration: - amd64/i386 - 11.0-CURRENT @ r273153 - 100 times in a tight loop as root with the following commands... -- kyua test lib/libc -- kyua test lib/libc/sys -- kyua test lib/libc/sys/mincore_test r274143: Expect lib.libc.sys.getcontext_test.setcontext_link to fail on amd64; add additional debugging to make the underlying problem more visible Calling setcontext(2) on amd64 as shown in the test program is failing on amd64, not i386, with a return code of -1 and an errno of EINVAL Further investigation is being done in the PR to determine the root cause for the failure PR: 194828 Tested with the following configuration: - amd64/i386 - 11.0-CURRENT @ r273153 - 100 times in a tight loop as root with the following commands... -- kyua test lib/libc -- kyua test lib/libc/sys -- kyua test lib/libc/sys/getcontext_test r274571: Use _exit instead of exit so the file descriptors aren't flushed twice in the child processes Submitted by: pho r274572: Only expect timeouts on powerpc with NetBSD Submitted by: pho r274573: Expect :pthread_detach to fail with EINVAL instead of ESRCH on FreeBSD PR: 191906 In collaboration with: pho r274574: Add pthread_np.h #include and initialize the pthread attribute on FreeBSD Submitted by: pho r274575: #ifdef out a printf on !NetBSD that causes the testcase to fail when comparing the output from the helper program Submitted by: pho r274576: Port helper program to FreeBSD, similar to ../../lib/libc/stdlib/h_atexit.c Submitted by: pho In collaboration with: kib r274577: Add missing sys/time.h #include for timespecsub macro in lib/libnetbsd/sys/time.h r274579: Call sem_unlink on semaphores before attempting to create them Due to the lack of uniqueness in the semaphore name, and the fact that the tests don't have cleanup routines, an interrupted test can leave a semaphore "laying around", causing all subsequent attempts to run the test to fail I will file a NetBSD PR for this issue soon r274597: Skip the long-double epsilon checks on FreeBSD/i386 Sponsored by: EMC / Isilon Storage Division r274598: Reset errno to 0 before running scalbn to be sure that the tested errno is valid Sponsored by: EMC / Isilon Storage Division r274599: Alias isinff to isinf on FreeBSD isinf on FreeBSD automatically picks the appropriate type per math.h Sponsored by: EMC / Isilon Storage Division r274600: - Expect exp2_powers to fail on FreeBSD/i386 - Expect exp2_values to fail on FreeBSD due to the small epsilon Sponsored by: EMC / Isilon Storage Division r274601: - Skip over the testcases that call cbrtl on platforms where LDBL_PREC == 53 (arm, mips, powerpc). This fixes the build on these platforms, based on some ad hoc tinderbox runs I did a while ago - Skip cast the arguments to powl as long double so powl properly interprets those arugments at compile-time when picking the type Sponsored by: EMC / Isilon Storage Division r274626: Mechanically replace #if defined(__FreeBSD__) and #if defined(__NetBSD__) with their #ifdef equivalents for everything changed in contrib/netbsd-tests. There are some items from the vendor tree that use #if defined(__FreeBSD__) or #if defined(__NetBSD__) which are being left alone Requested by: bde, rpaulo Sponsored by: EMC / Isilon Storage Division r275033: Only pass 6 arguments to the 'run' function on amd64. amd64's makecontext on FreeBSD only supports a maximum of 6 arguments. This fixes the setcontext_link test on amd64. PR: 194828 r276046: Add __FreeBSD_version guards around hsearch_r to ease MFCing the code to stable/10 It was added when __FreeBSD_version was ~1100027 r276430: Expect access_test:access_inval to fail before __FreeBSD_version == 1100033 This will allow me to MFC the test, as jilles@ requested that I don't MFC the access(2) KBI change to 10-STABLE in r271655
Diffstat (limited to 'contrib/netbsd-tests/lib')
-rw-r--r--contrib/netbsd-tests/lib/csu/arch/alpha/h_initfini_align.S16
-rw-r--r--contrib/netbsd-tests/lib/csu/arch/arm/h_initfini_align.S20
-rw-r--r--contrib/netbsd-tests/lib/csu/arch/hppa/h_initfini_align.S12
-rw-r--r--contrib/netbsd-tests/lib/csu/arch/i386/h_initfini_align.S12
-rw-r--r--contrib/netbsd-tests/lib/csu/arch/ia64/h_initfini_align.S37
-rw-r--r--contrib/netbsd-tests/lib/csu/arch/mips/h_initfini_align.S19
-rw-r--r--contrib/netbsd-tests/lib/csu/arch/powerpc/h_initfini_align.S17
-rw-r--r--contrib/netbsd-tests/lib/csu/arch/sparc/h_initfini_align.S10
-rw-r--r--contrib/netbsd-tests/lib/csu/arch/sparc64/h_initfini_align.S11
-rw-r--r--contrib/netbsd-tests/lib/csu/arch/vax/h_initfini_align.S17
-rw-r--r--contrib/netbsd-tests/lib/csu/arch/x86_64/h_initfini_align.S13
-rw-r--r--contrib/netbsd-tests/lib/csu/dso/h_initfini3_dso.cxx37
-rw-r--r--contrib/netbsd-tests/lib/csu/h_initfini1.cxx9
-rw-r--r--contrib/netbsd-tests/lib/csu/h_initfini3.cxx22
-rw-r--r--contrib/netbsd-tests/lib/csu/h_initfini_common.cxx37
-rwxr-xr-xcontrib/netbsd-tests/lib/csu/t_crt0.sh104
-rw-r--r--contrib/netbsd-tests/lib/libbluetooth/t_bluetooth.c87
-rw-r--r--contrib/netbsd-tests/lib/libbluetooth/t_sdp_data.c136
-rw-r--r--contrib/netbsd-tests/lib/libbluetooth/t_sdp_get.c643
-rw-r--r--contrib/netbsd-tests/lib/libbluetooth/t_sdp_match.c87
-rw-r--r--contrib/netbsd-tests/lib/libbluetooth/t_sdp_put.c875
-rw-r--r--contrib/netbsd-tests/lib/libbluetooth/t_sdp_set.c359
-rw-r--r--contrib/netbsd-tests/lib/libbpfjit/t_bpfjit.c3975
-rw-r--r--contrib/netbsd-tests/lib/libbpfjit/t_cop.c657
-rw-r--r--contrib/netbsd-tests/lib/libbpfjit/t_extmem.c483
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S10
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/arm/return_one.S11
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c65
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/i386/return_one.S10
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/mips/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S12
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c52
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S11
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S11
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/vax/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c50
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S10
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_faccessat.c185
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c197
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_fchownat.c247
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_fexecve.c94
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_fstatat.c196
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_linkat.c217
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c120
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c124
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_mknodat.c150
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_o_search.c278
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_openat.c165
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c157
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_renameat.c152
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c150
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c176
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_utimensat.c212
-rw-r--r--contrib/netbsd-tests/lib/libc/common/exec_prot.h61
-rw-r--r--contrib/netbsd-tests/lib/libc/db/README66
-rw-r--r--contrib/netbsd-tests/lib/libc/db/h_db.c731
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/db/t_db.sh940
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c58
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/isqemu.h63
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c104
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh3
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c50
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c90
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c392
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c184
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c173
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_alarm.c150
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_assert.c132
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_basedirname.c200
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_closefrom.c173
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_cpuset.c114
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_dir.c165
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c135
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c117
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c167
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c206
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c354
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c163
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_ftok.c107
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_getcwd.c153
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_getgrent.c181
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_glob.c287
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c318
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_isnan.c66
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_nice.c221
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_pause.c114
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_raise.c194
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_randomid.c93
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_realpath.c152
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c148
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_sethostname.c150
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_siginfo.c505
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_sleep.c350
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_syslog.c56
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_time.c117
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_ttyname.c191
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_vis.c155
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/data/md5test-in7
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/data/md5test-out7
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/data/sha1test-in2
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/data/sha1test-out2
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out1
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/h_hash.c187
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/hash/t_hash.sh67
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/t_sha2.c257
-rw-r--r--contrib/netbsd-tests/lib/libc/inet/t_inet_network.c174
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_io.c193
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c277
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c98
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c209
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c157
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c58
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c62
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c60
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_wcstod.c460
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_wctomb.c212
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/gen_ether_subr25
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/README7
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp36
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp42
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c186
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp38
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp56
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp14
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp16
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp4
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp13
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp15
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp6
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp8
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh198
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp2
-rw-r--r--contrib/netbsd-tests/lib/libc/net/h_dns_server.c415
-rw-r--r--contrib/netbsd-tests/lib/libc/net/h_hostent.c195
-rw-r--r--contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c107
-rw-r--r--contrib/netbsd-tests/lib/libc/net/h_protoent.c97
-rw-r--r--contrib/netbsd-tests/lib/libc/net/h_servent.c100
-rw-r--r--contrib/netbsd-tests/lib/libc/net/hosts11
-rw-r--r--contrib/netbsd-tests/lib/libc/net/resolv.conf1
-rw-r--r--contrib/netbsd-tests/lib/libc/net/t_ether_aton.c137
-rw-r--r--contrib/netbsd-tests/lib/libc/net/t_getprotoent.c233
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/t_hostent.sh240
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh51
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/t_protoent.sh91
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/t_servent.sh111
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/README33
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/anchor.in33
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/README8
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat216
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat62
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat30
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat16
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat73
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat140
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat16
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/backref.in21
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/basic.in5
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/bracket.in55
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/c_comments.in17
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/complex.in23
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/error.in30
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/meta.in21
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/nospec.in7
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/paren.in19
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/regress.in9
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in45
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in21
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in10
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/startend.in9
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/subexp.in57
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/subtle.in21
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/word_bound.in13
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/zero.in7
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/debug.c278
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/main.c523
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/split.c344
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/t_exhaust.c224
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/regex/t_regex.sh73
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/t_regex_att.c639
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/test_regex.h44
-rw-r--r--contrib/netbsd-tests/lib/libc/rpc/h_testbits.x21
-rw-r--r--contrib/netbsd-tests/lib/libc/rpc/t_rpc.c161
-rw-r--r--contrib/netbsd-tests/lib/libc/rpc/t_xdr.c129
-rw-r--r--contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c196
-rw-r--r--contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c218
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_fgets.c46
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c47
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_gets.c43
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c48
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_memmove.c48
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_memset.c49
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_raw.c57
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_read.c65
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_readlink.c66
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c51
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c43
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c49
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c56
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_strcat.c46
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c45
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_strncat.c48
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c47
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c57
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c55
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/ssp/t_ssp.sh459
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c93
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_fflush.c175
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c1181
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_fopen.c444
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_fputc.c194
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c54
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_popen.c135
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_printf.c204
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_scanf.c85
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c212
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c130
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c242
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_abs.c154
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh54
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_atoi.c121
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_div.c98
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_exit.c186
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c211
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c250
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh123
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c411
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c95
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c88
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_random.c82
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c342
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c234
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_system.c83
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_bm.c102
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_memchr.c194
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_memcpy.c162
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_memmem.c105
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_memset.c207
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_popcount.c198
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strcat.c153
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strchr.c292
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strcmp.c136
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strcpy.c124
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strcspn.c58
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strerror.c139
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_stresep.c72
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strlen.c199
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strpbrk.c62
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strrchr.c257
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strspn.c60
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_swab.c95
-rw-r--r--contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c168
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_access.c219
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_chroot.c321
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c220
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_clone.c252
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_connect.c103
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_dup.c405
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_fsync.c120
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getcontext.c139
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getgroups.c174
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getitimer.c216
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getlogin.c237
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getpid.c134
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getrusage.c210
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getsid.c119
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c86
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_issetugid.c148
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_kevent.c206
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_kill.c312
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_link.c233
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_listen.c138
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c247
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c74
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mincore.c336
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_minherit.c200
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mkdir.c210
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c276
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mknod.c202
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mlock.c286
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mmap.c524
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mprotect.c365
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgctl.c362
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgget.c292
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c346
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c342
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msync.c248
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c191
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_pipe.c163
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_pipe2.c210
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_poll.c396
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c165
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c161
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_revoke.c195
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_select.c223
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c532
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_setuid.c122
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_sigaction.c165
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c115
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c126
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_socketpair.c141
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_stat.c421
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c133
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_timer_create.c211
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_truncate.c188
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_ucontext.c76
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_umask.c205
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_unlink.c162
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_write.c236
-rw-r--r--contrib/netbsd-tests/lib/libc/t_cdb.c158
-rw-r--r--contrib/netbsd-tests/lib/libc/t_convfp.c155
-rw-r--r--contrib/netbsd-tests/lib/libc/t_gdtoa.c67
-rw-r--r--contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c87
-rw-r--r--contrib/netbsd-tests/lib/libc/time/t_mktime.c155
-rw-r--r--contrib/netbsd-tests/lib/libc/time/t_strptime.c281
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c62
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c115
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c107
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_static.c95
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c55
-rw-r--r--contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c58
-rw-r--r--contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c174
-rw-r--r--contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c163
-rw-r--r--contrib/netbsd-tests/lib/libcrypt/t_crypt.c145
-rw-r--r--contrib/netbsd-tests/lib/libcurses/atf.terminfo44
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/addch.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/addchstr.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/addstr.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/attributes.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/background1.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/background2.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/background3.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/background4.chk6
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/background5.chk3
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/bell.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/box_standout.chk5
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/chgat1.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/chgat2.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/chgat3.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/clear1.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/clear10.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/clear2.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/clear3.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/clear4.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/clear5.chk23
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/clear6.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/clear7.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/clear8.chk6
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/clear9.chk6
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/color_blank_draw.chk24
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/color_blue_back.chk24
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/color_default.chk24
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/color_red_fore.chk24
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/color_set.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/color_start.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin1.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin10.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin11.chk4
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin12.chk4
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin13.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin14.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin2.chk6
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin3.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin4.chk6
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin5.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin6.chk6
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin7.chk6
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin8.chk4
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/copywin9.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/curs_set1.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/curs_set2.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/curs_set3.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/curses_start.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/fill.chk23
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/home.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/timeout.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/wborder.chk6
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/wborder_refresh.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/wgetstr.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/wgetstr_refresh.chk2
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/window.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/wprintw_refresh.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/wscrl1.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/check_files/wscrl2.chk1
-rw-r--r--contrib/netbsd-tests/lib/libcurses/director/director.c279
-rw-r--r--contrib/netbsd-tests/lib/libcurses/director/returns.h66
-rw-r--r--contrib/netbsd-tests/lib/libcurses/director/testlang_conf.l437
-rw-r--r--contrib/netbsd-tests/lib/libcurses/director/testlang_parse.y1617
-rw-r--r--contrib/netbsd-tests/lib/libcurses/slave/command_table.h397
-rw-r--r--contrib/netbsd-tests/lib/libcurses/slave/commands.c243
-rw-r--r--contrib/netbsd-tests/lib/libcurses/slave/curses_commands.c7165
-rw-r--r--contrib/netbsd-tests/lib/libcurses/slave/curses_commands.h422
-rw-r--r--contrib/netbsd-tests/lib/libcurses/slave/slave.c177
-rw-r--r--contrib/netbsd-tests/lib/libcurses/slave/slave.h50
-rwxr-xr-xcontrib/netbsd-tests/lib/libcurses/t_curses.sh294
-rw-r--r--contrib/netbsd-tests/lib/libcurses/testframe.txt241
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/addch4
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/addchnstr5
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/addchstr4
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/addnstr5
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/addstr4
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/assume_default_colors19
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/attributes23
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/background23
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/beep5
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/box8
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/can_change_color3
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/cbreak18
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/chgat15
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/clear57
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/color_content12
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/color_set11
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/copywin81
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/curs_set7
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/fill_screen29
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/getch3
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/getstr6
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/mvwin12
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/start3
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/start_color5
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/std_defines138
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/termattrs3
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/timeout21
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/wborder6
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/window2
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/window_create4
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/wprintw6
-rw-r--r--contrib/netbsd-tests/lib/libcurses/tests/wscrl11
-rw-r--r--contrib/netbsd-tests/lib/libdes/t_des.c989
-rwxr-xr-xcontrib/netbsd-tests/lib/libevent/t_event.sh67
-rw-r--r--contrib/netbsd-tests/lib/libexecinfo/t_backtrace.c167
-rw-r--r--contrib/netbsd-tests/lib/libm/t_acos.c105
-rw-r--r--contrib/netbsd-tests/lib/libm/t_asin.c296
-rw-r--r--contrib/netbsd-tests/lib/libm/t_atan.c101
-rw-r--r--contrib/netbsd-tests/lib/libm/t_cbrt.c374
-rw-r--r--contrib/netbsd-tests/lib/libm/t_ceil.c931
-rw-r--r--contrib/netbsd-tests/lib/libm/t_cos.c263
-rw-r--r--contrib/netbsd-tests/lib/libm/t_cosh.c270
-rw-r--r--contrib/netbsd-tests/lib/libm/t_erf.c299
-rw-r--r--contrib/netbsd-tests/lib/libm/t_exp.c576
-rw-r--r--contrib/netbsd-tests/lib/libm/t_fmod.c63
-rw-r--r--contrib/netbsd-tests/lib/libm/t_infinity.c119
-rw-r--r--contrib/netbsd-tests/lib/libm/t_ldexp.c480
-rw-r--r--contrib/netbsd-tests/lib/libm/t_libm.h62
-rw-r--r--contrib/netbsd-tests/lib/libm/t_log.c884
-rw-r--r--contrib/netbsd-tests/lib/libm/t_modf.c68
-rw-r--r--contrib/netbsd-tests/lib/libm/t_pow.c673
-rw-r--r--contrib/netbsd-tests/lib/libm/t_precision.c77
-rw-r--r--contrib/netbsd-tests/lib/libm/t_round.c85
-rw-r--r--contrib/netbsd-tests/lib/libm/t_scalbn.c526
-rw-r--r--contrib/netbsd-tests/lib/libm/t_sin.c263
-rw-r--r--contrib/netbsd-tests/lib/libm/t_sinh.c273
-rw-r--r--contrib/netbsd-tests/lib/libm/t_sqrt.c368
-rw-r--r--contrib/netbsd-tests/lib/libm/t_tan.c260
-rw-r--r--contrib/netbsd-tests/lib/libm/t_tanh.c207
-rw-r--r--contrib/netbsd-tests/lib/libobjc/t_threads.m136
-rw-r--r--contrib/netbsd-tests/lib/libposix/t_rename.c89
-rw-r--r--contrib/netbsd-tests/lib/libppath/personnel.plist26
-rwxr-xr-xcontrib/netbsd-tests/lib/libppath/plist_to_c20
-rw-r--r--contrib/netbsd-tests/lib/libppath/t_ppath.c1548
-rw-r--r--contrib/netbsd-tests/lib/libprop/t_basic.c203
-rw-r--r--contrib/netbsd-tests/lib/libpthread/d_mach92
-rw-r--r--contrib/netbsd-tests/lib/libpthread/dlopen/dso/h_pthread_dlopen.c86
-rw-r--r--contrib/netbsd-tests/lib/libpthread/dlopen/t_dlopen.c171
-rw-r--r--contrib/netbsd-tests/lib/libpthread/dlopen/t_dso_pthread_create.c96
-rw-r--r--contrib/netbsd-tests/lib/libpthread/dlopen/t_main_pthread_create.c106
-rw-r--r--contrib/netbsd-tests/lib/libpthread/h_atexit.c203
-rw-r--r--contrib/netbsd-tests/lib/libpthread/h_cancel.c60
-rw-r--r--contrib/netbsd-tests/lib/libpthread/h_common.h12
-rw-r--r--contrib/netbsd-tests/lib/libpthread/h_exit.c47
-rw-r--r--contrib/netbsd-tests/lib/libpthread/h_resolv.c208
-rwxr-xr-xcontrib/netbsd-tests/lib/libpthread/t_atexit.sh49
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_barrier.c110
-rwxr-xr-xcontrib/netbsd-tests/lib/libpthread/t_cancel.sh44
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_cond.c563
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_condwait.c146
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_detach.c95
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_equal.c74
-rwxr-xr-xcontrib/netbsd-tests/lib/libpthread/t_exit.sh41
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_fork.c115
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_fpu.c148
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_join.c181
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_kill.c147
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_mutex.c327
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_name.c103
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_once.c200
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_preempt.c128
-rwxr-xr-xcontrib/netbsd-tests/lib/libpthread/t_resolv.sh42
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_rwlock.c125
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_sem.c310
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_sigalarm.c107
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_siglongjmp.c109
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_sigmask.c261
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_sigsuspend.c90
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_sleep.c104
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_swapcontext.c112
-rw-r--r--contrib/netbsd-tests/lib/librt/t_sched.c256
-rw-r--r--contrib/netbsd-tests/lib/librt/t_sem.c181
-rw-r--r--contrib/netbsd-tests/lib/librumpclient/h_exec.c132
-rw-r--r--contrib/netbsd-tests/lib/librumpclient/h_execthr.c187
-rwxr-xr-xcontrib/netbsd-tests/lib/librumpclient/t_exec.sh154
-rw-r--r--contrib/netbsd-tests/lib/librumpclient/t_fd.c146
-rw-r--r--contrib/netbsd-tests/lib/librumphijack/h_client.c138
-rw-r--r--contrib/netbsd-tests/lib/librumphijack/h_cwd.c168
-rw-r--r--contrib/netbsd-tests/lib/librumphijack/h_netget.c101
-rw-r--r--contrib/netbsd-tests/lib/librumphijack/index.html5
-rw-r--r--contrib/netbsd-tests/lib/librumphijack/netstat.expout6
-rw-r--r--contrib/netbsd-tests/lib/librumphijack/ssh_config.in14
-rw-r--r--contrib/netbsd-tests/lib/librumphijack/ssh_host_key15
-rw-r--r--contrib/netbsd-tests/lib/librumphijack/ssh_host_key.pub1
-rw-r--r--contrib/netbsd-tests/lib/librumphijack/sshd_config.in39
-rwxr-xr-xcontrib/netbsd-tests/lib/librumphijack/t_asyncio.sh94
-rwxr-xr-xcontrib/netbsd-tests/lib/librumphijack/t_config.sh54
-rwxr-xr-xcontrib/netbsd-tests/lib/librumphijack/t_cwd.sh72
-rwxr-xr-xcontrib/netbsd-tests/lib/librumphijack/t_sh.sh91
-rwxr-xr-xcontrib/netbsd-tests/lib/librumphijack/t_tcpip.sh268
-rwxr-xr-xcontrib/netbsd-tests/lib/librumphijack/t_vfs.sh223
-rw-r--r--contrib/netbsd-tests/lib/libskey/t_algorithms.c121
-rwxr-xr-xcontrib/netbsd-tests/lib/libsljit/t_sljit.sh45
-rw-r--r--contrib/netbsd-tests/lib/libutil/t_efun.c135
-rw-r--r--contrib/netbsd-tests/lib/libutil/t_parsedate.c142
-rw-r--r--contrib/netbsd-tests/lib/libutil/t_pidfile.c363
-rw-r--r--contrib/netbsd-tests/lib/libutil/t_snprintb.c117
-rw-r--r--contrib/netbsd-tests/lib/libutil/t_sockaddr_snprintf.c185
-rw-r--r--contrib/netbsd-tests/lib/semaphore/pthread/t_sem_pth.c17
-rw-r--r--contrib/netbsd-tests/lib/semaphore/sem.c332
547 files changed, 85095 insertions, 0 deletions
diff --git a/contrib/netbsd-tests/lib/csu/arch/alpha/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/alpha/h_initfini_align.S
new file mode 100644
index 0000000..b4382c1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/arch/alpha/h_initfini_align.S
@@ -0,0 +1,16 @@
+/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:55 matt Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:55 matt Exp $")
+
+/*
+ * LINTSTUB: bool check_stack_alignment(void);
+ */
+
+LEAF_NOPROFILE(check_stack_alignment, 0)
+ ldiq v0, 0
+ and sp, 7, t0
+ cmoveq t0, 1, v0
+ ret
+END(check_stack_alignment)
diff --git a/contrib/netbsd-tests/lib/csu/arch/arm/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/arm/h_initfini_align.S
new file mode 100644
index 0000000..2abc56f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/arch/arm/h_initfini_align.S
@@ -0,0 +1,20 @@
+/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $")
+
+/*
+ * LINTSTUB: bool check_stack_alignment(void);
+ */
+
+ARM_ENTRY(check_stack_alignment)
+#ifdef __ARM_EABI__
+ tst sp, #7
+#else
+ tst sp, #3
+#endif
+ movne r0, #0
+ moveq r0, #1
+ RET
+END(check_stack_alignment)
diff --git a/contrib/netbsd-tests/lib/csu/arch/hppa/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/hppa/h_initfini_align.S
new file mode 100644
index 0000000..c297e90
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/arch/hppa/h_initfini_align.S
@@ -0,0 +1,12 @@
+/* $NetBSD: h_initfini_align.S,v 1.1 2013/11/15 11:48:30 skrll Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/11/15 11:48:30 skrll Exp $")
+
+LEAF_ENTRY(check_stack_alignment)
+ extru %sp,31,6,%ret0
+ comiclr,<> 0, %ret0, %ret0
+ ldi 1,%ret0
+ bv,n %r0(%r2)
+EXIT(check_stack_alignment)
diff --git a/contrib/netbsd-tests/lib/csu/arch/i386/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/i386/h_initfini_align.S
new file mode 100644
index 0000000..e212989
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/arch/i386/h_initfini_align.S
@@ -0,0 +1,12 @@
+/* $NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $")
+
+_ENTRY(check_stack_alignment)
+ movl %esp, %eax
+ andl $3, %eax
+ setz %al
+ movzbl %al, %eax
+ ret
diff --git a/contrib/netbsd-tests/lib/csu/arch/ia64/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/ia64/h_initfini_align.S
new file mode 100644
index 0000000..f7612a8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/arch/ia64/h_initfini_align.S
@@ -0,0 +1,37 @@
+/* $NetBSD: h_initfini_align.S,v 1.2 2014/03/16 09:27:04 cherry Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: h_initfini_align.S,v 1.2 2014/03/16 09:27:04 cherry Exp $")
+
+ENTRY(check_stack_alignment, 0)
+ .prologue
+ .regstk 0, 2, 0, 0
+
+ alloc loc0 = ar.pfs, 0, 2, 0, 0
+
+ .body
+ mov ret0 = 1
+ ;;
+
+ /* ar.bsp has an 8-byte alignment requirement */
+ mov loc1 = ar.bsp
+ ;;
+
+ and loc1 = 7, loc1
+ ;;
+
+ cmp.eq p1, p0 = 0, loc1
+ (p0) mov ret0 = 0
+ ;;
+
+ /* sp has a 16-byte alignment requirement */
+ (p1) mov loc1 = sp
+ ;;
+ (p1) and loc1 = 15, loc1
+ ;;
+
+ (p1) cmp.eq p1, p0 = 0, loc1
+ (p0) mov ret0 = 0
+
+ br.ret.sptk.few rp
diff --git a/contrib/netbsd-tests/lib/csu/arch/mips/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/mips/h_initfini_align.S
new file mode 100644
index 0000000..d6782ac
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/arch/mips/h_initfini_align.S
@@ -0,0 +1,19 @@
+/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $")
+
+/*
+ * LINTSTUB: bool check_stack_alignment(void);
+ */
+
+LEAF_NOPROFILE(check_stack_alignment)
+#ifdef __mips_o32
+ andi v1,sp,3
+#else
+ andi v1,sp,7
+#endif
+ sltiu v0,v1,1
+ jr ra
+END(check_stack_alignment)
diff --git a/contrib/netbsd-tests/lib/csu/arch/powerpc/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/powerpc/h_initfini_align.S
new file mode 100644
index 0000000..7abd9ea
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/arch/powerpc/h_initfini_align.S
@@ -0,0 +1,17 @@
+/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $")
+
+/*
+ * LINTSTUB: bool check_stack_alignment(void);
+ */
+
+_ENTRY(check_stack_alignment)
+ li %r3,0
+ andis. %r0,%r1,15
+ bnelr %cr0
+ li %r3,1
+ blr
+END(check_stack_alignment)
diff --git a/contrib/netbsd-tests/lib/csu/arch/sparc/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/sparc/h_initfini_align.S
new file mode 100644
index 0000000..a770d39
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/arch/sparc/h_initfini_align.S
@@ -0,0 +1,10 @@
+/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/12 11:22:26 martin Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/12 11:22:26 martin Exp $")
+
+_ENTRY(check_stack_alignment)
+ and %sp, 7, %o1
+ retl
+ not %o1, %o0
diff --git a/contrib/netbsd-tests/lib/csu/arch/sparc64/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/sparc64/h_initfini_align.S
new file mode 100644
index 0000000..402ceb3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/arch/sparc64/h_initfini_align.S
@@ -0,0 +1,11 @@
+/* $NetBSD: h_initfini_align.S,v 1.1 2013/11/15 20:00:20 martin Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/11/15 20:00:20 martin Exp $")
+
+_ENTRY(check_stack_alignment)
+ add %sp, BIAS, %o1
+ and %o1, 15, %o2
+ retl
+ not %o2, %o0
diff --git a/contrib/netbsd-tests/lib/csu/arch/vax/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/vax/h_initfini_align.S
new file mode 100644
index 0000000..a751e1f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/arch/vax/h_initfini_align.S
@@ -0,0 +1,17 @@
+/* $NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: h_initfini_align.S,v 1.1 2013/12/11 17:31:56 matt Exp $")
+
+/*
+ * LINTSTUB: bool check_stack_alignment(void);
+ */
+
+_ENTRY(check_stack_alignment, 0)
+ clrl %r0
+ bitl $3,%sp
+ bneq 1f
+ incl %r0
+1: ret
+END(check_stack_alignment)
diff --git a/contrib/netbsd-tests/lib/csu/arch/x86_64/h_initfini_align.S b/contrib/netbsd-tests/lib/csu/arch/x86_64/h_initfini_align.S
new file mode 100644
index 0000000..fbc1e56
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/arch/x86_64/h_initfini_align.S
@@ -0,0 +1,13 @@
+/* $NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: h_initfini_align.S,v 1.2 2010/12/12 18:21:21 joerg Exp $")
+
+_ENTRY(check_stack_alignment)
+ movl %esp, %eax
+ andl $15, %eax
+ subl $8, %eax
+ sete %al
+ movzbl %al, %eax
+ ret
diff --git a/contrib/netbsd-tests/lib/csu/dso/h_initfini3_dso.cxx b/contrib/netbsd-tests/lib/csu/dso/h_initfini3_dso.cxx
new file mode 100644
index 0000000..ff90ce6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/dso/h_initfini3_dso.cxx
@@ -0,0 +1,37 @@
+#include <unistd.h>
+
+#ifdef CHECK_STACK_ALIGNMENT
+#include <stdlib.h>
+
+extern "C" int check_stack_alignment(void);
+#endif
+
+class Test2 {
+public:
+ Test2()
+ {
+ static const char msg[] = "constructor2 executed\n";
+ write(STDOUT_FILENO, msg, sizeof(msg) - 1);
+#ifdef CHECK_STACK_ALIGNMENT
+ if (!check_stack_alignment()) {
+ static const char msg2[] = "stack unaligned \n";
+ write(STDOUT_FILENO, msg2, sizeof(msg2) - 1);
+ exit(1);
+ }
+#endif
+ }
+ ~Test2()
+ {
+ static const char msg[] = "destructor2 executed\n";
+ write(STDOUT_FILENO, msg, sizeof(msg) - 1);
+#ifdef CHECK_STACK_ALIGNMENT
+ if (!check_stack_alignment()) {
+ static const char msg2[] = "stack unaligned \n";
+ write(STDOUT_FILENO, msg2, sizeof(msg2) - 1);
+ exit(1);
+ }
+#endif
+ }
+};
+
+Test2 test2;
diff --git a/contrib/netbsd-tests/lib/csu/h_initfini1.cxx b/contrib/netbsd-tests/lib/csu/h_initfini1.cxx
new file mode 100644
index 0000000..d410f70
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/h_initfini1.cxx
@@ -0,0 +1,9 @@
+#include <unistd.h>
+
+int
+main(void)
+{
+ static const char msg[] = "main executed\n";
+ write(STDOUT_FILENO, msg, sizeof(msg) - 1);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/csu/h_initfini3.cxx b/contrib/netbsd-tests/lib/csu/h_initfini3.cxx
new file mode 100644
index 0000000..13f54ce
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/h_initfini3.cxx
@@ -0,0 +1,22 @@
+#include <dlfcn.h>
+#include <err.h>
+#include <unistd.h>
+
+int
+main(void)
+{
+ static const char msg1[] = "main started\n";
+ static const char msg2[] = "main after dlopen\n";
+ static const char msg3[] = "main terminated\n";
+
+ void *handle;
+
+ write(STDOUT_FILENO, msg1, sizeof(msg1) - 1);
+ handle = dlopen("h_initfini3_dso.so", RTLD_NOW | RTLD_LOCAL);
+ if (handle == NULL)
+ err(1, "dlopen");
+ write(STDOUT_FILENO, msg2, sizeof(msg2) - 1);
+ dlclose(handle);
+ write(STDOUT_FILENO, msg3, sizeof(msg3) - 1);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/csu/h_initfini_common.cxx b/contrib/netbsd-tests/lib/csu/h_initfini_common.cxx
new file mode 100644
index 0000000..dd34983
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/h_initfini_common.cxx
@@ -0,0 +1,37 @@
+#include <unistd.h>
+
+#ifdef CHECK_STACK_ALIGNMENT
+#include <stdlib.h>
+
+extern "C" int check_stack_alignment(void);
+#endif
+
+class Test {
+public:
+ Test()
+ {
+ static const char msg[] = "constructor executed\n";
+ write(STDOUT_FILENO, msg, sizeof(msg) - 1);
+#ifdef CHECK_STACK_ALIGNMENT
+ if (!check_stack_alignment()) {
+ static const char msg2[] = "stack unaligned \n";
+ write(STDOUT_FILENO, msg2, sizeof(msg2) - 1);
+ exit(1);
+ }
+#endif
+ }
+ ~Test()
+ {
+ static const char msg[] = "destructor executed\n";
+ write(STDOUT_FILENO, msg, sizeof(msg) - 1);
+#ifdef CHECK_STACK_ALIGNMENT
+ if (!check_stack_alignment()) {
+ static const char msg2[] = "stack unaligned \n";
+ write(STDOUT_FILENO, msg2, sizeof(msg2) - 1);
+ exit(1);
+ }
+#endif
+ }
+};
+
+Test test;
diff --git a/contrib/netbsd-tests/lib/csu/t_crt0.sh b/contrib/netbsd-tests/lib/csu/t_crt0.sh
new file mode 100755
index 0000000..a36a9b7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/csu/t_crt0.sh
@@ -0,0 +1,104 @@
+# $NetBSD: t_crt0.sh,v 1.4 2011/12/11 14:57:07 joerg Exp $
+#
+# 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.
+#
+
+atf_test_case initfini1
+initfini1_head()
+{
+ atf_set "descr" "Checks support for init/fini sections"
+}
+initfini1_body()
+{
+ cat >expout <<EOF
+constructor executed
+main executed
+destructor executed
+EOF
+
+ atf_check -o file:expout "$(atf_get_srcdir)/h_initfini1"
+}
+
+atf_test_case initfini2
+initfini2_head()
+{
+ atf_set "descr" "Checks support for init/fini sections in static binaries"
+}
+initfini2_body()
+{
+ cat >expout <<EOF
+constructor executed
+main executed
+destructor executed
+EOF
+
+ atf_check -o file:expout "$(atf_get_srcdir)/h_initfini2"
+}
+
+atf_test_case initfini3
+initfini3_head()
+{
+ atf_set "descr" "Checks support for init/fini sections in dlopen"
+}
+initfini3_body()
+{
+ cat >expout <<EOF
+constructor executed
+main started
+constructor2 executed
+main after dlopen
+destructor2 executed
+main terminated
+destructor executed
+EOF
+
+ atf_check -o file:expout "$(atf_get_srcdir)/h_initfini3"
+}
+
+atf_test_case initfini4
+initfini4_head()
+{
+ atf_set "descr" "Checks support for init/fini sections in LD_PRELOAD"
+}
+initfini4_body()
+{
+ cat >expout <<EOF
+constructor2 executed
+constructor executed
+main executed
+destructor executed
+destructor2 executed
+EOF
+
+ atf_check -o file:expout -x "env LD_PRELOAD=$(atf_get_srcdir)/h_initfini3_dso.so $(atf_get_srcdir)/h_initfini1"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case initfini1
+ atf_add_test_case initfini2
+ atf_add_test_case initfini3
+ atf_add_test_case initfini4
+}
diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_bluetooth.c b/contrib/netbsd-tests/lib/libbluetooth/t_bluetooth.c
new file mode 100644
index 0000000..066f8d9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libbluetooth/t_bluetooth.c
@@ -0,0 +1,87 @@
+/* $NetBSD: t_bluetooth.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Iain Hibbert.
+ *
+ * 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 <bluetooth.h>
+#include <string.h>
+
+ATF_TC(check_bt_aton);
+
+ATF_TC_HEAD(check_bt_aton, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test bt_aton results");
+}
+
+ATF_TC_BODY(check_bt_aton, tc)
+{
+ bdaddr_t bdaddr;
+
+ ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d:0e", &bdaddr), 0);
+ ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d0:0e:0f", &bdaddr), 0);
+ ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d:0e:0f:00", &bdaddr), 0);
+ ATF_CHECK_EQ(bt_aton("0a:0b:0c:0d:0e:0f\n", &bdaddr), 0);
+ ATF_CHECK_EQ(bt_aton(" 0a:0b:0c:0d:0e:0f", &bdaddr), 0);
+ ATF_CHECK_EQ(bt_aton("0a:0b:0x:0d:0e:0f", &bdaddr), 0);
+
+ ATF_REQUIRE(bt_aton("0a:0b:0c:0d:0e:0f", &bdaddr));
+ ATF_CHECK_EQ(bdaddr.b[0], 0x0f);
+ ATF_CHECK_EQ(bdaddr.b[1], 0x0e);
+ ATF_CHECK_EQ(bdaddr.b[2], 0x0d);
+ ATF_CHECK_EQ(bdaddr.b[3], 0x0c);
+ ATF_CHECK_EQ(bdaddr.b[4], 0x0b);
+ ATF_CHECK_EQ(bdaddr.b[5], 0x0a);
+}
+
+ATF_TC(check_bt_ntoa);
+
+ATF_TC_HEAD(check_bt_ntoa, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test bt_ntoa results");
+}
+
+ATF_TC_BODY(check_bt_ntoa, tc)
+{
+ bdaddr_t bdaddr = { { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 } };
+
+ ATF_CHECK_STREQ(bt_ntoa(&bdaddr, NULL), "55:44:33:22:11:00");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, check_bt_aton);
+ ATF_TP_ADD_TC(tp, check_bt_ntoa);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_data.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_data.c
new file mode 100644
index 0000000..cff6627
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_data.c
@@ -0,0 +1,136 @@
+/* $NetBSD: t_sdp_data.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Iain Hibbert.
+ *
+ * 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 <sdp.h>
+
+ATF_TC(check_sdp_data_type);
+
+ATF_TC_HEAD(check_sdp_data_type, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_data_type results");
+}
+
+ATF_TC_BODY(check_sdp_data_type, tc)
+{
+ uint8_t data[] = {
+ 0x00, // nil
+ 0x08, 0x00, // uint8 0x00
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t value;
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_NIL);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UINT8);
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TC(check_sdp_data_size);
+
+ATF_TC_HEAD(check_sdp_data_size, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_data_size results");
+}
+
+ATF_TC_BODY(check_sdp_data_size, tc)
+{
+ uint8_t data[] = {
+ 0x00, // nil
+ 0x08, 0x00, // uint8
+ 0x11, 0x00, 0x00, // int16
+ 0x1a, 0x00, 0x00, 0x00, // uuid32
+ 0x00,
+ 0x28, 0x00, // bool
+ 0x25, 0x00, // str8(0)
+ 0x25, 0x02, 0x00, 0x00, // str8(2)
+ 0x36, 0x00, 0x00, // seq16(0)
+ 0x3e, 0x00, 0x05, 0x00, // alt16(5)
+ 0x00, 0x00, 0x00, 0x00,
+ 0x37, 0x00, 0x00, 0x00, // seq32(0)
+ 0x00,
+ 0x47, 0x00, 0x00, 0x00, // url32(7)
+ 0x07, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t value;
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_size(&value), 1);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_size(&value), 2);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_size(&value), 3);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_size(&value), 5);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_size(&value), 2);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_size(&value), 2);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_size(&value), 4);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_size(&value), 3);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_size(&value), 8);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_size(&value), 5);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_size(&value), 12);
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, check_sdp_data_type);
+ ATF_TP_ADD_TC(tp, check_sdp_data_size);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_get.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_get.c
new file mode 100644
index 0000000..3ad8070
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_get.c
@@ -0,0 +1,643 @@
+/* $NetBSD: t_sdp_get.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Iain Hibbert.
+ *
+ * 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 <limits.h>
+#include <sdp.h>
+#include <string.h>
+
+ATF_TC(check_sdp_get_data);
+
+ATF_TC_HEAD(check_sdp_get_data, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_get_data results");
+}
+
+ATF_TC_BODY(check_sdp_get_data, tc)
+{
+ uint8_t data[] = {
+ 0x09, 0x00, 0x00, // uint16 0x0000
+ 0x35, 0x05, // seq8(5)
+ 0x19, 0x00, 0x00, // uuid16 0x0000
+ 0x08, 0x00, // uint8 0x00
+ 0x36, 0x00, 0x01, // seq16(1)
+ 0x19, // uint16 /* invalid */
+ 0x25, 0x04, 0x54, 0x45, // str8(4) "TEST"
+ 0x53, 0x54,
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t value, seq;
+
+ /*
+ * sdp_get_data constructs a new sdp_data_t containing
+ * the next data element, advancing test if successful
+ */
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UINT16);
+ ATF_CHECK_EQ(sdp_data_size(&value), 3);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_SEQ8);
+ ATF_CHECK_EQ(sdp_data_size(&value), 7);
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_SEQ16);
+ ATF_CHECK_EQ(sdp_data_size(&value), 4);
+ ATF_REQUIRE_EQ(sdp_get_seq(&value, &seq), true);
+ ATF_REQUIRE_EQ(sdp_get_data(&seq, &value), false); /* invalid */
+
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_STR8);
+ ATF_CHECK_EQ(sdp_data_size(&value), 6);
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TC(check_sdp_get_attr);
+
+ATF_TC_HEAD(check_sdp_get_attr, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_get_attr results");
+}
+
+ATF_TC_BODY(check_sdp_get_attr, tc)
+{
+ uint8_t data[] = {
+ 0x09, 0x00, 0x00, // uint16 0x0000
+ 0x35, 0x05, // seq8(5)
+ 0x19, 0x00, 0x00, // uuid16 0x0000
+ 0x08, 0x00, // uint8 0x00
+ 0x08, 0x00, // uint8 0x00
+ 0x09, 0x00, 0x01, // uint16 0x0001
+ 0x19, 0x12, 0x34, // uuid16 0x1234
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t value;
+ uint16_t attr;
+
+ /*
+ * sdp_get_attr expects a UINT16 followed by any data item
+ * and advances test if successful
+ */
+ ATF_REQUIRE(sdp_get_attr(&test, &attr, &value));
+ ATF_CHECK_EQ(attr, 0x0000);
+ ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_SEQ8);
+ ATF_CHECK_EQ(sdp_data_size(&value), 7);
+
+ ATF_REQUIRE_EQ(sdp_get_attr(&test, &attr, &value), false);
+ ATF_REQUIRE(sdp_get_data(&test, &value));
+ ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UINT8);
+ ATF_CHECK_EQ(sdp_data_size(&value), 2);
+
+ ATF_REQUIRE(sdp_get_attr(&test, &attr, &value));
+ ATF_CHECK_EQ(attr, 0x0001);
+ ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_UUID16);
+ ATF_CHECK_EQ(sdp_data_size(&value), 3);
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TC(check_sdp_get_uuid);
+
+ATF_TC_HEAD(check_sdp_get_uuid, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_get_uuid results");
+}
+
+ATF_TC_BODY(check_sdp_get_uuid, tc)
+{
+ uint8_t data[] = {
+ 0x19, 0x12, 0x34, // uuid16 0x1234
+ 0x1a, 0x11, 0x22, 0x33, // uuid32 0x11223344
+ 0x44,
+ 0x00, // nil
+ 0x1c, // uuid128 0x00112233-4444--5555-6666-778899aabbcc
+ 0x00, 0x11, 0x22, 0x33,
+ 0x44, 0x44, 0x55, 0x55,
+ 0x66, 0x66, 0x77, 0x88,
+ 0x99, 0xaa, 0xbb, 0xcc,
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ uuid_t u16 = {
+ 0x00001234,
+ 0x0000,
+ 0x1000,
+ 0x80,
+ 0x00,
+ { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb }
+ };
+ uuid_t u32 = {
+ 0x11223344,
+ 0x0000,
+ 0x1000,
+ 0x80,
+ 0x00,
+ { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb }
+ };
+ uuid_t u128 = {
+ 0x00112233,
+ 0x4444,
+ 0x5555,
+ 0x66,
+ 0x66,
+ { 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc }
+ };
+ sdp_data_t nil;
+ uuid_t value;
+
+ /*
+ * sdp_get_uuid expects any UUID type returns the full uuid
+ * advancing test if successful
+ */
+ ATF_REQUIRE(sdp_get_uuid(&test, &value));
+ ATF_CHECK(uuid_equal(&value, &u16, NULL));
+
+ ATF_REQUIRE(sdp_get_uuid(&test, &value));
+ ATF_CHECK(uuid_equal(&value, &u32, NULL));
+
+ ATF_REQUIRE_EQ(sdp_get_uuid(&test, &value), false); /* not uuid */
+ ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL);
+
+ ATF_REQUIRE(sdp_get_uuid(&test, &value));
+ ATF_CHECK(uuid_equal(&value, &u128, NULL));
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TC(check_sdp_get_bool);
+
+ATF_TC_HEAD(check_sdp_get_bool, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_get_bool results");
+}
+
+ATF_TC_BODY(check_sdp_get_bool, tc)
+{
+ uint8_t data[] = {
+ 0x28, 0x00, // bool false
+ 0x00, // nil
+ 0x28, 0x01, // bool true
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t nil;
+ bool value;
+
+ /*
+ * sdp_get_bool expects a BOOL type
+ * advancing test if successful
+ */
+ ATF_REQUIRE(sdp_get_bool(&test, &value));
+ ATF_CHECK_EQ(value, false);
+
+ ATF_REQUIRE_EQ(sdp_get_bool(&test, &value), false); /* not bool */
+ ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL);
+
+ ATF_REQUIRE(sdp_get_bool(&test, &value));
+ ATF_CHECK_EQ(value, true);
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TC(check_sdp_get_uint);
+
+ATF_TC_HEAD(check_sdp_get_uint, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_get_uint results");
+}
+
+ATF_TC_BODY(check_sdp_get_uint, tc)
+{
+ uint8_t data[] = {
+ 0x08, 0x00, // uint8 0x00
+ 0x08, 0xff, // uint8 0xff
+ 0x09, 0x01, 0x02, // uint16 0x0102
+ 0x09, 0xff, 0xff, // uint16 0xffff
+ 0x00, // nil
+ 0x0a, 0x01, 0x02, 0x03, // uint32 0x01020304
+ 0x04,
+ 0x0a, 0xff, 0xff, 0xff, // uint32 0xffffffff
+ 0xff,
+ 0x0b, 0x01, 0x02, 0x03, // uint64 0x0102030405060708
+ 0x04, 0x05, 0x06, 0x07,
+ 0x08,
+ 0x0b, 0xff, 0xff, 0xff, // uint64 0xffffffffffffffff
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff,
+ 0x0c, 0x00, 0x00, 0x00, // uint128 0x00000000000000000000000000000000
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x0c, 0x00, 0x00, 0x00, // uint128 0x00000000000000010000000000000000
+ 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x0c, 0x00, 0x00, 0x00, // uint128 0x0000000000000000ffffffffffffffff
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff,
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t nil;
+ uintmax_t value;
+
+ /*
+ * sdp_get_uint expects any UINT type, advancing test if successful
+ */
+ ATF_REQUIRE(sdp_get_uint(&test, &value));
+ ATF_CHECK_EQ(value, 0x00);
+
+ ATF_REQUIRE(sdp_get_uint(&test, &value));
+ ATF_CHECK_EQ(value, UINT8_MAX);
+
+ ATF_REQUIRE(sdp_get_uint(&test, &value));
+ ATF_CHECK_EQ(value, 0x0102);
+
+ ATF_REQUIRE(sdp_get_uint(&test, &value));
+ ATF_CHECK_EQ(value, UINT16_MAX);
+
+ ATF_REQUIRE_EQ(sdp_get_uint(&test, &value), false); /* not uint */
+ ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL);
+
+ ATF_REQUIRE(sdp_get_uint(&test, &value));
+ ATF_CHECK_EQ(value, 0x01020304);
+
+ ATF_REQUIRE(sdp_get_uint(&test, &value));
+ ATF_CHECK_EQ(value, UINT32_MAX);
+
+ ATF_REQUIRE(sdp_get_uint(&test, &value));
+ ATF_CHECK_EQ(value, 0x0102030405060708);
+
+ ATF_REQUIRE(sdp_get_uint(&test, &value));
+ ATF_CHECK_EQ(value, UINT64_MAX);
+
+ /*
+ * expected failure is that we cannot decode UINT128 values larger than UINT64
+ */
+ ATF_REQUIRE(sdp_get_uint(&test, &value));
+ ATF_CHECK_EQ(value, 0x00000000000000000000000000000000);
+
+ ATF_REQUIRE_EQ(sdp_get_uint(&test, &value), false); /* overflow */
+ ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_UINT128);
+
+ ATF_REQUIRE(sdp_get_uint(&test, &value));
+ ATF_CHECK_EQ(value, UINT64_MAX);
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TC(check_sdp_get_int);
+
+ATF_TC_HEAD(check_sdp_get_int, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_get_int results");
+}
+
+ATF_TC_BODY(check_sdp_get_int, tc)
+{
+ uint8_t data[] = {
+ 0x10, 0x00, // int8 0x00
+ 0x10, 0x7f, // int8 0x7f
+ 0x10, 0x80, // int8 0x80
+ 0x11, 0x01, 0x02, // int16 0x0102
+ 0x11, 0x7f, 0xff, // int16 0x7fff
+ 0x11, 0x80, 0x00, // int16 0x8000
+ 0x00, // nil
+ 0x12, 0x01, 0x02, 0x03, // int32 0x01020304
+ 0x04,
+ 0x12, 0x7f, 0xff, 0xff, // int32 0x7fffffff
+ 0xff,
+ 0x12, 0x80, 0x00, 0x00, // int32 0x80000000
+ 0x00,
+ 0x13, 0x01, 0x02, 0x03, // int64 0x0102030405060708
+ 0x04, 0x05, 0x06, 0x07,
+ 0x08,
+ 0x13, 0x7f, 0xff, 0xff, // int64 0x7fffffffffffffff
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff,
+ 0x13, 0x80, 0x00, 0x00, // int64 0x8000000000000000
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x14, 0x00, 0x00, 0x00, // int128 0x00000000000000000000000000000000
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x14, 0x00, 0x00, 0x00, // int128 0x00000000000000007fffffffffffffff
+ 0x00, 0x00, 0x00, 0x00, // (INT64_MAX)
+ 0x00, 0x7f, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff,
+ 0x14, 0x00, 0x00, 0x00, // int128 0x00000000000000008000000000000000
+ 0x00, 0x00, 0x00, 0x00, // (INT64_MAX + 1)
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x14, 0xff, 0xff, 0xff, // int128 0xffffffffffffffff8000000000000000
+ 0xff, 0xff, 0xff, 0xff, // (INT64_MIN)
+ 0xff, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x14, 0xff, 0xff, 0xff, // int128 0xffffffffffffffff7fffffffffffffff
+ 0xff, 0xff, 0xff, 0xff, // (INT64_MIN - 1)
+ 0xff, 0x7f, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff,
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t nil;
+ intmax_t value;
+
+ /*
+ * sdp_get_int expects any INT type, advancing test if successful
+ */
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, 0);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, INT8_MAX);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, INT8_MIN);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, 0x0102);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, INT16_MAX);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, INT16_MIN);
+
+ ATF_REQUIRE_EQ(sdp_get_int(&test, &value), false); /* not int */
+ ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, 0x01020304);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, INT32_MAX);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, INT32_MIN);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, 0x0102030405060708);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, INT64_MAX);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, INT64_MIN);
+
+ /*
+ * expected failure is that we cannot decode INT128 values larger than INT64
+ */
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, 0);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, INT64_MAX);
+
+ ATF_REQUIRE_EQ(sdp_get_int(&test, &value), false); /* overflow */
+ ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_INT128);
+
+ ATF_REQUIRE(sdp_get_int(&test, &value));
+ ATF_CHECK_EQ(value, INT64_MIN);
+
+ ATF_REQUIRE_EQ(sdp_get_int(&test, &value), false); /* underflow */
+ ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_INT128);
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TC(check_sdp_get_seq);
+
+ATF_TC_HEAD(check_sdp_get_seq, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_get_seq results");
+}
+
+ATF_TC_BODY(check_sdp_get_seq, tc)
+{
+ uint8_t data[] = {
+ 0x35, 0x00, // seq8(0)
+ 0x00, // nil
+ 0x36, 0x00, 0x00, // seq16(0)
+ 0x37, 0x00, 0x00, 0x00, // seq32(0)
+ 0x00,
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t value;
+
+ /*
+ * sdp_get_seq expects a SEQ type
+ * advancing test if successful
+ */
+ ATF_REQUIRE(sdp_get_seq(&test, &value));
+ ATF_CHECK_EQ(value.next, value.end);
+
+ ATF_REQUIRE_EQ(sdp_get_seq(&test, &value), false); /* not seq */
+ ATF_REQUIRE(sdp_get_data(&test, &value)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_NIL);
+
+ ATF_REQUIRE(sdp_get_seq(&test, &value));
+ ATF_CHECK_EQ(value.next, value.end);
+
+ ATF_REQUIRE(sdp_get_seq(&test, &value));
+ ATF_CHECK_EQ(value.next, value.end);
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TC(check_sdp_get_alt);
+
+ATF_TC_HEAD(check_sdp_get_alt, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_get_alt results");
+}
+
+ATF_TC_BODY(check_sdp_get_alt, tc)
+{
+ uint8_t data[] = {
+ 0x3d, 0x00, // alt8(0)
+ 0x00, // nil
+ 0x3e, 0x00, 0x00, // alt16(0)
+ 0x3f, 0x00, 0x00, 0x00, // alt32(0)
+ 0x00,
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t value;
+
+ /*
+ * sdp_get_alt expects a ALT type
+ * advancing test if successful
+ */
+ ATF_REQUIRE(sdp_get_alt(&test, &value));
+ ATF_CHECK_EQ(value.next, value.end);
+
+ ATF_REQUIRE_EQ(sdp_get_alt(&test, &value), false); /* not alt */
+ ATF_REQUIRE(sdp_get_data(&test, &value)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&value), SDP_DATA_NIL);
+
+ ATF_REQUIRE(sdp_get_alt(&test, &value));
+ ATF_CHECK_EQ(value.next, value.end);
+
+ ATF_REQUIRE(sdp_get_alt(&test, &value));
+ ATF_CHECK_EQ(value.next, value.end);
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TC(check_sdp_get_str);
+
+ATF_TC_HEAD(check_sdp_get_str, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_get_str results");
+}
+
+ATF_TC_BODY(check_sdp_get_str, tc)
+{
+ uint8_t data[] = {
+ 0x25, 0x04, 0x53, 0x54, // str8(4) "STR8"
+ 0x52, 0x38,
+ 0x00, // nil
+ 0x26, 0x00, 0x05, 0x53, // str16(5) "STR16"
+ 0x54, 0x52, 0x31, 0x36,
+ 0x27, 0x00, 0x00, 0x00, // str32(5) "STR32"
+ 0x05, 0x53, 0x54, 0x52,
+ 0x33, 0x32,
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t nil;
+ char *str;
+ size_t len;
+
+ /*
+ * sdp_get_str expects a STR type
+ * advancing test if successful
+ */
+ ATF_REQUIRE(sdp_get_str(&test, &str, &len));
+ ATF_CHECK(len == 4 && strncmp(str, "STR8", 4) == 0);
+
+ ATF_REQUIRE_EQ(sdp_get_str(&test, &str, &len), false); /* not str */
+ ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL);
+
+ ATF_REQUIRE(sdp_get_str(&test, &str, &len));
+ ATF_CHECK(len == 5 && strncmp(str, "STR16", 5) == 0);
+
+ ATF_REQUIRE(sdp_get_str(&test, &str, &len));
+ ATF_CHECK(len == 5 && strncmp(str, "STR32", 5) == 0);
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TC(check_sdp_get_url);
+
+ATF_TC_HEAD(check_sdp_get_url, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_get_url results");
+}
+
+ATF_TC_BODY(check_sdp_get_url, tc)
+{
+ uint8_t data[] = {
+ 0x45, 0x04, 0x55, 0x52, // url8(4) "URL8"
+ 0x4c, 0x38,
+ 0x00, // nil
+ 0x46, 0x00, 0x05, 0x55, // url16(5) "URL16"
+ 0x52, 0x4c, 0x31, 0x36,
+ 0x47, 0x00, 0x00, 0x00, // url32(5) "URL32"
+ 0x05, 0x55, 0x52, 0x4c,
+ 0x33, 0x32,
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t nil;
+ char *url;
+ size_t len;
+
+ /*
+ * sdp_get_url expects a URL type
+ * advancing test if successful
+ */
+ ATF_REQUIRE(sdp_get_url(&test, &url, &len));
+ ATF_CHECK(len == 4 && strncmp(url, "URL8", 4) == 0);
+
+ ATF_REQUIRE_EQ(sdp_get_url(&test, &url, &len), false); /* not url */
+ ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL);
+
+ ATF_REQUIRE(sdp_get_url(&test, &url, &len));
+ ATF_CHECK(len == 5 && strncmp(url, "URL16", 5) == 0);
+
+ ATF_REQUIRE(sdp_get_url(&test, &url, &len));
+ ATF_CHECK(len == 5 && strncmp(url, "URL32", 5) == 0);
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, check_sdp_get_data);
+ ATF_TP_ADD_TC(tp, check_sdp_get_attr);
+ ATF_TP_ADD_TC(tp, check_sdp_get_uuid);
+ ATF_TP_ADD_TC(tp, check_sdp_get_bool);
+ ATF_TP_ADD_TC(tp, check_sdp_get_uint);
+ ATF_TP_ADD_TC(tp, check_sdp_get_int);
+ ATF_TP_ADD_TC(tp, check_sdp_get_seq);
+ ATF_TP_ADD_TC(tp, check_sdp_get_alt);
+ ATF_TP_ADD_TC(tp, check_sdp_get_str);
+ ATF_TP_ADD_TC(tp, check_sdp_get_url);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_match.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_match.c
new file mode 100644
index 0000000..54a5bd5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_match.c
@@ -0,0 +1,87 @@
+/* $NetBSD: t_sdp_match.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Iain Hibbert.
+ *
+ * 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 <sdp.h>
+
+ATF_TC(check_sdp_match_uuid16);
+
+ATF_TC_HEAD(check_sdp_match_uuid16, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_match_uuid16 results");
+}
+
+ATF_TC_BODY(check_sdp_match_uuid16, tc)
+{
+ uint8_t data[] = {
+ 0x19, 0x11, 0x11, // uuid16 0x1111
+ 0x00, // nil
+ 0x19, 0x12, 0x34, // uuid16 0x1234
+ 0x1a, 0x00, 0x00, 0x34, // uuid32 0x00003456
+ 0x56,
+ 0x1c, 0x00, 0x00, 0x43, // uuid128 00004321-0000-1000-8000-00805f9b34fb
+ 0x21, 0x00, 0x00, 0x10,
+ 0x00, 0x80, 0x00, 0x00,
+ 0x80, 0x5f, 0x9b, 0x34,
+ 0xfb,
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t nil;
+
+ /*
+ * sdp_match_uuid16 advances if the UUID matches the 16-bit short alias given
+ */
+
+ ATF_REQUIRE_EQ(sdp_match_uuid16(&test, 0x1100), false); /* mismatch */
+ ATF_REQUIRE(sdp_match_uuid16(&test, 0x1111));
+
+ ATF_REQUIRE_EQ(sdp_match_uuid16(&test, 0x1234), false); /* not uuid */
+ ATF_REQUIRE(sdp_get_data(&test, &nil)); /* (skip) */
+ ATF_CHECK_EQ(sdp_data_type(&nil), SDP_DATA_NIL);
+ ATF_REQUIRE(sdp_match_uuid16(&test, 0x1234));
+
+ ATF_REQUIRE(sdp_match_uuid16(&test, 0x3456));
+
+ ATF_REQUIRE_EQ(sdp_match_uuid16(&test, 0x1234), false); /* mismatch */
+ ATF_REQUIRE(sdp_match_uuid16(&test, 0x4321));
+
+ ATF_CHECK_EQ(test.next, test.end);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, check_sdp_match_uuid16);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_put.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_put.c
new file mode 100644
index 0000000..fff4119
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_put.c
@@ -0,0 +1,875 @@
+/* $NetBSD: t_sdp_put.c,v 1.3 2011/04/16 07:32:27 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Iain Hibbert.
+ *
+ * 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 <limits.h>
+#include <sdp.h>
+#include <string.h>
+
+ATF_TC(check_sdp_put_data);
+
+ATF_TC_HEAD(check_sdp_put_data, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_data results");
+}
+
+ATF_TC_BODY(check_sdp_put_data, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+ uint8_t data[] = {
+ 0x35, 0x05, // seq8(5)
+ 0x08, 0x00, // uint8 0x00
+ 0x09, 0x12, 0x34, // uint16 0x1234
+ };
+ sdp_data_t value = { data, data + sizeof(data) };
+
+ ATF_REQUIRE(sdp_put_data(&test, &value));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x35, 0x05, // seq8(5)
+ 0x08, 0x00, // uint8 0x00
+ 0x09, 0x12, 0x34, // uint16 0x1234
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_attr);
+
+ATF_TC_HEAD(check_sdp_put_attr, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_attr results");
+}
+
+ATF_TC_BODY(check_sdp_put_attr, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+ uint8_t data[] = {
+ 0x00, // nil
+ 0x19, 0x33, 0x44, // uuid16 0x3344
+ };
+ sdp_data_t value = { data, data + sizeof(data) };
+
+ ATF_REQUIRE_EQ(sdp_put_attr(&test, 0xabcd, &value), false);
+ value.next += 1; // skip "nil"
+ ATF_REQUIRE(sdp_put_attr(&test, 0x1337, &value));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x09, 0x13, 0x37, // uint16 0x1337
+ 0x19, 0x33, 0x44, // uuid16 0x3344
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_uuid);
+
+ATF_TC_HEAD(check_sdp_put_uuid, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid results");
+}
+
+ATF_TC_BODY(check_sdp_put_uuid, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+ const uuid_t u16 = {
+ 0x00001234,
+ 0x0000,
+ 0x1000,
+ 0x80,
+ 0x00,
+ { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb }
+ };
+ const uuid_t u32 = {
+ 0x12345678,
+ 0x0000,
+ 0x1000,
+ 0x80,
+ 0x00,
+ { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb }
+ };
+ const uuid_t u128 = {
+ 0x00112233,
+ 0x4444,
+ 0x5555,
+ 0x66,
+ 0x77,
+ { 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd }
+ };
+
+ ATF_REQUIRE(sdp_put_uuid(&test, &u16));
+ ATF_REQUIRE(sdp_put_uuid(&test, &u32));
+ ATF_REQUIRE(sdp_put_uuid(&test, &u128));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x19, 0x12, 0x34, // uuid16 0x1234
+ 0x1a, 0x12, 0x34, 0x56, // uuid32 0x12345678
+ 0x78,
+ 0x1c, 0x00, 0x11, 0x22, // uuid128 00112233-4444-5555-6677-8899aabbccdd
+ 0x33, 0x44, 0x44, 0x55,
+ 0x55, 0x66, 0x77, 0x88,
+ 0x99, 0xaa, 0xbb, 0xcc,
+ 0xdd,
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_uuid16);
+
+ATF_TC_HEAD(check_sdp_put_uuid16, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid16 results");
+}
+
+ATF_TC_BODY(check_sdp_put_uuid16, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_uuid16(&test, 0x4567));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x19, 0x45, 0x67, // uuid16 0x4567
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_uuid32);
+
+ATF_TC_HEAD(check_sdp_put_uuid32, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid32 results");
+}
+
+ATF_TC_BODY(check_sdp_put_uuid32, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_uuid32(&test, 0xabcdef00));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x1a, 0xab, 0xcd, 0xef, // uuid32 0xabcdef00
+ 0x00,
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_uuid128);
+
+ATF_TC_HEAD(check_sdp_put_uuid128, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_uuid128 results");
+}
+
+ATF_TC_BODY(check_sdp_put_uuid128, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+ uuid_t value = {
+ 0x00000100,
+ 0x0000,
+ 0x1000,
+ 0x80,
+ 0x00,
+ { 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb }
+ };
+
+ ATF_REQUIRE(sdp_put_uuid128(&test, &value));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x1c, 0x00, 0x00, 0x01, // uuid128 0000100-0000-1000-8000-00805f9b34fb
+ 0x00, 0x00, 0x00, 0x10, // (L2CAP protocol)
+ 0x00, 0x80, 0x00, 0x00,
+ 0x80, 0x5f, 0x9b, 0x34,
+ 0xfb,
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_bool);
+
+ATF_TC_HEAD(check_sdp_put_bool, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_bool results");
+}
+
+ATF_TC_BODY(check_sdp_put_bool, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_bool(&test, true));
+ ATF_REQUIRE(sdp_put_bool(&test, false));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x28, 0x01, // bool true
+ 0x28, 0x00, // bool false
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_uint);
+
+ATF_TC_HEAD(check_sdp_put_uint, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint results");
+}
+
+ATF_TC_BODY(check_sdp_put_uint, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)0));
+ ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT8_MAX));
+ ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT8_MAX + 1));
+ ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT16_MAX));
+ ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT16_MAX + 1));
+ ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT32_MAX));
+ ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT32_MAX + 1));
+ ATF_REQUIRE(sdp_put_uint(&test, (uintmax_t)UINT64_MAX));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x08, 0x00, // uint8 0x00
+ 0x08, 0xff, // uint8 0xff
+ 0x09, 0x01, 0x00, // uint16 0x0100
+ 0x09, 0xff, 0xff, // uint16 0xffff
+ 0x0a, 0x00, 0x01, 0x00, // uint32 0x00010000
+ 0x00,
+ 0x0a, 0xff, 0xff, 0xff, // uint32 0xffffffff
+ 0xff,
+ 0x0b, 0x00, 0x00, 0x00, // uint64 0x0000000100000000
+ 0x01, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x0b, 0xff, 0xff, 0xff, // uint64 0xffffffffffffffff
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff,
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_uint8);
+
+ATF_TC_HEAD(check_sdp_put_uint8, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint8 results");
+}
+
+ATF_TC_BODY(check_sdp_put_uint8, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_uint8(&test, (uint8_t)0));
+ ATF_REQUIRE(sdp_put_uint8(&test, (uint8_t)UINT8_MAX));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x08, 0x00, // uint8 0x00
+ 0x08, 0xff, // uint8 0xff
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_uint16);
+
+ATF_TC_HEAD(check_sdp_put_uint16, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint16 results");
+}
+
+ATF_TC_BODY(check_sdp_put_uint16, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)0));
+ ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)UINT8_MAX));
+ ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)UINT16_MAX));
+ ATF_REQUIRE(sdp_put_uint16(&test, (uint16_t)0xabcd));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x09, 0x00, 0x00, // uint16 0x0000
+ 0x09, 0x00, 0xff, // uint16 0x00ff
+ 0x09, 0xff, 0xff, // uint16 0xffff
+ 0x09, 0xab, 0xcd, // uint16 0xabcd
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_uint32);
+
+ATF_TC_HEAD(check_sdp_put_uint32, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint32 results");
+}
+
+ATF_TC_BODY(check_sdp_put_uint32, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)0));
+ ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)UINT8_MAX));
+ ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)UINT16_MAX));
+ ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)UINT32_MAX));
+ ATF_REQUIRE(sdp_put_uint32(&test, (uint32_t)0xdeadbeef));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000000
+ 0x00,
+ 0x0a, 0x00, 0x00, 0x00, // uint32 0x000000ff
+ 0xff,
+ 0x0a, 0x00, 0x00, 0xff, // uint32 0x0000ffff
+ 0xff,
+ 0x0a, 0xff, 0xff, 0xff, // uint32 0xffffffff
+ 0xff,
+ 0x0a, 0xde, 0xad, 0xbe, // uint32 0xdeadbeef
+ 0xef,
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_uint64);
+
+ATF_TC_HEAD(check_sdp_put_uint64, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_uint64 results");
+}
+
+ATF_TC_BODY(check_sdp_put_uint64, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)0));
+ ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT8_MAX));
+ ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT16_MAX));
+ ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT32_MAX));
+ ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)UINT64_MAX));
+ ATF_REQUIRE(sdp_put_uint64(&test, (uint64_t)0xc0ffeecafec0ffee));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x0b, 0x00, 0x00, 0x00, // uint64 0x0000000000000000
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x0b, 0x00, 0x00, 0x00, // uint64 0x00000000000000ff
+ 0x00, 0x00, 0x00, 0x00,
+ 0xff,
+ 0x0b, 0x00, 0x00, 0x00, // uint64 0x000000000000ffff
+ 0x00, 0x00, 0x00, 0xff,
+ 0xff,
+ 0x0b, 0x00, 0x00, 0x00, // uint64 0x00000000ffffffff
+ 0x00, 0xff, 0xff, 0xff,
+ 0xff,
+ 0x0b, 0xff, 0xff, 0xff, // uint64 0xffffffffffffffff
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff,
+ 0x0b, 0xc0, 0xff, 0xee, // uint64 0xc0ffeecafec0ffee
+ 0xca, 0xfe, 0xc0, 0xff,
+ 0xee,
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_int);
+
+ATF_TC_HEAD(check_sdp_put_int, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_int results");
+}
+
+ATF_TC_BODY(check_sdp_put_int, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)0));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MIN));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MAX));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MIN - 1));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT8_MAX + 1));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MIN));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MAX));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MIN - 1));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT16_MAX + 1));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MIN));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MAX));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MIN - 1));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT32_MAX + 1));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT64_MIN));
+ ATF_REQUIRE(sdp_put_int(&test, (intmax_t)INT64_MAX));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x10, 0x00, // int8 0
+ 0x10, 0x80, // int8 -128
+ 0x10, 0x7f, // int8 127
+ 0x11, 0xff, 0x7f, // int16 -129
+ 0x11, 0x00, 0x80, // int16 128
+ 0x11, 0x80, 0x00, // int16 -32768
+ 0x11, 0x7f, 0xff, // int16 32767
+ 0x12, 0xff, 0xff, 0x7f, // int32 -32769
+ 0xff,
+ 0x12, 0x00, 0x00, 0x80, // int32 32768
+ 0x00,
+ 0x12, 0x80, 0x00, 0x00, // int32 -2147483648
+ 0x00,
+ 0x12, 0x7f, 0xff, 0xff, // int32 2147483647
+ 0xff,
+ 0x13, 0xff, 0xff, 0xff, // int64 -2147483649
+ 0xff, 0x7f, 0xff, 0xff,
+ 0xff,
+ 0x13, 0x00, 0x00, 0x00, // int64 2147483648
+ 0x00, 0x80, 0x00, 0x00,
+ 0x00,
+ 0x13, 0x80, 0x00, 0x00, // int64 -9223372036854775808
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x13, 0x7f, 0xff, 0xff, // int64 9223372036854775807
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff,
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_int8);
+
+ATF_TC_HEAD(check_sdp_put_int8, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_int8 results");
+}
+
+ATF_TC_BODY(check_sdp_put_int8, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_int8(&test, (int8_t)0));
+ ATF_REQUIRE(sdp_put_int8(&test, (int8_t)INT8_MIN));
+ ATF_REQUIRE(sdp_put_int8(&test, (int8_t)INT8_MAX));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x10, 0x00, // int8 0
+ 0x10, 0x80, // int8 -128
+ 0x10, 0x7f, // int8 127
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_int16);
+
+ATF_TC_HEAD(check_sdp_put_int16, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_int16 results");
+}
+
+ATF_TC_BODY(check_sdp_put_int16, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_int16(&test, (int16_t)0));
+ ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT8_MIN));
+ ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT8_MAX));
+ ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT16_MIN));
+ ATF_REQUIRE(sdp_put_int16(&test, (int16_t)INT16_MAX));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x11, 0x00, 0x00, // int16 0
+ 0x11, 0xff, 0x80, // int16 -128
+ 0x11, 0x00, 0x7f, // int16 127
+ 0x11, 0x80, 0x00, // int16 -32768
+ 0x11, 0x7f, 0xff, // int16 32767
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_int32);
+
+ATF_TC_HEAD(check_sdp_put_int32, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_int32 results");
+}
+
+ATF_TC_BODY(check_sdp_put_int32, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_int32(&test, (int32_t)0));
+ ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT8_MIN));
+ ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT8_MAX));
+ ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT16_MIN));
+ ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT16_MAX));
+ ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT32_MIN));
+ ATF_REQUIRE(sdp_put_int32(&test, (int32_t)INT32_MAX));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x12, 0x00, 0x00, 0x00, // int32 0
+ 0x00,
+ 0x12, 0xff, 0xff, 0xff, // int32 -128
+ 0x80,
+ 0x12, 0x00, 0x00, 0x00, // int32 127
+ 0x7f,
+ 0x12, 0xff, 0xff, 0x80, // int32 -32768
+ 0x00,
+ 0x12, 0x00, 0x00, 0x7f, // int32 32767
+ 0xff,
+ 0x12, 0x80, 0x00, 0x00, // int32 -2147483648
+ 0x00,
+ 0x12, 0x7f, 0xff, 0xff, // int32 2147483647
+ 0xff,
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_int64);
+
+ATF_TC_HEAD(check_sdp_put_int64, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_int64 results");
+}
+
+ATF_TC_BODY(check_sdp_put_int64, tc)
+{
+ uint8_t buf[256];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_int64(&test, (int64_t)0));
+ ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT8_MIN));
+ ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT8_MAX));
+ ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT16_MIN));
+ ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT16_MAX));
+ ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT32_MIN));
+ ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT32_MAX));
+ ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT64_MIN));
+ ATF_REQUIRE(sdp_put_int64(&test, (int64_t)INT64_MAX));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x13, 0x00, 0x00, 0x00, // int64 0
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x13, 0xff, 0xff, 0xff, // int64 -128
+ 0xff, 0xff, 0xff, 0xff,
+ 0x80,
+ 0x13, 0x00, 0x00, 0x00, // int64 127
+ 0x00, 0x00, 0x00, 0x00,
+ 0x7f,
+ 0x13, 0xff, 0xff, 0xff, // int64 -32768
+ 0xff, 0xff, 0xff, 0x80,
+ 0x00,
+ 0x13, 0x00, 0x00, 0x00, // int64 32767
+ 0x00, 0x00, 0x00, 0x7f,
+ 0xff,
+ 0x13, 0xff, 0xff, 0xff, // int64 -2147483648
+ 0xff, 0x80, 0x00, 0x00,
+ 0x00,
+ 0x13, 0x00, 0x00, 0x00, // int64 2147483647
+ 0x00, 0x7f, 0xff, 0xff,
+ 0xff,
+ 0x13, 0x80, 0x00, 0x00, // int64 -9223372036854775808
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x13, 0x7f, 0xff, 0xff, // int64 9223372036854775807
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff,
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_seq);
+
+ATF_TC_HEAD(check_sdp_put_seq, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_seq results");
+}
+
+ATF_TC_BODY(check_sdp_put_seq, tc)
+{
+ uint8_t buf[512];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)0));
+ ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)UINT8_MAX));
+ ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)UINT8_MAX + 1));
+ ATF_REQUIRE(sdp_put_seq(&test, (ssize_t)-1));
+ ATF_CHECK_EQ(sdp_put_seq(&test, (ssize_t)UINT16_MAX), false); /* no room */
+ ATF_CHECK_EQ(sdp_put_seq(&test, (ssize_t)SSIZE_MAX), false); /* no room */
+ test.end = test.next;
+ test.next = buf;
+
+ /* (not a valid element list) */
+ const uint8_t expect[] = {
+ 0x35, 0x00, // seq8(0)
+ 0x35, 0xff, // seq8(255)
+ 0x36, 0x01, 0x00, // seq16(256)
+ 0x36, 0x01, 0xf6, // seq16(502) <- sizeof(buf) - 7 - 3
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_alt);
+
+ATF_TC_HEAD(check_sdp_put_alt, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_alt results");
+}
+
+ATF_TC_BODY(check_sdp_put_alt, tc)
+{
+ uint8_t buf[512];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)0));
+ ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)UINT8_MAX));
+ ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)UINT8_MAX + 1));
+ ATF_REQUIRE(sdp_put_alt(&test, (ssize_t)-1));
+ ATF_CHECK_EQ(sdp_put_alt(&test, (ssize_t)UINT16_MAX), false); /* no room */
+ ATF_CHECK_EQ(sdp_put_alt(&test, (ssize_t)SSIZE_MAX), false); /* no room */
+ test.end = test.next;
+ test.next = buf;
+
+ /* (not a valid element list) */
+ const uint8_t expect[] = {
+ 0x3d, 0x00, // alt8(0)
+ 0x3d, 0xff, // alt8(255)
+ 0x3e, 0x01, 0x00, // alt16(256)
+ 0x3e, 0x01, 0xf6, // alt16(502) <- sizeof(buf) - 7 - 3
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_str);
+
+ATF_TC_HEAD(check_sdp_put_str, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_str results");
+}
+
+ATF_TC_BODY(check_sdp_put_str, tc)
+{
+ uint8_t buf[512];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ /*
+ * this does not test str16 or str32, but that is
+ * handled by the same code as sdp_put_seq above..
+ */
+
+ ATF_REQUIRE(sdp_put_str(&test, "Hello World!", 5));
+ ATF_REQUIRE(sdp_put_str(&test, "Hello\0World", 11));
+ ATF_REQUIRE(sdp_put_str(&test, "Hello World!", -1));
+ ATF_REQUIRE(sdp_put_str(&test, "Hello\0World", -1));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x25, 0x05, 0x48, 0x65, // str8 "Hello"
+ 0x6c, 0x6c, 0x6f,
+ 0x25, 0x0b, 0x48, 0x65, // str8 "Hello\0World"
+ 0x6c, 0x6c, 0x6f, 0x00,
+ 0x57, 0x6f, 0x72, 0x6c,
+ 0x64,
+ 0x25, 0x0c, 0x48, 0x65, // str8 "Hello World!"
+ 0x6c, 0x6c, 0x6f, 0x20,
+ 0x57, 0x6f, 0x72, 0x6c,
+ 0x64, 0x21,
+ 0x25, 0x05, 0x48, 0x65, // str8 "Hello"
+ 0x6c, 0x6c, 0x6f,
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_put_url);
+
+ATF_TC_HEAD(check_sdp_put_url, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_put_url results");
+}
+
+ATF_TC_BODY(check_sdp_put_url, tc)
+{
+ uint8_t buf[512];
+ sdp_data_t test = { buf, buf + sizeof(buf) };
+
+ /*
+ * this does not test url16 or url32, but that is
+ * handled by the same code as sdp_put_seq above..
+ */
+
+ ATF_REQUIRE(sdp_put_url(&test, "http://www.netbsd.org/", 21));
+ ATF_REQUIRE(sdp_put_url(&test, "http://www.netbsd.org/", -1));
+ test.end = test.next;
+ test.next = buf;
+
+ const uint8_t expect[] = {
+ 0x45, 0x15, 0x68, 0x74, // url8 "http://www.netbsd.org"
+ 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x77, 0x77, 0x77,
+ 0x2e, 0x6e, 0x65, 0x74,
+ 0x62, 0x73, 0x64, 0x2e,
+ 0x6f, 0x72, 0x67,
+ 0x45, 0x16, 0x68, 0x74, // url8 "http://www.netbsd.org/"
+ 0x74, 0x70, 0x3a, 0x2f,
+ 0x2f, 0x77, 0x77, 0x77,
+ 0x2e, 0x6e, 0x65, 0x74,
+ 0x62, 0x73, 0x64, 0x2e,
+ 0x6f, 0x72, 0x67, 0x2f,
+ };
+
+ ATF_REQUIRE_EQ(test.end - test.next, sizeof(expect));
+ ATF_CHECK(memcmp(expect, test.next, sizeof(expect)) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, check_sdp_put_data);
+ ATF_TP_ADD_TC(tp, check_sdp_put_attr);
+ ATF_TP_ADD_TC(tp, check_sdp_put_uuid);
+ ATF_TP_ADD_TC(tp, check_sdp_put_uuid16);
+ ATF_TP_ADD_TC(tp, check_sdp_put_uuid32);
+ ATF_TP_ADD_TC(tp, check_sdp_put_uuid128);
+ ATF_TP_ADD_TC(tp, check_sdp_put_bool);
+ ATF_TP_ADD_TC(tp, check_sdp_put_uint);
+ ATF_TP_ADD_TC(tp, check_sdp_put_uint8);
+ ATF_TP_ADD_TC(tp, check_sdp_put_uint16);
+ ATF_TP_ADD_TC(tp, check_sdp_put_uint32);
+ ATF_TP_ADD_TC(tp, check_sdp_put_uint64);
+ ATF_TP_ADD_TC(tp, check_sdp_put_int);
+ ATF_TP_ADD_TC(tp, check_sdp_put_int8);
+ ATF_TP_ADD_TC(tp, check_sdp_put_int16);
+ ATF_TP_ADD_TC(tp, check_sdp_put_int32);
+ ATF_TP_ADD_TC(tp, check_sdp_put_int64);
+ ATF_TP_ADD_TC(tp, check_sdp_put_seq);
+ ATF_TP_ADD_TC(tp, check_sdp_put_alt);
+ ATF_TP_ADD_TC(tp, check_sdp_put_str);
+ ATF_TP_ADD_TC(tp, check_sdp_put_url);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libbluetooth/t_sdp_set.c b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_set.c
new file mode 100644
index 0000000..be5d953
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libbluetooth/t_sdp_set.c
@@ -0,0 +1,359 @@
+/* $NetBSD: t_sdp_set.c,v 1.2 2011/04/07 08:29:50 plunky Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Iain Hibbert.
+ *
+ * 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 <limits.h>
+#include <sdp.h>
+#include <string.h>
+
+ATF_TC(check_sdp_set_bool);
+
+ATF_TC_HEAD(check_sdp_set_bool, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_set_bool results");
+}
+
+ATF_TC_BODY(check_sdp_set_bool, tc)
+{
+ uint8_t data[] = {
+ 0x28, 0x00, // bool false
+ 0x00, // nil
+ 0x28, // bool <invalid>
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t discard;
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_BOOL);
+ ATF_REQUIRE(sdp_set_bool(&test, true));
+ ATF_CHECK_EQ(test.next[1], 0x01);
+ ATF_REQUIRE(sdp_set_bool(&test, false));
+ ATF_CHECK_EQ(test.next[1], 0x00);
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_NIL);
+ ATF_CHECK_EQ(sdp_set_bool(&test, true), false); /* not bool */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_BOOL);
+ ATF_CHECK_EQ(sdp_set_bool(&test, true), false); /* no value */
+}
+
+ATF_TC(check_sdp_set_uint);
+
+ATF_TC_HEAD(check_sdp_set_uint, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_set_uint results");
+}
+
+ATF_TC_BODY(check_sdp_set_uint, tc)
+{
+ uint8_t data[] = {
+ 0x08, 0x00, // uint8 0x00
+ 0x00, // nil
+ 0x09, 0x00, 0x00, // uint16 0x0000
+ 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000000
+ 0x00,
+ 0x0b, 0x00, 0x00, 0x00, // uint64 0x0000000000000000
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x0c, 0x00, 0x44, 0x00, // uint128 0x00440044004400440044004400440044
+ 0x44, 0x00, 0x44, 0x00,
+ 0x44, 0x00, 0x44, 0x00,
+ 0x44, 0x00, 0x44, 0x00,
+ 0x00,
+ 0x09, 0x00, // uint16 <invalid>
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t discard;
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT8);
+ ATF_REQUIRE(sdp_set_uint(&test, 0x44));
+ ATF_CHECK_EQ(sdp_set_uint(&test, UINT8_MAX + 1), false); /* too big */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_NIL);
+ ATF_CHECK_EQ(sdp_set_uint(&test, 0x00), false); /* not uint */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT16);
+ ATF_REQUIRE(sdp_set_uint(&test, 0xabcd));
+ ATF_CHECK_EQ(sdp_set_uint(&test, UINT16_MAX + 1), false); /* too big */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT32);
+ ATF_REQUIRE(sdp_set_uint(&test, 0xdeadbeef));
+ ATF_CHECK_EQ(sdp_set_uint(&test, (uintmax_t)UINT32_MAX + 1), false); /* too big */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT64);
+ ATF_REQUIRE(sdp_set_uint(&test, 0xc0ffeecafec0ffee));
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT128);
+ ATF_REQUIRE(sdp_set_uint(&test, 0xabcdef0123456789));
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_UINT16);
+ ATF_CHECK_EQ(sdp_set_uint(&test, 0x3344), false); /* no value */
+
+ const uint8_t expect[] = {
+ 0x08, 0x44, // uint8 0x44
+ 0x00, // nil
+ 0x09, 0xab, 0xcd, // uint16 0xabcd
+ 0x0a, 0xde, 0xad, 0xbe, // uint32 0xdeadbeef
+ 0xef,
+ 0x0b, 0xc0, 0xff, 0xee, // uint64 0xc0ffeecafec0ffee
+ 0xca, 0xfe, 0xc0, 0xff,
+ 0xee,
+ 0x0c, 0x00, 0x00, 0x00, // uint128 0x0000000000000000abcdef0123456789
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xab, 0xcd, 0xef,
+ 0x01, 0x23, 0x45, 0x67,
+ 0x89,
+ 0x09, 0x00, // uint16 <invalid>
+ };
+
+ ATF_REQUIRE_EQ(sizeof(data), sizeof(expect));
+ ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_set_int);
+
+ATF_TC_HEAD(check_sdp_set_int, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_set_int results");
+}
+
+ATF_TC_BODY(check_sdp_set_int, tc)
+{
+ uint8_t data[] = {
+ 0x10, 0x00, // int8 0
+ 0x00, // nil
+ 0x11, 0x00, 0x00, // int16 0
+ 0x12, 0x00, 0x00, 0x00, // int32 0
+ 0x00,
+ 0x13, 0x00, 0x00, 0x00, // int64 0
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00,
+ 0x14, 0x00, 0x44, 0x00, // int128 0x00440044004400440044004400440044
+ 0x44, 0x00, 0x44, 0x00,
+ 0x44, 0x00, 0x44, 0x00,
+ 0x44, 0x00, 0x44, 0x00,
+ 0x00,
+ 0x11, 0x00, // int16 <invalid>
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t discard;
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT8);
+ ATF_REQUIRE(sdp_set_int(&test, -1));
+ ATF_CHECK_EQ(sdp_set_int(&test, INT8_MAX + 1), false); /* too big */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_NIL);
+ ATF_CHECK_EQ(sdp_set_int(&test, 33), false); /* not int */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16);
+ ATF_REQUIRE(sdp_set_int(&test, 789));
+ ATF_CHECK_EQ(sdp_set_int(&test, INT16_MIN - 1), false); /* too big */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT32);
+ ATF_REQUIRE(sdp_set_int(&test, -4567));
+ ATF_CHECK_EQ(sdp_set_int(&test, (intmax_t)INT32_MAX + 1), false); /* too big */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT64);
+ ATF_REQUIRE(sdp_set_int(&test, -3483738234));
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT128);
+ ATF_REQUIRE(sdp_set_int(&test, 3423489463464));
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16);
+ ATF_CHECK_EQ(sdp_set_int(&test, 1234), false); /* no value */
+
+ const uint8_t expect[] = {
+ 0x10, 0xff, // int8 -1
+ 0x00, // nil
+ 0x11, 0x03, 0x15, // int16 789
+ 0x12, 0xff, 0xff, 0xee, // int32 -4567
+ 0x29,
+ 0x13, 0xff, 0xff, 0xff, // int64 -3483738234
+ 0xff, 0x30, 0x5a, 0x5f,
+ 0x86,
+ 0x14, 0x00, 0x00, 0x00, // int128 3423489463464
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03,
+ 0x1d, 0x17, 0xdf, 0x94,
+ 0xa8,
+ 0x11, 0x00, // int16 <invalid>
+ };
+
+ ATF_REQUIRE_EQ(sizeof(data), sizeof(expect));
+ ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_set_seq);
+
+ATF_TC_HEAD(check_sdp_set_seq, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_set_seq results");
+}
+
+ATF_TC_BODY(check_sdp_set_seq, tc)
+{
+ uint8_t data[] = {
+ 0x35, 0x03, // seq8(3)
+ 0x11, 0xff, 0xff, // int16 -1
+ 0x36, 0x01, 0x00, // seq16(256)
+ 0x09, 0xff, 0xff, // uint16 0xffff
+ 0x37, 0x01, 0x02, 0x03, // seq32(16909060)
+ 0x04,
+ 0x36, 0x00, // seq16(<invalid>)
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t discard;
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ8);
+ ATF_REQUIRE(sdp_set_seq(&test, 0));
+ ATF_CHECK_EQ(sdp_set_seq(&test, UINT8_MAX), false); /* data too big */
+ ATF_CHECK_EQ(sdp_set_seq(&test, UINT16_MAX), false); /* size too big */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16);
+ ATF_CHECK_EQ(sdp_set_seq(&test, 33), false); /* not seq */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ16);
+ ATF_REQUIRE(sdp_set_seq(&test, 3));
+ ATF_CHECK_EQ(sdp_set_seq(&test, SSIZE_MAX), false); /* size too big */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ32);
+ ATF_REQUIRE(sdp_set_seq(&test, 0));
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_SEQ16);
+ ATF_CHECK_EQ(sdp_set_seq(&test, 22), false); /* no size */
+
+ const uint8_t expect[] = {
+ 0x35, 0x00, // seq8(0)
+ 0x11, 0xff, 0xff, // int16 -1
+ 0x36, 0x00, 0x03, // seq16(3)
+ 0x09, 0xff, 0xff, // uint16 0xffff
+ 0x37, 0x00, 0x00, 0x00, // seq32(0)
+ 0x00,
+ 0x36, 0x00, // seq16(<invalid>)
+ };
+
+ ATF_REQUIRE_EQ(sizeof(data), sizeof(expect));
+ ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0);
+}
+
+ATF_TC(check_sdp_set_alt);
+
+ATF_TC_HEAD(check_sdp_set_alt, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sdp_set_alt results");
+}
+
+ATF_TC_BODY(check_sdp_set_alt, tc)
+{
+ uint8_t data[] = {
+ 0x3d, 0x06, // alt8(6)
+ 0x11, 0xff, 0xff, // int16 -1
+ 0x3e, 0xff, 0xff, // alt16(65535)
+ 0x3f, 0x01, 0x02, 0x03, // alt32(16909060)
+ 0x04,
+ 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000003
+ 0x03,
+ 0x3e, 0x00, // alt16(<invalid>)
+ };
+ sdp_data_t test = { data, data + sizeof(data) };
+ sdp_data_t discard;
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_ALT8);
+ ATF_REQUIRE(sdp_set_alt(&test, 0));
+ ATF_CHECK_EQ(sdp_set_alt(&test, UINT8_MAX), false); /* data too big */
+ ATF_CHECK_EQ(sdp_set_alt(&test, UINT16_MAX), false); /* size too big */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_INT16);
+ ATF_CHECK_EQ(sdp_set_alt(&test, 27), false); /* not alt */
+ ATF_REQUIRE(sdp_get_data(&test, &discard));
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_ALT16);
+ ATF_REQUIRE(sdp_set_alt(&test, 10));
+ ATF_CHECK_EQ(sdp_set_alt(&test, SSIZE_MAX), false); /* size too big */
+ ATF_REQUIRE(sdp_get_alt(&test, &discard));
+ ATF_CHECK_EQ(sdp_data_type(&discard), SDP_DATA_ALT32);
+ ATF_CHECK(sdp_set_alt(&discard, -1)); /* end of alt16 */
+ ATF_CHECK_EQ(sdp_set_alt(&discard, 6), false); /* data too big */
+
+ ATF_CHECK_EQ(sdp_data_type(&test), SDP_DATA_ALT16);
+ ATF_CHECK_EQ(sdp_set_alt(&test, 22), false); /* no size */
+
+ const uint8_t expect[] = {
+ 0x3d, 0x00, // alt8(0)
+ 0x11, 0xff, 0xff, // int16 -1
+ 0x3e, 0x00, 0x0a, // alt16(10)
+ 0x3f, 0x00, 0x00, 0x00, // alt32(5)
+ 0x05,
+ 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000003
+ 0x03,
+ 0x3e, 0x00, // alt16(<invalid>)
+ };
+
+ ATF_REQUIRE_EQ(sizeof(data), sizeof(expect));
+ ATF_CHECK(memcmp(expect, data, sizeof(expect)) == 0);
+}
+
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, check_sdp_set_bool);
+ ATF_TP_ADD_TC(tp, check_sdp_set_uint);
+ ATF_TP_ADD_TC(tp, check_sdp_set_int);
+ ATF_TP_ADD_TC(tp, check_sdp_set_seq);
+ ATF_TP_ADD_TC(tp, check_sdp_set_alt);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libbpfjit/t_bpfjit.c b/contrib/netbsd-tests/lib/libbpfjit/t_bpfjit.c
new file mode 100644
index 0000000..da67c1b3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libbpfjit/t_bpfjit.c
@@ -0,0 +1,3975 @@
+/* $NetBSD: t_bpfjit.c,v 1.6 2014/07/08 21:07:52 alnsn Exp $ */
+
+/*-
+ * Copyright (c) 2011-2012, 2014 Alexander Nasonov.
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_bpfjit.c,v 1.6 2014/07/08 21:07:52 alnsn Exp $");
+
+#include <atf-c.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <net/bpf.h>
+#include <net/bpfjit.h>
+
+static uint8_t deadbeef_at_5[16] = {
+ 0, 0xf1, 2, 0xf3, 4, 0xde, 0xad, 0xbe, 0xef, 0xff
+};
+
+static inline
+unsigned int jitcall(bpfjit_func_t fn,
+ const uint8_t *pkt, unsigned int wirelen, unsigned int buflen)
+{
+ bpf_args_t args;
+
+ args.pkt = pkt;
+ args.wirelen = wirelen;
+ args.buflen = buflen;
+
+ return fn(NULL, &args);
+}
+
+ATF_TC(libbpfjit_empty);
+ATF_TC_HEAD(libbpfjit_empty, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that JIT compilation of an empty bpf program fails");
+}
+
+ATF_TC_BODY(libbpfjit_empty, tc)
+{
+ struct bpf_insn dummy;
+
+ ATF_CHECK(bpfjit_generate_code(NULL, &dummy, 0) == NULL);
+}
+
+ATF_TC(libbpfjit_alu_add_k);
+ATF_TC_HEAD(libbpfjit_alu_add_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_K");
+}
+
+ATF_TC_BODY(libbpfjit_alu_add_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 3),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 2),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 5);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_sub_k);
+ATF_TC_HEAD(libbpfjit_alu_sub_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_K");
+}
+
+ATF_TC_BODY(libbpfjit_alu_sub_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 1),
+ BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, 2),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_mul_k);
+ATF_TC_HEAD(libbpfjit_alu_mul_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_K");
+}
+
+ATF_TC_BODY(libbpfjit_alu_mul_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
+ BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, 3),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0xfffffffd));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div0_k);
+ATF_TC_HEAD(libbpfjit_alu_div0_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div0_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ //ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div1_k);
+ATF_TC_HEAD(libbpfjit_alu_div1_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=1");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div1_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 7),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 1),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 7);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div2_k);
+ATF_TC_HEAD(libbpfjit_alu_div2_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=2");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div2_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 7),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 2),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 3);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div4_k);
+ATF_TC_HEAD(libbpfjit_alu_div4_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=4");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div4_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 4),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x3fffffff));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div10_k);
+ATF_TC_HEAD(libbpfjit_alu_div10_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div10_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484384));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div10000_k);
+ATF_TC_HEAD(libbpfjit_alu_div10000_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=10000");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div10000_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, 10000),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div7609801_k);
+ATF_TC_HEAD(libbpfjit_alu_div7609801_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=7609801");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div7609801_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(7609801)),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 564);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div80000000_k);
+ATF_TC_HEAD(libbpfjit_alu_div80000000_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_K with k=0x80000000");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div80000000_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffde)),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0x80000000)),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_and_k);
+ATF_TC_HEAD(libbpfjit_alu_and_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_AND+BPF_K");
+}
+
+ATF_TC_BODY(libbpfjit_alu_and_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdead),
+ BPF_STMT(BPF_ALU+BPF_AND+BPF_K, 0xbeef),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == (0xdead&0xbeef));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_or_k);
+ATF_TC_HEAD(libbpfjit_alu_or_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_OR+BPF_K");
+}
+
+ATF_TC_BODY(libbpfjit_alu_or_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000),
+ BPF_STMT(BPF_ALU+BPF_OR+BPF_K, 0x0000beef),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_lsh_k);
+ATF_TC_HEAD(libbpfjit_alu_lsh_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K");
+}
+
+ATF_TC_BODY(libbpfjit_alu_lsh_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
+ BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 16),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xbeef0000);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_lsh0_k);
+ATF_TC_HEAD(libbpfjit_alu_lsh0_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_K with k=0");
+}
+
+ATF_TC_BODY(libbpfjit_alu_lsh0_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
+ BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_rsh_k);
+ATF_TC_HEAD(libbpfjit_alu_rsh_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K");
+}
+
+ATF_TC_BODY(libbpfjit_alu_rsh_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
+ BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 16),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0x0000dead);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_rsh0_k);
+ATF_TC_HEAD(libbpfjit_alu_rsh0_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_K with k=0");
+}
+
+ATF_TC_BODY(libbpfjit_alu_rsh0_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
+ BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_modulo_k);
+ATF_TC_HEAD(libbpfjit_alu_modulo_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of modulo logic of BPF_ALU+BPF_K operations");
+}
+
+ATF_TC_BODY(libbpfjit_alu_modulo_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
+
+ /* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */
+ BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x0fffff77)),
+
+ /* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */
+ BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 1),
+
+ /* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xdddddddd)),
+
+ /* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */
+ BPF_STMT(BPF_ALU+BPF_SUB+BPF_K, UINT32_C(0xffffffff)),
+
+ /* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */
+ BPF_STMT(BPF_ALU+BPF_OR+BPF_K, UINT32_C(0x0000030c)),
+
+ /* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */
+ BPF_STMT(BPF_ALU+BPF_NEG, 0),
+
+ /* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */
+ BPF_STMT(BPF_ALU+BPF_AND+BPF_K, UINT32_C(0xffffff0f)),
+
+ /* F000009A,42218C74 >> 3 = 1E000013,48443180 */
+ /* 00000000,42218C74 >> 3 = 00000000,08443180 */
+ BPF_STMT(BPF_ALU+BPF_RSH+BPF_K, 3),
+
+ /* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */
+ BPF_STMT(BPF_ALU+BPF_MUL+BPF_K, UINT32_C(0x7fffff77)),
+
+ /* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */
+ /* 00000000,93818280 / DEAD = 00000000,0000A994 */
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_K, UINT32_C(0xdead)),
+
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) != UINT32_C(0x71cbbbc3));
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x0000a994));
+
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_add_x);
+ATF_TC_HEAD(libbpfjit_alu_add_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_ADD+BPF_X");
+}
+
+ATF_TC_BODY(libbpfjit_alu_add_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 3),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 5);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_sub_x);
+ATF_TC_HEAD(libbpfjit_alu_sub_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_SUB+BPF_X");
+}
+
+ATF_TC_BODY(libbpfjit_alu_sub_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 1),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
+ BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_mul_x);
+ATF_TC_HEAD(libbpfjit_alu_mul_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_MUL+BPF_X");
+}
+
+ATF_TC_BODY(libbpfjit_alu_mul_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
+ BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0xfffffffd));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div0_x);
+ATF_TC_HEAD(libbpfjit_alu_div0_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div0_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div1_x);
+ATF_TC_HEAD(libbpfjit_alu_div1_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=1");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div1_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 7),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 7);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div2_x);
+ATF_TC_HEAD(libbpfjit_alu_div2_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=2");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div2_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 7),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 3);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div4_x);
+ATF_TC_HEAD(libbpfjit_alu_div4_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=4");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div4_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0xffffffff)),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x3fffffff));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div10_x);
+ATF_TC_HEAD(libbpfjit_alu_div10_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div10_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484384));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div10000_x);
+ATF_TC_HEAD(libbpfjit_alu_div10000_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=10000");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div10000_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294843849)),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 10000),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(429484));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div7609801_x);
+ATF_TC_HEAD(libbpfjit_alu_div7609801_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=7609801");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div7609801_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(4294967295)),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(7609801)),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 564);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_div80000000_x);
+ATF_TC_HEAD(libbpfjit_alu_div80000000_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_DIV+BPF_X with X=0x80000000");
+}
+
+ATF_TC_BODY(libbpfjit_alu_div80000000_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX - 33),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0x80000000)),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_and_x);
+ATF_TC_HEAD(libbpfjit_alu_and_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_AND+BPF_X");
+}
+
+ATF_TC_BODY(libbpfjit_alu_and_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdead),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0xbeef),
+ BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == (0xdead&0xbeef));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_or_x);
+ATF_TC_HEAD(libbpfjit_alu_or_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_OR+BPF_X");
+}
+
+ATF_TC_BODY(libbpfjit_alu_or_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdead0000),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0x0000beef),
+ BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_lsh_x);
+ATF_TC_HEAD(libbpfjit_alu_lsh_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X");
+}
+
+ATF_TC_BODY(libbpfjit_alu_lsh_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16),
+ BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xbeef0000);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_lsh0_x);
+ATF_TC_HEAD(libbpfjit_alu_lsh0_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_LSH+BPF_X with k=0");
+}
+
+ATF_TC_BODY(libbpfjit_alu_lsh0_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
+ BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_rsh_x);
+ATF_TC_HEAD(libbpfjit_alu_rsh_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X");
+}
+
+ATF_TC_BODY(libbpfjit_alu_rsh_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 16),
+ BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0x0000dead);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_rsh0_x);
+ATF_TC_HEAD(libbpfjit_alu_rsh0_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_RSH+BPF_X with k=0");
+}
+
+ATF_TC_BODY(libbpfjit_alu_rsh0_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 0xdeadbeef),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
+ BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0xdeadbeef);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_modulo_x);
+ATF_TC_HEAD(libbpfjit_alu_modulo_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of modulo logic of BPF_ALU+BPF_X operations");
+}
+
+ATF_TC_BODY(libbpfjit_alu_modulo_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
+
+ /* (7FFFFF77 * 0FFFFF77) = 07FFFFB2,F0004951 */
+ BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0fffff77)),
+ BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0),
+
+ /* 07FFFFB2,F0004951 << 1 = 0FFFFF65,E00092A2 */
+ BPF_STMT(BPF_LDX+BPF_W+BPF_K, 1),
+ BPF_STMT(BPF_ALU+BPF_LSH+BPF_X, 0),
+
+ /* 0FFFFF65,E00092A2 + DDDDDDDD = 0FFFFF66,BDDE707F */
+ BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdddddddd)),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
+
+ /* 0FFFFF66,BDDE707F - FFFFFFFF = 0FFFFF65,BDDE7080 */
+ BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffffff)),
+ BPF_STMT(BPF_ALU+BPF_SUB+BPF_X, 0),
+
+ /* 0FFFFF65,BDDE7080 | 0000030C = 0FFFFF65,BDDE738C */
+ BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x0000030c)),
+ BPF_STMT(BPF_ALU+BPF_OR+BPF_X, 0),
+
+ /* -0FFFFF65,BDDE738C mod(2^64) = F000009A,42218C74 */
+ BPF_STMT(BPF_ALU+BPF_NEG, 0),
+
+ /* F000009A,42218C74 & FFFFFF0F = F000009A,42218C04 */
+ BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xffffff0f)),
+ BPF_STMT(BPF_ALU+BPF_AND+BPF_X, 0),
+
+ /* F000009A,42218C74 >> 3 = 1E000013,48443180 */
+ /* 00000000,42218C74 >> 3 = 00000000,08443180 */
+ BPF_STMT(BPF_LDX+BPF_W+BPF_K, 3),
+ BPF_STMT(BPF_ALU+BPF_RSH+BPF_X, 0),
+
+ /* 00000000,08443180 * 7FFFFF77 = 042218BB,93818280 */
+ BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0x7fffff77)),
+ BPF_STMT(BPF_ALU+BPF_MUL+BPF_X, 0),
+
+ /* 042218BB,93818280 / DEAD = 000004C0,71CBBBC3 */
+ /* 00000000,93818280 / DEAD = 00000000,0000A994 */
+ BPF_STMT(BPF_LDX+BPF_W+BPF_K, UINT32_C(0xdead)),
+ BPF_STMT(BPF_ALU+BPF_DIV+BPF_X, 0),
+
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) != UINT32_C(0x71cbbbc3));
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_C(0x0000a994));
+
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_alu_neg);
+ATF_TC_HEAD(libbpfjit_alu_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ALU+BPF_NEG");
+}
+
+ATF_TC_BODY(libbpfjit_alu_neg, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 777),
+ BPF_STMT(BPF_ALU+BPF_NEG, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0u-777u);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_jmp_ja);
+ATF_TC_HEAD(libbpfjit_jmp_ja, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_JMP+BPF_JA");
+}
+
+ATF_TC_BODY(libbpfjit_jmp_ja, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_JMP+BPF_JA, 1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_jmp_jgt_k);
+ATF_TC_HEAD(libbpfjit_jmp_jgt_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_K");
+}
+
+ATF_TC_BODY(libbpfjit_jmp_jgt_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 7, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 2, 2, 0),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 9, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 4, 1, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 2, 3),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ BPF_STMT(BPF_RET+BPF_K, 4),
+ BPF_STMT(BPF_RET+BPF_K, 5),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 5, 3, 1),
+ BPF_STMT(BPF_RET+BPF_K, 6),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 0, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7),
+ BPF_STMT(BPF_RET+BPF_K, 8)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[8]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_jmp_jge_k);
+ATF_TC_HEAD(libbpfjit_jmp_jge_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_K");
+}
+
+ATF_TC_BODY(libbpfjit_jmp_jge_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 8, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 3, 2, 0),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 9, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 5, 1, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 2, 3),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ BPF_STMT(BPF_RET+BPF_K, 4),
+ BPF_STMT(BPF_RET+BPF_K, 5),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 6, 3, 1),
+ BPF_STMT(BPF_RET+BPF_K, 6),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 1, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7),
+ BPF_STMT(BPF_RET+BPF_K, 8)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[8]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_jmp_jeq_k);
+ATF_TC_HEAD(libbpfjit_jmp_jeq_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_K");
+}
+
+ATF_TC_BODY(libbpfjit_jmp_jeq_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 1, 0),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 9, 1, 1),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 5, 1, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 7, 2, 3),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ BPF_STMT(BPF_RET+BPF_K, 4),
+ BPF_STMT(BPF_RET+BPF_K, 5),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 3, 1),
+ BPF_STMT(BPF_RET+BPF_K, 6),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 1, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7),
+ BPF_STMT(BPF_RET+BPF_K, 8)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[8]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 7);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 7);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_jmp_jset_k);
+ATF_TC_HEAD(libbpfjit_jmp_jset_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_K");
+}
+
+ATF_TC_BODY(libbpfjit_jmp_jset_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 8, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 4, 2, 0),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 3, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 1, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 1, 2, 3),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ BPF_STMT(BPF_RET+BPF_K, 4),
+ BPF_STMT(BPF_RET+BPF_K, 5),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 2, 3, 1),
+ BPF_STMT(BPF_RET+BPF_K, 6),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 7, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7),
+ BPF_STMT(BPF_RET+BPF_K, 8)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[8]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 5);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_jmp_modulo_k);
+ATF_TC_HEAD(libbpfjit_jmp_modulo_k, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of modulo logic of BPF_JMP+BPF_K operations");
+}
+
+ATF_TC_BODY(libbpfjit_jmp_modulo_k, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
+ BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xfffff770), 0, 3),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xfffff770), 2, 0),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xfffff771), 1, 0),
+ BPF_STMT(BPF_JMP+BPF_JA, 1),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+
+ /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)),
+
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 4),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 5),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 6),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, UINT32_C(0xffffeee0), 0, 3),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, UINT32_C(0xffffeee0), 2, 0),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, UINT32_C(0xffffeee1), 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 7)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_jmp_jgt_x);
+ATF_TC_HEAD(libbpfjit_jmp_jgt_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_JMP+BPF_JGT+BPF_X");
+}
+
+ATF_TC_BODY(libbpfjit_jmp_jgt_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 1, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 2, 3),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ BPF_STMT(BPF_RET+BPF_K, 4),
+ BPF_STMT(BPF_RET+BPF_K, 5),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 4, 1),
+ BPF_STMT(BPF_RET+BPF_K, 6),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7),
+ BPF_STMT(BPF_RET+BPF_K, 8)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[8]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_jmp_jge_x);
+ATF_TC_HEAD(libbpfjit_jmp_jge_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_JMP+BPF_JGE+BPF_X");
+}
+
+ATF_TC_BODY(libbpfjit_jmp_jge_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 3, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 2, 3),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ BPF_STMT(BPF_RET+BPF_K, 4),
+ BPF_STMT(BPF_RET+BPF_K, 5),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 4, 1),
+ BPF_STMT(BPF_RET+BPF_K, 6),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7),
+ BPF_STMT(BPF_RET+BPF_K, 8)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[8]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 7);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_jmp_jeq_x);
+ATF_TC_HEAD(libbpfjit_jmp_jeq_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_JMP+BPF_JEQ+BPF_X");
+}
+
+ATF_TC_BODY(libbpfjit_jmp_jeq_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 9),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 2, 3),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ BPF_STMT(BPF_RET+BPF_K, 4),
+ BPF_STMT(BPF_RET+BPF_K, 5),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 6),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 3, 1),
+ BPF_STMT(BPF_RET+BPF_K, 6),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 1, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7),
+ BPF_STMT(BPF_RET+BPF_K, 8)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[8]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 7);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 7);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 7);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_jmp_jset_x);
+ATF_TC_HEAD(libbpfjit_jmp_jset_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_JMP+BPF_JSET+BPF_X");
+}
+
+ATF_TC_BODY(libbpfjit_jmp_jset_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 8),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 4),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 0),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 3, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 1, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 1),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 2, 3),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ BPF_STMT(BPF_RET+BPF_K, 4),
+ BPF_STMT(BPF_RET+BPF_K, 5),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 4, 1),
+ BPF_STMT(BPF_RET+BPF_K, 6),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 7),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_X, 0, 0, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7),
+ BPF_STMT(BPF_RET+BPF_K, 8)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[8]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 1);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 1);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 7);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 5);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 8);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 5);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_jmp_modulo_x);
+ATF_TC_HEAD(libbpfjit_jmp_modulo_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of modulo logic of BPF_JMP+BPF_X operations");
+}
+
+ATF_TC_BODY(libbpfjit_jmp_modulo_x, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_C(0x7fffff77)),
+ /* FFFFF770 << 4 = FFFFF770 */
+ BPF_STMT(BPF_ALU+BPF_LSH+BPF_K, 4),
+
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff770)),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xfffff771)),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0),
+ BPF_STMT(BPF_JMP+BPF_JA, 1),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+
+ /* FFFFF770+FFFFF770 = 00000001,FFFFEEE0 */
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xfffff770)),
+
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 4),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 5),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 6),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee0)),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 0, 4),
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_X, 0, 3, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_C(0xffffeee1)),
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_X, 0, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 7)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_ld_abs);
+ATF_TC_HEAD(libbpfjit_ld_abs, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LD+BPF_ABS");
+}
+
+ATF_TC_BODY(libbpfjit_ld_abs, tc)
+{
+ static struct bpf_insn insns[3][2] = {
+ {
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 5),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 5),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ }
+ };
+
+ static size_t lengths[3] = { 1, 2, 4 };
+ static unsigned int expected[3] = { 0xde, 0xdead, 0xdeadbeef };
+
+ size_t i, l;
+ uint8_t *pkt = deadbeef_at_5;
+ size_t pktsize = sizeof(deadbeef_at_5);
+
+ size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
+
+ for (i = 0; i < 3; i++) {
+ bpfjit_func_t code;
+
+ ATF_CHECK(bpf_validate(insns[i], insn_count));
+
+ code = bpfjit_generate_code(NULL, insns[i], insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (l = 1; l < 5 + lengths[i]; l++) {
+ ATF_CHECK(jitcall(code, pkt, l, l) == 0);
+ ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0);
+ }
+
+ l = 5 + lengths[i];
+ ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
+ ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]);
+
+ l = pktsize;
+ ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
+
+ bpfjit_free_code(code);
+ }
+}
+
+ATF_TC(libbpfjit_ld_abs_k_overflow);
+ATF_TC_HEAD(libbpfjit_ld_abs_k_overflow, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LD+BPF_ABS with overflow in k+4");
+}
+
+ATF_TC_BODY(libbpfjit_ld_abs_k_overflow, tc)
+{
+ static struct bpf_insn insns[12][3] = {
+ {
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, UINT32_MAX - 1),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 1),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 2),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, UINT32_MAX - 3),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ }
+ };
+
+ int i;
+ uint8_t pkt[8] = { 0 };
+
+ size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
+
+ for (i = 0; i < 3; i++) {
+ bpfjit_func_t code;
+
+ ATF_CHECK(bpf_validate(insns[i], insn_count));
+
+ code = bpfjit_generate_code(NULL, insns[i], insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+
+ bpfjit_free_code(code);
+ }
+}
+
+ATF_TC(libbpfjit_ld_ind);
+ATF_TC_HEAD(libbpfjit_ld_ind, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LD+BPF_IND");
+}
+
+ATF_TC_BODY(libbpfjit_ld_ind, tc)
+{
+ static struct bpf_insn insns[6][3] = {
+ {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
+ BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ },
+ {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 2),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ },
+ {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 3),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 2),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ },
+ {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
+ BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ },
+ {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ },
+ {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ }
+ };
+
+ static size_t lengths[6] = { 1, 2, 4, 1, 2, 4 };
+
+ static unsigned int expected[6] = {
+ 0xde, 0xdead, 0xdeadbeef,
+ 0xde, 0xdead, 0xdeadbeef
+ };
+
+ size_t i, l;
+ uint8_t *pkt = deadbeef_at_5;
+ size_t pktsize = sizeof(deadbeef_at_5);
+
+ size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
+
+ for (i = 0; i < 3; i++) {
+ bpfjit_func_t code;
+
+ ATF_CHECK(bpf_validate(insns[i], insn_count));
+
+ code = bpfjit_generate_code(NULL, insns[i], insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (l = 1; l < 5 + lengths[i]; l++) {
+ ATF_CHECK(jitcall(code, pkt, l, l) == 0);
+ ATF_CHECK(jitcall(code, pkt, pktsize, l) == 0);
+ }
+
+ l = 5 + lengths[i];
+ ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
+ ATF_CHECK(jitcall(code, pkt, pktsize, l) == expected[i]);
+
+ l = pktsize;
+ ATF_CHECK(jitcall(code, pkt, l, l) == expected[i]);
+
+ bpfjit_free_code(code);
+ }
+}
+
+ATF_TC(libbpfjit_ld_ind_k_overflow);
+ATF_TC_HEAD(libbpfjit_ld_ind_k_overflow, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LD+BPF_IND with overflow in k+4");
+}
+
+ATF_TC_BODY(libbpfjit_ld_ind_k_overflow, tc)
+{
+ static struct bpf_insn insns[12][3] = {
+ {
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, UINT32_MAX - 1),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 1),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 2),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ },
+ {
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 7),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, UINT32_MAX - 3),
+ BPF_STMT(BPF_RET+BPF_K, 1)
+ }
+ };
+
+ int i;
+ uint8_t pkt[8] = { 0 };
+
+ size_t insn_count = sizeof(insns[0]) / sizeof(insns[0][0]);
+
+ for (i = 0; i < 3; i++) {
+ bpfjit_func_t code;
+
+ ATF_CHECK(bpf_validate(insns[i], insn_count));
+
+ code = bpfjit_generate_code(NULL, insns[i], insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+
+ bpfjit_free_code(code);
+ }
+}
+
+ATF_TC(libbpfjit_ld_ind_x_overflow1);
+ATF_TC_HEAD(libbpfjit_ld_ind_x_overflow1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4");
+}
+
+ATF_TC_BODY(libbpfjit_ld_ind_x_overflow1, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_LEN, 0),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)),
+ BPF_STMT(BPF_MISC+BPF_TAX, 0),
+ BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ size_t i;
+ bpfjit_func_t code;
+ uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 1; i <= sizeof(pkt); i++) {
+ ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i);
+ ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i);
+ }
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_ld_ind_x_overflow2);
+ATF_TC_HEAD(libbpfjit_ld_ind_x_overflow2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LD+BPF_IND with overflow in X+4");
+}
+
+ATF_TC_BODY(libbpfjit_ld_ind_x_overflow2, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_LEN, 0),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, UINT32_C(0xffffffff)),
+ BPF_STMT(BPF_ST, 3),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3),
+ BPF_STMT(BPF_LD+BPF_B+BPF_IND, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ size_t i;
+ bpfjit_func_t code;
+ uint8_t pkt[8] = { 10, 20, 30, 40, 50, 60, 70, 80 };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 1; i <= sizeof(pkt); i++) {
+ ATF_CHECK(bpf_filter(insns, pkt, i, i) == 10 * i);
+ ATF_CHECK(jitcall(code, pkt, i, i) == 10 * i);
+ }
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_ld_len);
+ATF_TC_HEAD(libbpfjit_ld_len, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LD+BPF_W+BPF_LEN");
+}
+
+ATF_TC_BODY(libbpfjit_ld_len, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ size_t i;
+ bpfjit_func_t code;
+ uint8_t pkt[32]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 0; i < sizeof(pkt); i++)
+ ATF_CHECK(jitcall(code, pkt, i, 1) == i);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_ld_imm);
+ATF_TC_HEAD(libbpfjit_ld_imm, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LD+BPF_IMM");
+}
+
+ATF_TC_BODY(libbpfjit_ld_imm, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_ldx_imm1);
+ATF_TC_HEAD(libbpfjit_ldx_imm1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LDX+BPF_IMM");
+}
+
+ATF_TC_BODY(libbpfjit_ldx_imm1, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, UINT32_MAX - 5),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX - 5);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_ldx_imm2);
+ATF_TC_HEAD(libbpfjit_ldx_imm2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LDX+BPF_IMM");
+}
+
+ATF_TC_BODY(libbpfjit_ldx_imm2, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 5),
+ BPF_STMT(BPF_LD+BPF_IMM, 5),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_ldx_len1);
+ATF_TC_HEAD(libbpfjit_ldx_len1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LDX+BPF_LEN");
+}
+
+ATF_TC_BODY(libbpfjit_ldx_len1, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ size_t i;
+ bpfjit_func_t code;
+ uint8_t pkt[5]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 1; i < sizeof(pkt); i++) {
+ ATF_CHECK(jitcall(code, pkt, i, 1) == i);
+ ATF_CHECK(jitcall(code, pkt, i + 1, i) == i + 1);
+ }
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_ldx_len2);
+ATF_TC_HEAD(libbpfjit_ldx_len2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LDX+BPF_LEN");
+}
+
+ATF_TC_BODY(libbpfjit_ldx_len2, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_LD+BPF_IMM, 5),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_X, 0, 1, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[5]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 5, 1) == UINT32_MAX);
+ ATF_CHECK(jitcall(code, pkt, 6, 5) == 7);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_ldx_msh);
+ATF_TC_HEAD(libbpfjit_ldx_msh, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_LDX+BPF_MSH");
+}
+
+ATF_TC_BODY(libbpfjit_ldx_msh, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 1),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[2] = { 0, 0x7a };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 40);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_misc_tax);
+ATF_TC_HEAD(libbpfjit_misc_tax, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_MISC+BPF_TAX");
+}
+
+ATF_TC_BODY(libbpfjit_misc_tax, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 3),
+ BPF_STMT(BPF_MISC+BPF_TAX, 0),
+ BPF_STMT(BPF_LD+BPF_B+BPF_IND, 2),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[] = { 0, 11, 22, 33, 44, 55 };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, sizeof(pkt), sizeof(pkt)) == 55);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_misc_txa);
+ATF_TC_HEAD(libbpfjit_misc_txa, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_MISC+BPF_TXA");
+}
+
+ATF_TC_BODY(libbpfjit_misc_txa, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 391),
+ BPF_STMT(BPF_MISC+BPF_TXA, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 391);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_st1);
+ATF_TC_HEAD(libbpfjit_st1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ST");
+}
+
+ATF_TC_BODY(libbpfjit_st1, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_ST, 0),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 1),
+ BPF_STMT(BPF_LD+BPF_MEM, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ size_t i;
+ bpfjit_func_t code;
+ uint8_t pkt[16]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 1; i <= sizeof(pkt); i++)
+ ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_st2);
+ATF_TC_HEAD(libbpfjit_st2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ST");
+}
+
+ATF_TC_BODY(libbpfjit_st2, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
+ BPF_STMT(BPF_LD+BPF_MEM, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_st3);
+ATF_TC_HEAD(libbpfjit_st3, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ST");
+}
+
+ATF_TC_BODY(libbpfjit_st3, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_ST, 0),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100),
+ BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0),
+ BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1),
+ BPF_STMT(BPF_RET+BPF_A, 0),
+ BPF_STMT(BPF_LD+BPF_MEM, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[2]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_REQUIRE(BPF_MEMWORDS > 1);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 102);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_st4);
+ATF_TC_HEAD(libbpfjit_st4, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ST");
+}
+
+ATF_TC_BODY(libbpfjit_st4, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_ST, 5),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 100),
+ BPF_STMT(BPF_ST, BPF_MEMWORDS-1),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, 200),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 301, 2, 0),
+ BPF_STMT(BPF_LD+BPF_MEM, BPF_MEMWORDS-1),
+ BPF_STMT(BPF_RET+BPF_A, 0),
+ BPF_STMT(BPF_LD+BPF_MEM, 5),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[2]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_REQUIRE(BPF_MEMWORDS > 6);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 1);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 102);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_st5);
+ATF_TC_HEAD(libbpfjit_st5, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_ST");
+}
+
+ATF_TC_BODY(libbpfjit_st5, tc)
+{
+ struct bpf_insn insns[5*BPF_MEMWORDS+2];
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ size_t k;
+ bpfjit_func_t code;
+ uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */
+
+ memset(insns, 0, sizeof(insns));
+
+ /* for each k do M[k] = k */
+ for (k = 0; k < BPF_MEMWORDS; k++) {
+ insns[2*k].code = BPF_LD+BPF_IMM;
+ insns[2*k].k = 3*k;
+ insns[2*k+1].code = BPF_ST;
+ insns[2*k+1].k = k;
+ }
+
+ /* load wirelen into A */
+ insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN;
+
+ /* for each k, if (A == k + 1) return M[k] */
+ for (k = 0; k < BPF_MEMWORDS; k++) {
+ insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K;
+ insns[2*BPF_MEMWORDS+3*k+1].k = k+1;
+ insns[2*BPF_MEMWORDS+3*k+1].jt = 0;
+ insns[2*BPF_MEMWORDS+3*k+1].jf = 2;
+ insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM;
+ insns[2*BPF_MEMWORDS+3*k+2].k = k;
+ insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A;
+ insns[2*BPF_MEMWORDS+3*k+3].k = 0;
+ }
+
+ insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K;
+ insns[5*BPF_MEMWORDS+1].k = UINT32_MAX;
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (k = 1; k <= sizeof(pkt); k++)
+ ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_stx1);
+ATF_TC_HEAD(libbpfjit_stx1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_STX");
+}
+
+ATF_TC_BODY(libbpfjit_stx1, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_STX, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ size_t i;
+ bpfjit_func_t code;
+ uint8_t pkt[16]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 1; i <= sizeof(pkt); i++)
+ ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == i);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_stx2);
+ATF_TC_HEAD(libbpfjit_stx2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_STX");
+}
+
+ATF_TC_BODY(libbpfjit_stx2, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_STX, BPF_MEMWORDS-1),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 0),
+ BPF_STMT(BPF_MISC+BPF_TXA, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_stx3);
+ATF_TC_HEAD(libbpfjit_stx3, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_STX");
+}
+
+ATF_TC_BODY(libbpfjit_stx3, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_LEN, 0),
+ BPF_STMT(BPF_STX, 5),
+ BPF_STMT(BPF_STX, 2),
+ BPF_STMT(BPF_STX, 3),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 1),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 2),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 3),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 5),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_MEM, 6),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ size_t i;
+ bpfjit_func_t code;
+ uint8_t pkt[16]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 1; i <= sizeof(pkt); i++)
+ ATF_CHECK(jitcall(code, pkt, i, sizeof(pkt)) == 3 * i);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_stx4);
+ATF_TC_HEAD(libbpfjit_stx4, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation of BPF_STX");
+}
+
+ATF_TC_BODY(libbpfjit_stx4, tc)
+{
+ struct bpf_insn insns[5*BPF_MEMWORDS+2];
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ size_t k;
+ bpfjit_func_t code;
+ uint8_t pkt[BPF_MEMWORDS]; /* the program doesn't read any data */
+
+ memset(insns, 0, sizeof(insns));
+
+ /* for each k do M[k] = k */
+ for (k = 0; k < BPF_MEMWORDS; k++) {
+ insns[2*k].code = BPF_LDX+BPF_W+BPF_IMM;
+ insns[2*k].k = 3*k;
+ insns[2*k+1].code = BPF_STX;
+ insns[2*k+1].k = k;
+ }
+
+ /* load wirelen into A */
+ insns[2*BPF_MEMWORDS].code = BPF_LD+BPF_W+BPF_LEN;
+
+ /* for each k, if (A == k + 1) return M[k] */
+ for (k = 0; k < BPF_MEMWORDS; k++) {
+ insns[2*BPF_MEMWORDS+3*k+1].code = BPF_JMP+BPF_JEQ+BPF_K;
+ insns[2*BPF_MEMWORDS+3*k+1].k = k+1;
+ insns[2*BPF_MEMWORDS+3*k+1].jt = 0;
+ insns[2*BPF_MEMWORDS+3*k+1].jf = 2;
+ insns[2*BPF_MEMWORDS+3*k+2].code = BPF_LD+BPF_MEM;
+ insns[2*BPF_MEMWORDS+3*k+2].k = k;
+ insns[2*BPF_MEMWORDS+3*k+3].code = BPF_RET+BPF_A;
+ insns[2*BPF_MEMWORDS+3*k+3].k = 0;
+ }
+
+ insns[5*BPF_MEMWORDS+1].code = BPF_RET+BPF_K;
+ insns[5*BPF_MEMWORDS+1].k = UINT32_MAX;
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (k = 1; k <= sizeof(pkt); k++)
+ ATF_CHECK(jitcall(code, pkt, k, k) == 3*(k-1));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_opt_ld_abs_1);
+ATF_TC_HEAD(libbpfjit_opt_ld_abs_1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation with length optimization "
+ "applied to BPF_LD+BPF_ABS");
+}
+
+ATF_TC_BODY(libbpfjit_opt_ld_abs_1, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+
+ size_t i, j;
+ bpfjit_func_t code;
+ uint8_t pkt[2][34] = {
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x0f,
+ 0x80, 0x03, 0x70, 0x23
+ },
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x23,
+ 0x80, 0x03, 0x70, 0x0f
+ }
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 0; i < 2; i++) {
+ for (j = 1; j < sizeof(pkt[i]); j++)
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
+ }
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_opt_ld_abs_2);
+ATF_TC_HEAD(libbpfjit_opt_ld_abs_2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation with length optimization "
+ "applied to BPF_LD+BPF_ABS");
+}
+
+ATF_TC_BODY(libbpfjit_opt_ld_abs_2, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3),
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+
+ size_t i, j;
+ bpfjit_func_t code;
+ uint8_t pkt[2][34] = {
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x0f,
+ 0x80, 0x03, 0x70, 0x23
+ },
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x23,
+ 0x80, 0x03, 0x70, 0x0f
+ }
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 0; i < 2; i++) {
+ for (j = 1; j < sizeof(pkt[i]); j++)
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
+ }
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_opt_ld_abs_3);
+ATF_TC_HEAD(libbpfjit_opt_ld_abs_3, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation with length optimization "
+ "applied to BPF_LD+BPF_ABS");
+}
+
+ATF_TC_BODY(libbpfjit_opt_ld_abs_3, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 6),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 5),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+
+ size_t i, j;
+ bpfjit_func_t code;
+ uint8_t pkt[2][34] = {
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x0f,
+ 0x80, 0x03, 0x70, 0x23
+ },
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x23,
+ 0x80, 0x03, 0x70, 0x0f
+ }
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 0; i < 2; i++) {
+ for (j = 1; j < sizeof(pkt[i]); j++)
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
+ }
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_opt_ld_ind_1);
+ATF_TC_HEAD(libbpfjit_opt_ld_ind_1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation with length optimization "
+ "applied to BPF_LD+BPF_IND");
+}
+
+ATF_TC_BODY(libbpfjit_opt_ld_ind_1, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 12),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 0),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 8),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 14),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 18),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+
+ size_t i, j;
+ bpfjit_func_t code;
+ uint8_t pkt[2][34] = {
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x0f,
+ 0x80, 0x03, 0x70, 0x23
+ },
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x23,
+ 0x80, 0x03, 0x70, 0x0f
+ }
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 0; i < 2; i++) {
+ for (j = 1; j < sizeof(pkt[i]); j++)
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
+ }
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_opt_ld_ind_2);
+ATF_TC_HEAD(libbpfjit_opt_ld_ind_2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation with length optimization "
+ "applied to BPF_LD+BPF_IND");
+}
+
+ATF_TC_BODY(libbpfjit_opt_ld_ind_2, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 26),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 6),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 5),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 30),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 3),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+
+ size_t i, j;
+ bpfjit_func_t code;
+ uint8_t pkt[2][34] = {
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x0f,
+ 0x80, 0x03, 0x70, 0x23
+ },
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x23,
+ 0x80, 0x03, 0x70, 0x0f
+ }
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 0; i < 2; i++) {
+ for (j = 1; j < sizeof(pkt[i]); j++)
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
+ }
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_opt_ld_ind_3);
+ATF_TC_HEAD(libbpfjit_opt_ld_ind_3, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation with length optimization "
+ "applied to BPF_LD+BPF_IND");
+}
+
+ATF_TC_BODY(libbpfjit_opt_ld_ind_3, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 15),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 11),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+
+ size_t i, j;
+ bpfjit_func_t code;
+ uint8_t pkt[2][34] = {
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x0f,
+ 0x80, 0x03, 0x70, 0x23
+ },
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x23,
+ 0x80, 0x03, 0x70, 0x0f
+ }
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 0; i < 2; i++) {
+ for (j = 1; j < sizeof(pkt[i]); j++)
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
+ }
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_opt_ld_ind_4);
+ATF_TC_HEAD(libbpfjit_opt_ld_ind_4, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test JIT compilation with length optimization "
+ "applied to BPF_LD+BPF_IND");
+}
+
+ATF_TC_BODY(libbpfjit_opt_ld_ind_4, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 11),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 19),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 2),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 3, 7),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 6),
+ BPF_STMT(BPF_LD+BPF_W+BPF_IND, 15),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 4),
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 0),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x800, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+
+ size_t i, j;
+ bpfjit_func_t code;
+ uint8_t pkt[2][34] = {
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x0f,
+ 0x80, 0x03, 0x70, 0x23
+ },
+ {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0x08, 0x00,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 0x80, 0x03, 0x70, 0x23,
+ 0x80, 0x03, 0x70, 0x0f
+ }
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ for (i = 0; i < 2; i++) {
+ for (j = 1; j < sizeof(pkt[i]); j++)
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == 0);
+ ATF_CHECK(jitcall(code, pkt[i], j, j) == UINT32_MAX);
+ }
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_abc_ja);
+ATF_TC_HEAD(libbpfjit_abc_ja, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test ABC optimization with a single BPF_JMP+BPF_JA");
+}
+
+ATF_TC_BODY(libbpfjit_abc_ja, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */
+ BPF_STMT(BPF_JMP+BPF_JA, 2),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, UINT32_MAX - 1),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 2), /* min. length 6 */
+ BPF_STMT(BPF_RET+BPF_A, 0),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 7),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[6] = {0, 0, /* UINT32_MAX: */ 255, 255, 255, 255};
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == UINT32_MAX);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_abc_ja_over);
+ATF_TC_HEAD(libbpfjit_abc_ja_over, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test ABC optimization when BPF_JMP+BPF_JA jumps over all loads");
+}
+
+ATF_TC_BODY(libbpfjit_abc_ja_over, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_JMP+BPF_JA, 2),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 4),
+ BPF_STMT(BPF_RET+BPF_K, 1),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 5),
+ BPF_STMT(BPF_RET+BPF_K, 2),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 6),
+ BPF_STMT(BPF_RET+BPF_K, 3),
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1]; /* the program doesn't read any data */
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == UINT32_MAX);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_abc_ld_chain);
+ATF_TC_HEAD(libbpfjit_abc_ld_chain, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test ABC optimization of a chain of BPF_LD instructions "
+ "with exits leading to a single BPF_RET");
+}
+
+ATF_TC_BODY(libbpfjit_abc_ld_chain, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 3), /* min. length 4 */
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 8, 0, 4),
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 4), /* min. length 6 */
+ BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 7, 0, 2),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 6), /* min. length 10 */
+ BPF_JUMP(BPF_JMP+BPF_JGT+BPF_K, 6, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 123456789),
+ BPF_STMT(BPF_RET+BPF_K, 987654321),
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[10] = {};
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ /* Packet is too short. */
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
+
+ /* !(pkt[3] == 8) => return 123456789 */
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 123456789);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 123456789);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 123456789);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 123456789);
+ ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789);
+
+ /* !(pkt[4:2] >= 7) => too short or return 123456789 */
+ pkt[3] = 8;
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 123456789);
+ ATF_CHECK(jitcall(code, pkt, 9, 9) == 123456789);
+
+ /* !(pkt[6:4] > 6) => too short or return 987654321 */
+ pkt[4] = pkt[5] = 1;
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+ ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
+ ATF_CHECK(jitcall(code, pkt, 10, 10) == 987654321);
+
+ /* (pkt[6:4] > 6) => too short or return 123456789 */
+ pkt[6] = pkt[7] = pkt[8] = pkt[9] = 1;
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+ ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
+ ATF_CHECK(jitcall(code, pkt, 10, 10) == 123456789);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_examples_1);
+ATF_TC_HEAD(libbpfjit_examples_1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test the first example from bpf(4) - "
+ "accept Reverse ARP requests");
+}
+
+ATF_TC_BODY(libbpfjit_examples_1, tc)
+{
+ /*
+ * The following filter is taken from the Reverse ARP
+ * Daemon. It accepts only Reverse ARP requests.
+ */
+ struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8035, 0, 3),
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 3, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, 42),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[22] = {};
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ /* Packet is too short. */
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+ ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
+ ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
+ ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
+ ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
+ ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
+ ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
+ ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
+ ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
+ ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
+ ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
+ ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
+ ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
+ ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
+
+ /* The packet doesn't match. */
+ ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
+
+ /* Still no match after setting the protocol field. */
+ pkt[12] = 0x80; pkt[13] = 0x35;
+ ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
+
+ /* Set RARP message type. */
+ pkt[21] = 3;
+ ATF_CHECK(jitcall(code, pkt, 22, 22) == 42);
+
+ /* Packet is too short. */
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+ ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
+ ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
+ ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
+ ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
+ ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
+ ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
+ ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
+ ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
+ ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
+ ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
+ ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
+ ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
+ ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
+
+ /* Change RARP message type. */
+ pkt[20] = 3;
+ ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_examples_2);
+ATF_TC_HEAD(libbpfjit_examples_2, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test the second example from bpf(4) - "
+ "accept IP packets between two specified hosts");
+}
+
+ATF_TC_BODY(libbpfjit_examples_2, tc)
+{
+ /*
+ * This filter accepts only IP packets between host 128.3.112.15
+ * and 128.3.112.35.
+ */
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 8),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 26),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 2),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 3, 4),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x80037023, 0, 3),
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 30),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x8003700f, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[34] = {};
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ /* Packet is too short. */
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+ ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
+ ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
+ ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
+ ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
+ ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
+ ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
+ ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
+ ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
+ ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
+ ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
+ ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
+ ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
+ ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
+ ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
+ ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
+ ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
+ ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
+ ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
+ ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
+ ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
+ ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
+ ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
+ ATF_CHECK(jitcall(code, pkt, 31, 31) == 0);
+ ATF_CHECK(jitcall(code, pkt, 32, 32) == 0);
+ ATF_CHECK(jitcall(code, pkt, 33, 33) == 0);
+
+ /* The packet doesn't match. */
+ ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
+
+ /* Still no match after setting the protocol field. */
+ pkt[12] = 8;
+ ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
+
+ pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 15;
+ ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
+
+ pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 35;
+ ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX);
+
+ /* Swap the ip addresses. */
+ pkt[26] = 128; pkt[27] = 3; pkt[28] = 112; pkt[29] = 35;
+ ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
+
+ pkt[30] = 128; pkt[31] = 3; pkt[32] = 112; pkt[33] = 15;
+ ATF_CHECK(jitcall(code, pkt, 34, 34) == UINT32_MAX);
+
+ /* Packet is too short. */
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+ ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
+ ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
+ ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
+ ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
+ ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
+ ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
+ ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
+ ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
+ ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
+ ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
+ ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
+ ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
+ ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
+ ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
+ ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
+ ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
+ ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
+ ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
+ ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
+ ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
+ ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
+ ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
+ ATF_CHECK(jitcall(code, pkt, 31, 31) == 0);
+ ATF_CHECK(jitcall(code, pkt, 32, 32) == 0);
+ ATF_CHECK(jitcall(code, pkt, 33, 33) == 0);
+
+ /* Change the protocol field. */
+ pkt[13] = 8;
+ ATF_CHECK(jitcall(code, pkt, 34, 34) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_examples_3);
+ATF_TC_HEAD(libbpfjit_examples_3, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test the third example from bpf(4) - "
+ "accept TCP finger packets");
+}
+
+ATF_TC_BODY(libbpfjit_examples_3, tc)
+{
+ /*
+ * This filter returns only TCP finger packets.
+ */
+ struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 12),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x0800, 0, 10),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 23),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 6, 0, 8),
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 20),
+ BPF_JUMP(BPF_JMP+BPF_JSET+BPF_K, 0x1fff, 6, 0),
+ BPF_STMT(BPF_LDX+BPF_B+BPF_MSH, 14),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 14),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 2, 0),
+ BPF_STMT(BPF_LD+BPF_H+BPF_IND, 16),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 79, 0, 1),
+ BPF_STMT(BPF_RET+BPF_K, UINT32_MAX),
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[30] = {};
+
+ /* Set IP fragment offset to non-zero. */
+ pkt[20] = 1; pkt[21] = 1;
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ /* Packet is too short. */
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+ ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
+ ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
+ ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
+ ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
+ ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
+ ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
+ ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
+ ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
+ ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
+ ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
+ ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
+ ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
+ ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
+ ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
+ ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
+ ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
+ ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
+ ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
+ ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
+ ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
+ ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
+
+ /* The packet doesn't match. */
+ ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
+
+ /* Still no match after setting the protocol field. */
+ pkt[12] = 8;
+ ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
+
+ /* Get one step closer to the match. */
+ pkt[23] = 6;
+ ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
+
+ /* Set IP fragment offset to zero. */
+ pkt[20] = 0x20; pkt[21] = 0;
+ ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
+
+ /* Set IP header length to 12. */
+ pkt[14] = 0xd3;
+ ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
+
+ /* Match one branch of the program. */
+ pkt[27] = 79;
+ ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX);
+
+ /* Match the other branch of the program. */
+ pkt[29] = 79; pkt[27] = 0;
+ ATF_CHECK(jitcall(code, pkt, 30, 30) == UINT32_MAX);
+
+ /* Packet is too short. */
+ ATF_CHECK(jitcall(code, pkt, 1, 1) == 0);
+ ATF_CHECK(jitcall(code, pkt, 2, 2) == 0);
+ ATF_CHECK(jitcall(code, pkt, 3, 3) == 0);
+ ATF_CHECK(jitcall(code, pkt, 4, 4) == 0);
+ ATF_CHECK(jitcall(code, pkt, 5, 5) == 0);
+ ATF_CHECK(jitcall(code, pkt, 6, 6) == 0);
+ ATF_CHECK(jitcall(code, pkt, 7, 7) == 0);
+ ATF_CHECK(jitcall(code, pkt, 8, 8) == 0);
+ ATF_CHECK(jitcall(code, pkt, 9, 9) == 0);
+ ATF_CHECK(jitcall(code, pkt, 10, 10) == 0);
+ ATF_CHECK(jitcall(code, pkt, 11, 11) == 0);
+ ATF_CHECK(jitcall(code, pkt, 12, 12) == 0);
+ ATF_CHECK(jitcall(code, pkt, 13, 13) == 0);
+ ATF_CHECK(jitcall(code, pkt, 14, 14) == 0);
+ ATF_CHECK(jitcall(code, pkt, 15, 15) == 0);
+ ATF_CHECK(jitcall(code, pkt, 16, 16) == 0);
+ ATF_CHECK(jitcall(code, pkt, 17, 17) == 0);
+ ATF_CHECK(jitcall(code, pkt, 18, 18) == 0);
+ ATF_CHECK(jitcall(code, pkt, 19, 19) == 0);
+ ATF_CHECK(jitcall(code, pkt, 20, 20) == 0);
+ ATF_CHECK(jitcall(code, pkt, 21, 21) == 0);
+ ATF_CHECK(jitcall(code, pkt, 22, 22) == 0);
+ ATF_CHECK(jitcall(code, pkt, 23, 23) == 0);
+ ATF_CHECK(jitcall(code, pkt, 24, 24) == 0);
+ ATF_CHECK(jitcall(code, pkt, 25, 25) == 0);
+ ATF_CHECK(jitcall(code, pkt, 26, 26) == 0);
+ ATF_CHECK(jitcall(code, pkt, 27, 27) == 0);
+ ATF_CHECK(jitcall(code, pkt, 28, 28) == 0);
+ ATF_CHECK(jitcall(code, pkt, 29, 29) == 0);
+
+ /* Set IP header length to 16. Packet is too short. */
+ pkt[14] = 4;
+ ATF_CHECK(jitcall(code, pkt, 30, 30) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_cop_no_ctx);
+ATF_TC_HEAD(libbpfjit_cop_no_ctx, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COP "
+ "instruction can't be accepted without a context");
+}
+
+ATF_TC_BODY(libbpfjit_cop_no_ctx, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_MISC+BPF_COP, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(!bpf_validate(insns, insn_count));
+
+ ATF_CHECK(bpfjit_generate_code(NULL, insns, insn_count) == NULL);
+}
+
+ATF_TC(libbpfjit_copx_no_ctx);
+ATF_TC_HEAD(libbpfjit_copx_no_ctx, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that BPF_MISC|BPF_COPX "
+ "instruction can't be accepted without a context");
+}
+
+ATF_TC_BODY(libbpfjit_copx_no_ctx, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_MISC+BPF_COPX, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(!bpf_validate(insns, insn_count));
+
+ ATF_CHECK(bpfjit_generate_code(NULL, insns, insn_count) == NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ /*
+ * For every new test please also add a similar test
+ * to ../../net/bpfjit/t_bpfjit.c
+ */
+ ATF_TP_ADD_TC(tp, libbpfjit_empty);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_add_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_sub_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_mul_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div0_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div1_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div2_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div4_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div10_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div10000_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div7609801_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div80000000_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_and_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_or_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh0_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh0_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_modulo_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_add_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_sub_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_mul_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div0_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div1_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div2_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div4_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div10_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div10000_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div7609801_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_div80000000_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_and_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_or_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_lsh0_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_rsh0_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_modulo_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_alu_neg);
+ ATF_TP_ADD_TC(tp, libbpfjit_jmp_ja);
+ ATF_TP_ADD_TC(tp, libbpfjit_jmp_jgt_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_jmp_jge_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_jmp_jeq_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_jmp_jset_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_jmp_modulo_k);
+ ATF_TP_ADD_TC(tp, libbpfjit_jmp_jgt_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_jmp_jge_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_jmp_jeq_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_jmp_jset_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_jmp_modulo_x);
+ ATF_TP_ADD_TC(tp, libbpfjit_ld_abs);
+ ATF_TP_ADD_TC(tp, libbpfjit_ld_abs_k_overflow);
+ ATF_TP_ADD_TC(tp, libbpfjit_ld_ind);
+ ATF_TP_ADD_TC(tp, libbpfjit_ld_ind_k_overflow);
+ ATF_TP_ADD_TC(tp, libbpfjit_ld_ind_x_overflow1);
+ ATF_TP_ADD_TC(tp, libbpfjit_ld_ind_x_overflow2);
+ ATF_TP_ADD_TC(tp, libbpfjit_ld_len);
+ ATF_TP_ADD_TC(tp, libbpfjit_ld_imm);
+ ATF_TP_ADD_TC(tp, libbpfjit_ldx_imm1);
+ ATF_TP_ADD_TC(tp, libbpfjit_ldx_imm2);
+ ATF_TP_ADD_TC(tp, libbpfjit_ldx_len1);
+ ATF_TP_ADD_TC(tp, libbpfjit_ldx_len2);
+ ATF_TP_ADD_TC(tp, libbpfjit_ldx_msh);
+ ATF_TP_ADD_TC(tp, libbpfjit_misc_tax);
+ ATF_TP_ADD_TC(tp, libbpfjit_misc_txa);
+ ATF_TP_ADD_TC(tp, libbpfjit_st1);
+ ATF_TP_ADD_TC(tp, libbpfjit_st2);
+ ATF_TP_ADD_TC(tp, libbpfjit_st3);
+ ATF_TP_ADD_TC(tp, libbpfjit_st4);
+ ATF_TP_ADD_TC(tp, libbpfjit_st5);
+ ATF_TP_ADD_TC(tp, libbpfjit_stx1);
+ ATF_TP_ADD_TC(tp, libbpfjit_stx2);
+ ATF_TP_ADD_TC(tp, libbpfjit_stx3);
+ ATF_TP_ADD_TC(tp, libbpfjit_stx4);
+ ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_abs_1);
+ ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_abs_2);
+ ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_abs_3);
+ ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_1);
+ ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_2);
+ ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_3);
+ ATF_TP_ADD_TC(tp, libbpfjit_opt_ld_ind_4);
+ ATF_TP_ADD_TC(tp, libbpfjit_abc_ja);
+ ATF_TP_ADD_TC(tp, libbpfjit_abc_ja_over);
+ ATF_TP_ADD_TC(tp, libbpfjit_abc_ld_chain);
+ ATF_TP_ADD_TC(tp, libbpfjit_examples_1);
+ ATF_TP_ADD_TC(tp, libbpfjit_examples_2);
+ ATF_TP_ADD_TC(tp, libbpfjit_examples_3);
+ ATF_TP_ADD_TC(tp, libbpfjit_cop_no_ctx);
+ ATF_TP_ADD_TC(tp, libbpfjit_copx_no_ctx);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libbpfjit/t_cop.c b/contrib/netbsd-tests/lib/libbpfjit/t_cop.c
new file mode 100644
index 0000000..7b3b086
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libbpfjit/t_cop.c
@@ -0,0 +1,657 @@
+/* $NetBSD: t_cop.c,v 1.4 2014/07/13 21:35:33 alnsn Exp $ */
+
+/*-
+ * Copyright (c) 2013-2014 Alexander Nasonov.
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_cop.c,v 1.4 2014/07/13 21:35:33 alnsn Exp $");
+
+#include <atf-c.h>
+#include <stdint.h>
+#include <string.h>
+
+#define __BPF_PRIVATE
+#include <net/bpf.h>
+#include <net/bpfjit.h>
+
+static uint32_t retA(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
+static uint32_t retBL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
+static uint32_t retWL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
+static uint32_t retNF(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
+static uint32_t setARG(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
+
+static const bpf_copfunc_t copfuncs[] = {
+ &retA,
+ &retBL,
+ &retWL,
+ &retNF,
+ &setARG
+};
+
+static const bpf_ctx_t ctx = {
+ .copfuncs = copfuncs,
+ .nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]),
+ .extwords = 0
+};
+
+static uint32_t
+retA(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
+{
+
+ return A;
+}
+
+static uint32_t
+retBL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
+{
+
+ return args->buflen;
+}
+
+static uint32_t
+retWL(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
+{
+
+ return args->wirelen;
+}
+
+static uint32_t
+retNF(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
+{
+
+ return bc->nfuncs;
+}
+
+/*
+ * COP function with a side effect.
+ */
+static uint32_t
+setARG(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
+{
+ bool *arg = (bool *)args->arg;
+ bool old = *arg;
+
+ *arg = true;
+ return old;
+}
+
+ATF_TC(libbpfjit_cop_no_ctx);
+ATF_TC_HEAD(libbpfjit_cop_no_ctx, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that bpf program with BPF_COP "
+ "instruction isn't valid without a context");
+}
+
+ATF_TC_BODY(libbpfjit_cop_no_ctx, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_MISC+BPF_COP, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7)
+ };
+
+ bpfjit_func_t code;
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(!bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_CHECK(code == NULL);
+}
+
+ATF_TC(libbpfjit_cop_ret_A);
+ATF_TC_HEAD(libbpfjit_cop_ret_A, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
+ "that returns a content of the A register");
+}
+
+ATF_TC_BODY(libbpfjit_cop_ret_A, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_MISC+BPF_COP, 0), // retA
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 13);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_cop_ret_buflen);
+ATF_TC_HEAD(libbpfjit_cop_ret_buflen, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
+ "that returns the buflen argument");
+}
+
+ATF_TC_BODY(libbpfjit_cop_ret_buflen, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_MISC+BPF_COP, 1), // retBL
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == sizeof(pkt));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_cop_ret_wirelen);
+ATF_TC_HEAD(libbpfjit_cop_ret_wirelen, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
+ "that returns the wirelen argument");
+}
+
+ATF_TC_BODY(libbpfjit_cop_ret_wirelen, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_MISC+BPF_COP, 2), // retWL
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == sizeof(pkt));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_cop_ret_nfuncs);
+ATF_TC_HEAD(libbpfjit_cop_ret_nfuncs, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
+ "that returns nfuncs member of the context argument");
+}
+
+ATF_TC_BODY(libbpfjit_cop_ret_nfuncs, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_MISC+BPF_COP, 3), // retNF
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == ctx.nfuncs);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_cop_side_effect);
+ATF_TC_HEAD(libbpfjit_cop_side_effect, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that ABC optimization doesn't skip BPF_COP call");
+}
+
+ATF_TC_BODY(libbpfjit_cop_side_effect, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0),
+ BPF_STMT(BPF_MISC+BPF_COP, 4), // setARG
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99999),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ bool arg = false;
+ uint8_t pkt[1] = { 0 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ .mem = NULL,
+ .arg = &arg
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 0);
+ ATF_CHECK(arg == true);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_cop_copx);
+ATF_TC_HEAD(libbpfjit_cop_copx, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test BPF_COP call followed by BPF_COPX call");
+}
+
+ATF_TC_BODY(libbpfjit_cop_copx, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 1), /* A <- 1 */
+ BPF_STMT(BPF_MISC+BPF_COP, 0), /* retA */
+ BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A = P[0] */
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */
+ BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */
+ BPF_STMT(BPF_MISC+BPF_COPX, 0), /* retNF */
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 2 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 3 + ctx.nfuncs);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_cop_invalid_index);
+ATF_TC_HEAD(libbpfjit_cop_invalid_index, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that out-of-range coprocessor function fails validation");
+}
+
+ATF_TC_BODY(libbpfjit_cop_invalid_index, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_MISC+BPF_COP, 6), // invalid index
+ BPF_STMT(BPF_RET+BPF_K, 27)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL);
+}
+
+ATF_TC(libbpfjit_copx_no_ctx);
+ATF_TC_HEAD(libbpfjit_copx_no_ctx, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that bpf program with BPF_COPX "
+ "instruction isn't valid without a context");
+}
+
+ATF_TC_BODY(libbpfjit_copx_no_ctx, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_MISC+BPF_COP, 0),
+ BPF_STMT(BPF_RET+BPF_K, 7)
+ };
+
+ bpfjit_func_t code;
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(!bpf_validate(insns, insn_count));
+
+ code = bpfjit_generate_code(NULL, insns, insn_count);
+ ATF_CHECK(code == NULL);
+}
+
+ATF_TC(libbpfjit_copx_ret_A);
+ATF_TC_HEAD(libbpfjit_copx_ret_A, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
+ "that returns a content of the A register");
+}
+
+ATF_TC_BODY(libbpfjit_copx_ret_A, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_LDX+BPF_IMM, 0), // retA
+ BPF_STMT(BPF_MISC+BPF_COPX, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 13);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_copx_ret_buflen);
+ATF_TC_HEAD(libbpfjit_copx_ret_buflen, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
+ "that returns the buflen argument");
+}
+
+ATF_TC_BODY(libbpfjit_copx_ret_buflen, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_LDX+BPF_IMM, 1), // retBL
+ BPF_STMT(BPF_MISC+BPF_COPX, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == sizeof(pkt));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_copx_ret_wirelen);
+ATF_TC_HEAD(libbpfjit_copx_ret_wirelen, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
+ "that returns the wirelen argument");
+}
+
+ATF_TC_BODY(libbpfjit_copx_ret_wirelen, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_IMM, 2), // retWL
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_MISC+BPF_COPX, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == sizeof(pkt));
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_copx_ret_nfuncs);
+ATF_TC_HEAD(libbpfjit_copx_ret_nfuncs, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
+ "that returns nfuncs member of the context argument");
+}
+
+ATF_TC_BODY(libbpfjit_copx_ret_nfuncs, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_LDX+BPF_IMM, 3), // retNF
+ BPF_STMT(BPF_MISC+BPF_COPX, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == ctx.nfuncs);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_copx_side_effect);
+ATF_TC_HEAD(libbpfjit_copx_side_effect, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that ABC optimization doesn't skip BPF_COPX call");
+}
+
+ATF_TC_BODY(libbpfjit_copx_side_effect, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0),
+ BPF_STMT(BPF_LDX+BPF_IMM, 4), // setARG
+ BPF_STMT(BPF_MISC+BPF_COPX, 0),
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99999),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ bool arg = false;
+ uint8_t pkt[1] = { 0 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ .mem = NULL,
+ .arg = &arg
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 0);
+ ATF_CHECK(arg == true);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_copx_cop);
+ATF_TC_HEAD(libbpfjit_copx_cop, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test BPF_COPX call followed by BPF_COP call");
+}
+
+ATF_TC_BODY(libbpfjit_copx_cop, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_IMM, 2), /* X <- 2 */
+ BPF_STMT(BPF_MISC+BPF_COPX, 0), /* retWL */
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */
+ BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A = P[0] */
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */
+ BPF_STMT(BPF_MISC+BPF_TAX, 0), /* X <- A */
+ BPF_STMT(BPF_MISC+BPF_COP, 3), /* retNF */
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 1), /* A = A + X */
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 2 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 5 + ctx.nfuncs);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_copx_invalid_index);
+ATF_TC_HEAD(libbpfjit_copx_invalid_index, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that out-of-range BPF_COPX call fails at runtime");
+}
+
+ATF_TC_BODY(libbpfjit_copx_invalid_index, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LDX+BPF_IMM, 5), // invalid index
+ BPF_STMT(BPF_MISC+BPF_COPX, 0),
+ BPF_STMT(BPF_RET+BPF_K, 27)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ /*
+ * For every new test please also add a similar test
+ * to ../../net/bpfjit/t_cop.c
+ */
+ ATF_TP_ADD_TC(tp, libbpfjit_cop_no_ctx);
+ ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_A);
+ ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_buflen);
+ ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_wirelen);
+ ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_nfuncs);
+ ATF_TP_ADD_TC(tp, libbpfjit_cop_side_effect);
+ ATF_TP_ADD_TC(tp, libbpfjit_cop_copx);
+ ATF_TP_ADD_TC(tp, libbpfjit_cop_invalid_index);
+
+ ATF_TP_ADD_TC(tp, libbpfjit_copx_no_ctx);
+ ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_A);
+ ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_buflen);
+ ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_wirelen);
+ ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_nfuncs);
+ ATF_TP_ADD_TC(tp, libbpfjit_copx_side_effect);
+ ATF_TP_ADD_TC(tp, libbpfjit_copx_cop);
+ ATF_TP_ADD_TC(tp, libbpfjit_copx_invalid_index);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libbpfjit/t_extmem.c b/contrib/netbsd-tests/lib/libbpfjit/t_extmem.c
new file mode 100644
index 0000000..ab6ea88
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libbpfjit/t_extmem.c
@@ -0,0 +1,483 @@
+/* $NetBSD: t_extmem.c,v 1.3 2014/07/14 19:11:15 alnsn Exp $ */
+
+/*-
+ * Copyright (c) 2014 Alexander Nasonov.
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_extmem.c,v 1.3 2014/07/14 19:11:15 alnsn Exp $");
+
+#include <atf-c.h>
+#include <stdint.h>
+#include <string.h>
+
+#define __BPF_PRIVATE
+#include <net/bpf.h>
+#include <net/bpfjit.h>
+
+static uint32_t retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A);
+
+static const bpf_copfunc_t copfuncs[] = {
+ &retM
+};
+
+static const bpf_ctx_t ctx = {
+ .copfuncs = copfuncs,
+ .nfuncs = sizeof(copfuncs) / sizeof(copfuncs[0]),
+ .extwords = 4,
+ .preinited = BPF_MEMWORD_INIT(0) | BPF_MEMWORD_INIT(3),
+};
+
+static uint32_t
+retM(const bpf_ctx_t *bc, bpf_args_t *args, uint32_t A)
+{
+
+ return args->mem[(uintptr_t)args->arg];
+}
+
+
+ATF_TC(libbpfjit_extmem_load_default);
+ATF_TC_HEAD(libbpfjit_extmem_load_default, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that external memory "
+ "is zero initialized by default");
+}
+
+ATF_TC_BODY(libbpfjit_extmem_load_default, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_MEM, 1),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ uint32_t mem[ctx.extwords];
+
+ /* Pre-inited words. */
+ mem[0] = 0;
+ mem[3] = 3;
+
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ .mem = mem,
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 0);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_extmem_load_preinited);
+ATF_TC_HEAD(libbpfjit_extmem_load_preinited, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test a load of external "
+ "pre-initialized memory");
+}
+
+ATF_TC_BODY(libbpfjit_extmem_load_preinited, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_MEM, 3),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ uint32_t mem[ctx.extwords];
+
+ /* Pre-inited words. */
+ mem[0] = 0;
+ mem[3] = 3;
+
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ .mem = mem,
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 3);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_extmem_invalid_load);
+ATF_TC_HEAD(libbpfjit_extmem_invalid_load, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that out-of-range load "
+ "fails validation");
+}
+
+ATF_TC_BODY(libbpfjit_extmem_invalid_load, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_MEM, 4),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL);
+}
+
+ATF_TC(libbpfjit_extmem_store);
+ATF_TC_HEAD(libbpfjit_extmem_store, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test stores to external memory");
+}
+
+ATF_TC_BODY(libbpfjit_extmem_store, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 1), /* A <- 1 */
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2 */
+ BPF_STMT(BPF_ST, 1), /* M[1] <- A */
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */
+ BPF_STMT(BPF_STX, 2), /* M[2] <- X */
+ BPF_STMT(BPF_ST, 3), /* M[3] <- A */
+ BPF_STMT(BPF_RET+BPF_A, 0) /* ret A */
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ uint32_t mem[ctx.extwords];
+
+ /* Pre-inited words. */
+ mem[0] = 0;
+ mem[3] = 7;
+
+ mem[1] = mem[2] = 0xdeadbeef;
+
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ .mem = mem,
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 3);
+
+ bpfjit_free_code(code);
+
+ ATF_CHECK(mem[0] == 0);
+ ATF_CHECK(mem[1] == 1);
+ ATF_CHECK(mem[2] == 2);
+ ATF_CHECK(mem[3] == 3);
+}
+
+ATF_TC(libbpfjit_extmem_side_effect);
+ATF_TC_HEAD(libbpfjit_extmem_side_effect, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that ABC optimization doesn\'t "
+ "skip stores to external memory");
+}
+
+ATF_TC_BODY(libbpfjit_extmem_side_effect, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 0), /* A <- P[0] */
+ BPF_STMT(BPF_LDX+BPF_W+BPF_IMM, 2), /* X <- 2 */
+ BPF_STMT(BPF_ST, 1), /* M[1] <- A */
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_X, 0), /* A <- A + X */
+ BPF_STMT(BPF_STX, 2), /* M[2] <- X */
+ BPF_STMT(BPF_ST, 3), /* M[3] <- A */
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 99), /* A <- P[99] */
+ BPF_STMT(BPF_RET+BPF_A, 0) /* ret A */
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 1 };
+ uint32_t mem[ctx.extwords];
+
+ /* Pre-inited words. */
+ mem[0] = 0;
+ mem[3] = 7;
+
+ mem[1] = mem[2] = 0xdeadbeef;
+
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ .mem = mem,
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 0);
+
+ bpfjit_free_code(code);
+
+ ATF_CHECK(mem[0] == 0);
+ ATF_CHECK(mem[1] == 1);
+ ATF_CHECK(mem[2] == 2);
+ ATF_CHECK(mem[3] == 3);
+}
+
+ATF_TC(libbpfjit_extmem_invalid_store);
+ATF_TC_HEAD(libbpfjit_extmem_invalid_store, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that out-of-range store "
+ "fails validation");
+}
+
+ATF_TC_BODY(libbpfjit_extmem_invalid_store, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_ST, 4),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ ATF_CHECK(bpfjit_generate_code(&ctx, insns, insn_count) == NULL);
+}
+
+ATF_TC(libbpfjit_cop_ret_mem);
+ATF_TC_HEAD(libbpfjit_cop_ret_mem, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
+ "that returns a content of external memory word");
+}
+
+ATF_TC_BODY(libbpfjit_cop_ret_mem, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_ST, 2),
+ BPF_STMT(BPF_LD+BPF_IMM, 137),
+ BPF_STMT(BPF_ST, 1),
+ BPF_STMT(BPF_MISC+BPF_COP, 0), // retM
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ uint32_t mem[ctx.extwords];
+ void *arg = (void*)(uintptr_t)2;
+
+ /* Pre-inited words. */
+ mem[0] = 0;
+ mem[3] = 3;
+
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ .arg = arg,
+ .mem = mem,
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 13);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_cop_ret_preinited_mem);
+ATF_TC_HEAD(libbpfjit_cop_ret_preinited_mem, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function that "
+ "returns a content of external pre-initialized memory word");
+}
+
+ATF_TC_BODY(libbpfjit_cop_ret_preinited_mem, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_ST, 2),
+ BPF_STMT(BPF_LD+BPF_IMM, 137),
+ BPF_STMT(BPF_ST, 1),
+ BPF_STMT(BPF_MISC+BPF_COP, 0), // retM
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ uint32_t mem[ctx.extwords];
+ void *arg = (void*)(uintptr_t)3;
+
+ /* Pre-inited words. */
+ mem[0] = 0;
+ mem[3] = 3;
+
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ .arg = arg,
+ .mem = mem,
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 3);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_copx_ret_mem);
+ATF_TC_HEAD(libbpfjit_copx_ret_mem, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function "
+ "that returns a content of external memory word");
+}
+
+ATF_TC_BODY(libbpfjit_copx_ret_mem, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_ST, 2),
+ BPF_STMT(BPF_LD+BPF_IMM, 137),
+ BPF_STMT(BPF_ST, 1),
+ BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM
+ BPF_STMT(BPF_MISC+BPF_COPX, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ uint32_t mem[ctx.extwords];
+ void *arg = (void*)(uintptr_t)2;
+
+ /* Pre-inited words. */
+ mem[0] = 0;
+ mem[3] = 3;
+
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ .arg = arg,
+ .mem = mem,
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 13);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TC(libbpfjit_copx_ret_preinited_mem);
+ATF_TC_HEAD(libbpfjit_copx_ret_preinited_mem, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coprocessor function that "
+ "returns a content of external pre-initialized memory word");
+}
+
+ATF_TC_BODY(libbpfjit_copx_ret_preinited_mem, tc)
+{
+ static struct bpf_insn insns[] = {
+ BPF_STMT(BPF_LD+BPF_IMM, 13),
+ BPF_STMT(BPF_ST, 2),
+ BPF_STMT(BPF_LD+BPF_IMM, 137),
+ BPF_STMT(BPF_ST, 1),
+ BPF_STMT(BPF_LDX+BPF_IMM, 0), // retM
+ BPF_STMT(BPF_MISC+BPF_COPX, 0),
+ BPF_STMT(BPF_RET+BPF_A, 0)
+ };
+
+ bpfjit_func_t code;
+ uint8_t pkt[1] = { 0 };
+ uint32_t mem[ctx.extwords];
+ void *arg = (void*)(uintptr_t)3;
+
+ /* Pre-inited words. */
+ mem[0] = 0;
+ mem[3] = 3;
+
+ bpf_args_t args = {
+ .pkt = pkt,
+ .buflen = sizeof(pkt),
+ .wirelen = sizeof(pkt),
+ .arg = arg,
+ .mem = mem,
+ };
+
+ size_t insn_count = sizeof(insns) / sizeof(insns[0]);
+
+ code = bpfjit_generate_code(&ctx, insns, insn_count);
+ ATF_REQUIRE(code != NULL);
+
+ ATF_CHECK(code(&ctx, &args) == 3);
+
+ bpfjit_free_code(code);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ /*
+ * For every new test please also add a similar test
+ * to ../../net/bpfjit/t_extmem.c
+ */
+ ATF_TP_ADD_TC(tp, libbpfjit_extmem_load_default);
+ ATF_TP_ADD_TC(tp, libbpfjit_extmem_load_preinited);
+ ATF_TP_ADD_TC(tp, libbpfjit_extmem_invalid_load);
+ ATF_TP_ADD_TC(tp, libbpfjit_extmem_store);
+ ATF_TP_ADD_TC(tp, libbpfjit_extmem_side_effect);
+ ATF_TP_ADD_TC(tp, libbpfjit_extmem_invalid_store);
+ ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_mem);
+ ATF_TP_ADD_TC(tp, libbpfjit_cop_ret_preinited_mem);
+ ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_mem);
+ ATF_TP_ADD_TC(tp, libbpfjit_copx_ret_preinited_mem);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c
new file mode 100644
index 0000000..56a1be8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2014/08/10 05:47:38 matt Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/08/10 05:47:38 matt Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S
new file mode 100644
index 0000000..d237982
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S
@@ -0,0 +1,10 @@
+/* $NetBSD: return_one.S,v 1.1 2014/08/10 05:47:38 matt Exp $ */
+
+#include <machine/asm.h>
+
+ENTRY_NP(return_one)
+ mov x0, #1
+ ret
+ .globl return_one_end
+return_one_end:
+END(return_one)
diff --git a/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c
new file mode 100644
index 0000000..ba1cd8b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S b/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S
new file mode 100644
index 0000000..5308876
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S
@@ -0,0 +1,8 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end;
+
+return_one: return_one_end:
+ nop
diff --git a/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c
new file mode 100644
index 0000000..ba1cd8b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S b/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S
new file mode 100644
index 0000000..18800e2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/arm/return_one.S
@@ -0,0 +1,11 @@
+/* $NetBSD: return_one.S,v 1.2 2014/01/26 20:42:06 matt Exp $ */
+
+#include <machine/asm.h>
+
+ENTRY_NP(return_one)
+ mov r0, #1
+ RET
+ .align 0
+ .globl return_one_end
+return_one_end:
+END(return_one)
diff --git a/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c
new file mode 100644
index 0000000..ba1cd8b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S b/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S
new file mode 100644
index 0000000..5308876
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S
@@ -0,0 +1,8 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end;
+
+return_one: return_one_end:
+ nop
diff --git a/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c
new file mode 100644
index 0000000..11a20f5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c
@@ -0,0 +1,65 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $");
+
+#include <stdlib.h>
+#include <sys/sysctl.h>
+
+#include "../../common/exec_prot.h"
+
+/*
+ * Support for executable space protection has always been erratic under i386.
+ * Originally IA-32 can't do per-page execute permission, so it is
+ * implemented using different executable segments for %cs (code segment).
+ * This only allows coarse grained protection, especially when memory starts
+ * being fragmented.
+ * Later, PAE was introduced together with a NX/XD bit in the page table
+ * entry to offer per-page permission.
+ */
+int
+exec_prot_support(void)
+{
+ int pae;
+ size_t pae_len = sizeof(pae);
+
+ if (sysctlbyname("machdep.pae", &pae, &pae_len, NULL, 0) == -1)
+ return PARTIAL_XP;
+
+ if (pae == 1) {
+ if (system("cpuctl identify 0 | grep -q NOX") == 0 ||
+ system("cpuctl identify 0 | grep -q XD") == 0)
+ return PERPAGE_XP;
+ }
+
+ return PARTIAL_XP;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S b/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S
new file mode 100644
index 0000000..f80fd74
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/i386/return_one.S
@@ -0,0 +1,10 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $");
+
+_ENTRY(return_one)
+ movl $0x1,%eax
+ ret
+LABEL(return_one_end)
diff --git a/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c
new file mode 100644
index 0000000..ba1cd8b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S
new file mode 100644
index 0000000..5308876
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S
@@ -0,0 +1,8 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end;
+
+return_one: return_one_end:
+ nop
diff --git a/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c
new file mode 100644
index 0000000..ba1cd8b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:09 jym Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S b/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S
new file mode 100644
index 0000000..5308876
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S
@@ -0,0 +1,8 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:09 jym Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end;
+
+return_one: return_one_end:
+ nop
diff --git a/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c
new file mode 100644
index 0000000..474cfc7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S b/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S
new file mode 100644
index 0000000..3495260
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/mips/return_one.S
@@ -0,0 +1,8 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end;
+
+return_one: return_one_end:
+ nop
diff --git a/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c
new file mode 100644
index 0000000..623456b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2014/09/03 19:34:26 matt Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/09/03 19:34:26 matt Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return PERPAGE_XP;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S b/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S
new file mode 100644
index 0000000..ba3d678
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S
@@ -0,0 +1,12 @@
+/* $NetBSD: return_one.S,v 1.1 2014/09/03 19:34:26 matt Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end
+
+ENTRY_NP(return_one)
+ l.addi r11, r0, 1
+ l.jr lr
+ l.nop
+return_one_end:
+END(return_one)
diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c
new file mode 100644
index 0000000..81c1d86
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c
@@ -0,0 +1,52 @@
+/* $NetBSD: exec_prot_support.c,v 1.2 2012/03/16 08:51:47 matt Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.2 2012/03/16 08:51:47 matt Exp $");
+
+#include "../../common/exec_prot.h"
+
+#include <sys/sysctl.h>
+
+int
+exec_prot_support(void)
+{
+ int execprot = 0;
+ size_t len = sizeof(execprot);
+
+ if (sysctlbyname("machdep.execprot", &execprot, &len, NULL, 0) < 0)
+ return NOTIMPL;
+
+ if (execprot)
+ return PERPAGE_XP;
+
+ return NO_XP;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S b/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S
new file mode 100644
index 0000000..d40298e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S
@@ -0,0 +1,11 @@
+/* $NetBSD: return_one.S,v 1.2 2012/03/16 08:51:47 matt Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end
+
+_ENTRY(return_one)
+ li %r3, 1
+ blr
+return_one_end:
+END(return_one)
diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c
new file mode 100644
index 0000000..474cfc7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S
new file mode 100644
index 0000000..3495260
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S
@@ -0,0 +1,8 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end;
+
+return_one: return_one_end:
+ nop
diff --git a/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c
new file mode 100644
index 0000000..91c5ff4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2014/09/19 17:36:26 matt Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2014/09/19 17:36:26 matt Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return PERPAGE_XP;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S b/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S
new file mode 100644
index 0000000..43ddd2c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S
@@ -0,0 +1,11 @@
+/* $NetBSD: return_one.S,v 1.1 2014/09/19 17:36:26 matt Exp $ */
+
+#include <machine/asm.h>
+
+ .globl return_one_end
+
+ENTRY_NP(return_one)
+ li v0, 1
+ ret
+return_one_end:
+END(return_one)
diff --git a/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c
new file mode 100644
index 0000000..474cfc7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S
new file mode 100644
index 0000000..3495260
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S
@@ -0,0 +1,8 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end;
+
+return_one: return_one_end:
+ nop
diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c
new file mode 100644
index 0000000..474cfc7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S
new file mode 100644
index 0000000..3495260
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S
@@ -0,0 +1,8 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end;
+
+return_one: return_one_end:
+ nop
diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c
new file mode 100644
index 0000000..474cfc7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S
new file mode 100644
index 0000000..3495260
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S
@@ -0,0 +1,8 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end;
+
+return_one: return_one_end:
+ nop
diff --git a/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c
new file mode 100644
index 0000000..474cfc7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c
@@ -0,0 +1,41 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:10 jym Exp $");
+
+#include "../../common/exec_prot.h"
+
+int
+exec_prot_support(void)
+{
+ return NOTIMPL;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S b/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S
new file mode 100644
index 0000000..3495260
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/vax/return_one.S
@@ -0,0 +1,8 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:10 jym Exp $ */
+
+#include <machine/asm.h>
+
+.globl return_one, return_one_end;
+
+return_one: return_one_end:
+ nop
diff --git a/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c b/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c
new file mode 100644
index 0000000..2d8363d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c
@@ -0,0 +1,50 @@
+/* $NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:11 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: exec_prot_support.c,v 1.1 2011/07/18 23:16:11 jym Exp $");
+
+#include <stdlib.h>
+
+#include "../../common/exec_prot.h"
+
+/*
+ * When the NX/XD flag is present, the protection should be enabled.
+ */
+int
+exec_prot_support(void)
+{
+ if (system("cpuctl identify 0 | grep -q NOX") == 0 ||
+ system("cpuctl identify 0 | grep -q XD") == 0)
+ return PERPAGE_XP;
+
+ return NO_XP;
+}
diff --git a/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S b/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S
new file mode 100644
index 0000000..0903001
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S
@@ -0,0 +1,10 @@
+/* $NetBSD: return_one.S,v 1.1 2011/07/18 23:16:11 jym Exp $ */
+
+#include <machine/asm.h>
+
+RCSID("$NetBSD: return_one.S,v 1.1 2011/07/18 23:16:11 jym Exp $");
+
+_ENTRY(return_one)
+ movq $0x1, %rax
+ retq
+LABEL(return_one_end)
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c b/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c
new file mode 100644
index 0000000..c9e0cc8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_faccessat.c
@@ -0,0 +1,185 @@
+/* $NetBSD: t_faccessat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_faccessat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#define DIR "dir"
+#define FILE "dir/faccessat"
+#define BASEFILE "faccessat"
+#define LINK "dir/symlink"
+#define BASELINK "symlink"
+#define FILEERR "dir/faccessaterr"
+
+ATF_TC(faccessat_fd);
+ATF_TC_HEAD(faccessat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that faccessat works with fd");
+}
+ATF_TC_BODY(faccessat_fd, tc)
+{
+ int dfd;
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(faccessat(dfd, BASEFILE, F_OK, 0) == 0);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(faccessat_fdcwd);
+ATF_TC_HEAD(faccessat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that faccessat works with fd as AT_FDCWD");
+}
+ATF_TC_BODY(faccessat_fdcwd, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(chdir(DIR) == 0);
+ ATF_REQUIRE(faccessat(AT_FDCWD, BASEFILE, F_OK, 0) == 0);
+}
+
+ATF_TC(faccessat_fdcwderr);
+ATF_TC_HEAD(faccessat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that faccessat fails with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(faccessat_fdcwderr, tc)
+{
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(faccessat(AT_FDCWD, FILEERR, F_OK, 0) == -1);
+}
+
+ATF_TC(faccessat_fderr1);
+ATF_TC_HEAD(faccessat_fderr1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that faccessat fail with bad path");
+}
+ATF_TC_BODY(faccessat_fderr1, tc)
+{
+ int dfd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(faccessat(dfd, FILEERR, F_OK, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(faccessat_fderr2);
+ATF_TC_HEAD(faccessat_fderr2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that faccessat fails with bad fdat");
+}
+ATF_TC_BODY(faccessat_fderr2, tc)
+{
+ int dfd;
+ int fd;
+ char cwd[MAXPATHLEN];
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(faccessat(dfd, BASEFILE, F_OK, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(faccessat_fderr3);
+ATF_TC_HEAD(faccessat_fderr3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that faccessat fails with fd as -1");
+}
+ATF_TC_BODY(faccessat_fderr3, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(faccessat(-1, FILE, F_OK, 0) == -1);
+}
+
+ATF_TC(faccessat_fdlink);
+ATF_TC_HEAD(faccessat_fdlink, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that faccessat works on symlink");
+}
+ATF_TC_BODY(faccessat_fdlink, tc)
+{
+ int dfd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(symlink(FILE, LINK) == 0); /* NB: FILE does not exists */
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+
+ ATF_REQUIRE(faccessat(dfd, BASELINK, F_OK, 0) == -1);
+ ATF_REQUIRE(errno == ENOENT);
+
+ ATF_REQUIRE(faccessat(dfd, BASELINK, F_OK, AT_SYMLINK_NOFOLLOW) == 0);
+
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, faccessat_fd);
+ ATF_TP_ADD_TC(tp, faccessat_fdcwd);
+ ATF_TP_ADD_TC(tp, faccessat_fdcwderr);
+ ATF_TP_ADD_TC(tp, faccessat_fderr1);
+ ATF_TP_ADD_TC(tp, faccessat_fderr2);
+ ATF_TP_ADD_TC(tp, faccessat_fderr3);
+ ATF_TP_ADD_TC(tp, faccessat_fdlink);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c b/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c
new file mode 100644
index 0000000..462d53d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c
@@ -0,0 +1,197 @@
+/* $NetBSD: t_fchmodat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_fchmodat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#define DIR "dir"
+#define FILE "dir/fchmodat"
+#define BASEFILE "fchmodat"
+#define LINK "dir/symlink"
+#define BASELINK "symlink"
+#define FILEERR "dir/fchmodaterr"
+
+ATF_TC(fchmodat_fd);
+ATF_TC_HEAD(fchmodat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fchmodat works with fd");
+}
+ATF_TC_BODY(fchmodat_fd, tc)
+{
+ int dfd;
+ int fd;
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(fchmodat(dfd, BASEFILE, 0600, 0) == 0);
+ ATF_REQUIRE(close(dfd) == 0);
+
+ ATF_REQUIRE(stat(FILE, &st) == 0);
+ ATF_REQUIRE(st.st_mode = 0600);
+}
+
+ATF_TC(fchmodat_fdcwd);
+ATF_TC_HEAD(fchmodat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that fchmodat works with fd as AT_FDCWD");
+}
+ATF_TC_BODY(fchmodat_fdcwd, tc)
+{
+ int fd;
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(chdir(DIR) == 0);
+ ATF_REQUIRE(fchmodat(AT_FDCWD, BASEFILE, 0600, 0) == 0);
+
+ ATF_REQUIRE(stat(BASEFILE, &st) == 0);
+ ATF_REQUIRE(st.st_mode = 0600);
+}
+
+ATF_TC(fchmodat_fdcwderr);
+ATF_TC_HEAD(fchmodat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that fchmodat fails with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(fchmodat_fdcwderr, tc)
+{
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(fchmodat(AT_FDCWD, FILEERR, 0600, 0) == -1);
+}
+
+ATF_TC(fchmodat_fderr1);
+ATF_TC_HEAD(fchmodat_fderr1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fchmodat fail with bad path");
+}
+ATF_TC_BODY(fchmodat_fderr1, tc)
+{
+ int dfd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(fchmodat(dfd, FILEERR, 0600, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(fchmodat_fderr2);
+ATF_TC_HEAD(fchmodat_fderr2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fchmodat fails with bad fdat");
+}
+ATF_TC_BODY(fchmodat_fderr2, tc)
+{
+ int dfd;
+ int fd;
+ char cwd[MAXPATHLEN];
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(fchmodat(dfd, BASEFILE, 0600, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(fchmodat_fderr3);
+ATF_TC_HEAD(fchmodat_fderr3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fchmodat fails with fd as -1");
+}
+ATF_TC_BODY(fchmodat_fderr3, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(fchmodat(-1, FILE, 0600, 0) == -1);
+}
+
+ATF_TC(fchmodat_fdlink);
+ATF_TC_HEAD(fchmodat_fdlink, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fchmodat works on symlink");
+}
+ATF_TC_BODY(fchmodat_fdlink, tc)
+{
+ int dfdlink;
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(symlink(FILE, LINK) == 0);
+
+ ATF_REQUIRE((dfdlink = open(DIR, O_RDONLY, 0)) != -1);
+
+ ATF_REQUIRE(fchmodat(dfdlink, BASELINK, 0600, 0) == -1);
+ ATF_REQUIRE(errno = ENOENT);
+
+ ATF_REQUIRE(fchmodat(dfdlink, BASELINK, 0600, AT_SYMLINK_NOFOLLOW) == 0);
+
+ ATF_REQUIRE(close(dfdlink) == 0);
+
+ ATF_REQUIRE(lstat(LINK, &st) == 0);
+ ATF_REQUIRE(st.st_mode = 0600);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fchmodat_fd);
+ ATF_TP_ADD_TC(tp, fchmodat_fdcwd);
+ ATF_TP_ADD_TC(tp, fchmodat_fdcwderr);
+ ATF_TP_ADD_TC(tp, fchmodat_fderr1);
+ ATF_TP_ADD_TC(tp, fchmodat_fderr2);
+ ATF_TP_ADD_TC(tp, fchmodat_fderr3);
+ ATF_TP_ADD_TC(tp, fchmodat_fdlink);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c b/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c
new file mode 100644
index 0000000..80c7606
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_fchownat.c
@@ -0,0 +1,247 @@
+/* $NetBSD: t_fchownat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_fchownat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/param.h>
+
+#define DIR "dir"
+#define FILE "dir/fchownat"
+#define BASEFILE "fchownat"
+#define LINK "dir/symlink"
+#define BASELINK "symlink"
+#define FILEERR "dir/fchownaterr"
+#define USER "nobody"
+
+static int getuser(uid_t *, gid_t *);
+
+static int getuser(uid_t *uid, gid_t *gid)
+{
+ struct passwd *pw;
+
+ if ((pw = getpwnam(USER)) == NULL)
+ return -1;
+
+ *uid = pw->pw_uid;
+ *gid = pw->pw_gid;
+
+ return 0;
+}
+
+ATF_TC(fchownat_fd);
+ATF_TC_HEAD(fchownat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fchownat works with fd");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(fchownat_fd, tc)
+{
+ int dfd;
+ int fd;
+ uid_t uid;
+ gid_t gid;
+ struct stat st;
+
+ ATF_REQUIRE(getuser(&uid, &gid) == 0);
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(fchownat(dfd, BASEFILE, uid, gid, 0) == 0);
+ ATF_REQUIRE(close(dfd) == 0);
+
+ ATF_REQUIRE(stat(FILE, &st) == 0);
+ ATF_REQUIRE(st.st_uid == uid);
+ ATF_REQUIRE(st.st_gid == gid);
+}
+
+ATF_TC(fchownat_fdcwd);
+ATF_TC_HEAD(fchownat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that fchownat works with fd as AT_FDCWD");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(fchownat_fdcwd, tc)
+{
+ int fd;
+ uid_t uid;
+ gid_t gid;
+ struct stat st;
+
+ ATF_REQUIRE(getuser(&uid, &gid) == 0);
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(chdir(DIR) == 0);
+ ATF_REQUIRE(fchownat(AT_FDCWD, BASEFILE, uid, gid, 0) == 0);
+
+ ATF_REQUIRE(stat(BASEFILE, &st) == 0);
+ ATF_REQUIRE(st.st_uid == uid);
+ ATF_REQUIRE(st.st_gid == gid);
+}
+
+ATF_TC(fchownat_fdcwderr);
+ATF_TC_HEAD(fchownat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that fchownat fails with fd as AT_FDCWD and bad path");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(fchownat_fdcwderr, tc)
+{
+ uid_t uid;
+ gid_t gid;
+
+ ATF_REQUIRE(getuser(&uid, &gid) == 0);
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(fchownat(AT_FDCWD, FILEERR, uid, gid, 0) == -1);
+}
+
+ATF_TC(fchownat_fderr1);
+ATF_TC_HEAD(fchownat_fderr1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fchownat fail with bad path");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(fchownat_fderr1, tc)
+{
+ int dfd;
+ uid_t uid;
+ gid_t gid;
+
+ ATF_REQUIRE(getuser(&uid, &gid) == 0);
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(fchownat(dfd, FILEERR, uid, gid, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(fchownat_fderr2);
+ATF_TC_HEAD(fchownat_fderr2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fchownat fails with bad fdat");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(fchownat_fderr2, tc)
+{
+ int dfd;
+ int fd;
+ char cwd[MAXPATHLEN];
+ uid_t uid;
+ gid_t gid;
+
+ ATF_REQUIRE(getuser(&uid, &gid) == 0);
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(fchownat(dfd, BASEFILE, uid, gid, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(fchownat_fderr3);
+ATF_TC_HEAD(fchownat_fderr3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fchownat fails with fd as -1");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(fchownat_fderr3, tc)
+{
+ int fd;
+ uid_t uid;
+ gid_t gid;
+
+ ATF_REQUIRE(getuser(&uid, &gid) == 0);
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(fchownat(-1, FILE, uid, gid, 0) == -1);
+}
+
+ATF_TC(fchownat_fdlink);
+ATF_TC_HEAD(fchownat_fdlink, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fchownat works on symlink");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(fchownat_fdlink, tc)
+{
+ int dfd;
+ uid_t uid;
+ gid_t gid;
+ struct stat st;
+
+ ATF_REQUIRE(getuser(&uid, &gid) == 0);
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(symlink(FILE, LINK) == 0); /* Target does not exists */
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+
+ ATF_REQUIRE(fchownat(dfd, BASELINK, uid, gid, 0) == -1);
+ ATF_REQUIRE(errno == ENOENT);
+
+ ATF_REQUIRE(fchownat(dfd, BASELINK, uid, gid,
+ AT_SYMLINK_NOFOLLOW) == 0);
+
+ ATF_REQUIRE(close(dfd) == 0);
+
+ ATF_REQUIRE(lstat(LINK, &st) == 0);
+ ATF_REQUIRE(st.st_uid == uid);
+ ATF_REQUIRE(st.st_gid == gid);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fchownat_fd);
+ ATF_TP_ADD_TC(tp, fchownat_fdcwd);
+ ATF_TP_ADD_TC(tp, fchownat_fdcwderr);
+ ATF_TP_ADD_TC(tp, fchownat_fderr1);
+ ATF_TP_ADD_TC(tp, fchownat_fderr2);
+ ATF_TP_ADD_TC(tp, fchownat_fderr3);
+ ATF_TP_ADD_TC(tp, fchownat_fdlink);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c b/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c
new file mode 100644
index 0000000..d557b00
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_fexecve.c
@@ -0,0 +1,94 @@
+/* $NetBSD: t_fexecve.c,v 1.2 2013/03/17 04:35:59 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_fexecve.c,v 1.2 2013/03/17 04:35:59 jmmv Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+ATF_TC(fexecve);
+ATF_TC_HEAD(fexecve, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fexecve works");
+}
+ATF_TC_BODY(fexecve, tc)
+{
+ int status;
+ pid_t pid;
+ const char *const argv[] = { "touch", "test", NULL };
+ const char *const envp[] = { NULL };
+
+ ATF_REQUIRE((pid = fork()) != -1);
+ if (pid == 0) {
+ int fd;
+
+ if ((fd = open("/usr/bin/touch", O_RDONLY, 0)) == -1)
+ err(EXIT_FAILURE, "open /usr/bin/touch");
+
+ if (fexecve(fd, __UNCONST(argv), __UNCONST(envp)) == -1) {
+ int error;
+ if (errno == ENOSYS)
+ error = 76;
+ else
+ error = EXIT_FAILURE;
+ err(error, "fexecve");
+ }
+ }
+
+ ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
+ if (!WIFEXITED(status))
+ atf_tc_fail("child process did not exit cleanly");
+ if (WEXITSTATUS(status) == 76)
+ atf_tc_expect_fail("fexecve not implemented");
+ else
+ ATF_REQUIRE(WEXITSTATUS(status) == EXIT_SUCCESS);
+
+ ATF_REQUIRE(access("test", F_OK) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fexecve);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c b/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c
new file mode 100644
index 0000000..a48cd57
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_fstatat.c
@@ -0,0 +1,196 @@
+/* $NetBSD: t_fstatat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_fstatat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#define DIR "dir"
+#define FILE "dir/fstatat"
+#define BASEFILE "fstatat"
+#define LINK "dir/symlink"
+#define BASELINK "symlink"
+#define FILEERR "dir/symlink"
+
+ATF_TC(fstatat_fd);
+ATF_TC_HEAD(fstatat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fstatat works with fd");
+}
+ATF_TC_BODY(fstatat_fd, tc)
+{
+ int dfd;
+ int fd;
+ struct stat st1, st2;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(fstatat(dfd, BASEFILE, &st1, 0) == 0);
+ ATF_REQUIRE(close(dfd) == 0);
+
+ ATF_REQUIRE(stat(FILE, &st2) == 0);
+ ATF_REQUIRE(memcmp(&st1, &st2, sizeof(st1)) == 0);
+}
+
+ATF_TC(fstatat_fdcwd);
+ATF_TC_HEAD(fstatat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that fstatat works with fd as AT_FDCWD");
+}
+ATF_TC_BODY(fstatat_fdcwd, tc)
+{
+ int fd;
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(chdir(DIR) == 0);
+ ATF_REQUIRE(fstatat(AT_FDCWD, BASEFILE, &st, 0) == 0);
+}
+
+ATF_TC(fstatat_fdcwderr);
+ATF_TC_HEAD(fstatat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that fstatat fails with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(fstatat_fdcwderr, tc)
+{
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(fstatat(AT_FDCWD, FILEERR, &st, 0) == -1);
+}
+
+ATF_TC(fstatat_fderr1);
+ATF_TC_HEAD(fstatat_fderr1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fstatat fail with bad path");
+}
+ATF_TC_BODY(fstatat_fderr1, tc)
+{
+ int dfd;
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(fstatat(dfd, FILEERR, &st, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(fstatat_fderr2);
+ATF_TC_HEAD(fstatat_fderr2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fstatat fails with bad fdat");
+}
+ATF_TC_BODY(fstatat_fderr2, tc)
+{
+ int dfd;
+ int fd;
+ char cwd[MAXPATHLEN];
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(fstatat(dfd, BASEFILE, &st, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(fstatat_fderr3);
+ATF_TC_HEAD(fstatat_fderr3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fstatat fails with fd as -1");
+}
+ATF_TC_BODY(fstatat_fderr3, tc)
+{
+ int fd;
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(fstatat(-1, FILE, &st, 0) == -1);
+}
+
+ATF_TC(fstatat_fdlink);
+ATF_TC_HEAD(fstatat_fdlink, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fstatat works on symlink");
+}
+ATF_TC_BODY(fstatat_fdlink, tc)
+{
+ int dfd;
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(symlink(FILE, LINK) == 0); /* target does not exists */
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+
+ ATF_REQUIRE(fstatat(dfd, BASELINK, &st, 0) == -1);
+ ATF_REQUIRE(errno == ENOENT);
+
+ ATF_REQUIRE(fstatat(dfd, BASELINK, &st, AT_SYMLINK_NOFOLLOW) == 0);
+
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fstatat_fd);
+ ATF_TP_ADD_TC(tp, fstatat_fdcwd);
+ ATF_TP_ADD_TC(tp, fstatat_fdcwderr);
+ ATF_TP_ADD_TC(tp, fstatat_fderr1);
+ ATF_TP_ADD_TC(tp, fstatat_fderr2);
+ ATF_TP_ADD_TC(tp, fstatat_fderr3);
+ ATF_TP_ADD_TC(tp, fstatat_fdlink);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_linkat.c b/contrib/netbsd-tests/lib/libc/c063/t_linkat.c
new file mode 100644
index 0000000..b49a3f0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_linkat.c
@@ -0,0 +1,217 @@
+/* $NetBSD: t_linkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_linkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#define ODIR "olddir"
+#define NDIR "newdir"
+#define FILE "olddir/old"
+#define BASEFILE "old"
+#define RELFILE "../olddir/old"
+#define TARGET "newdir/new"
+#define BASETARGET "new"
+#define LINK "olddir/symlink"
+#define BASELINK "symlink"
+#define FILEERR "olddir/olderr"
+
+ATF_TC(linkat_fd);
+ATF_TC_HEAD(linkat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that linkat works with fd");
+}
+ATF_TC_BODY(linkat_fd, tc)
+{
+ int ofd, nfd, fd;
+ struct stat ost, nst;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(linkat(ofd, BASEFILE, nfd, BASETARGET, 0) == 0);
+ ATF_REQUIRE(close(ofd) == 0);
+ ATF_REQUIRE(close(nfd) == 0);
+
+ ATF_REQUIRE(stat(FILE, &ost) == 0);
+ ATF_REQUIRE(stat(TARGET, &nst) == 0);
+ ATF_REQUIRE(ost.st_ino == nst.st_ino);
+}
+
+ATF_TC(linkat_fdcwd);
+ATF_TC_HEAD(linkat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that linkat works with fd as AT_FDCWD");
+}
+ATF_TC_BODY(linkat_fdcwd, tc)
+{
+ int fd;
+ struct stat ost, nst;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE(linkat(AT_FDCWD, FILE, AT_FDCWD, TARGET, 0) == 0);
+
+ ATF_REQUIRE(stat(FILE, &ost) == 0);
+ ATF_REQUIRE(stat(TARGET, &nst) == 0);
+ ATF_REQUIRE(ost.st_ino == nst.st_ino);
+}
+
+ATF_TC(linkat_fdcwderr);
+ATF_TC_HEAD(linkat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that linkat fails with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(linkat_fdcwderr, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE(linkat(AT_FDCWD, FILEERR, AT_FDCWD, TARGET, 0) == -1);
+}
+
+ATF_TC(linkat_fderr);
+ATF_TC_HEAD(linkat_fderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that linkat fails with fd as -1");
+}
+ATF_TC_BODY(linkat_fderr, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE(linkat(-1, FILE, AT_FDCWD, TARGET, 0) == -1);
+ ATF_REQUIRE(linkat(AT_FDCWD, FILE, -1, TARGET, 0) == -1);
+ ATF_REQUIRE(linkat(-1, FILE, -1, TARGET, 0) == -1);
+}
+
+ATF_TC(linkat_fdlink1);
+ATF_TC_HEAD(linkat_fdlink1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that linkat works on symlink target");
+}
+ATF_TC_BODY(linkat_fdlink1, tc)
+{
+ int ofd, nfd, fd;
+ struct stat ost, nst;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+ ATF_REQUIRE(symlink(RELFILE, LINK) == 0);
+
+ ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(linkat(ofd, BASELINK, nfd, BASETARGET,
+ AT_SYMLINK_FOLLOW) == 0);
+ ATF_REQUIRE(close(ofd) == 0);
+ ATF_REQUIRE(close(nfd) == 0);
+
+ ATF_REQUIRE(lstat(LINK, &ost) == 0);
+ ATF_REQUIRE(lstat(TARGET, &nst) == 0);
+ ATF_REQUIRE(ost.st_ino != nst.st_ino);
+
+ ATF_REQUIRE(lstat(FILE, &ost) == 0);
+ ATF_REQUIRE(lstat(TARGET, &nst) == 0);
+ ATF_REQUIRE(ost.st_ino == nst.st_ino);
+}
+
+
+ATF_TC(linkat_fdlink2);
+ATF_TC_HEAD(linkat_fdlink2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that linkat works on symlink source");
+}
+ATF_TC_BODY(linkat_fdlink2, tc)
+{
+ int ofd, nfd, fd;
+ struct stat ost, nst;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+ ATF_REQUIRE(symlink(RELFILE, LINK) == 0);
+
+ ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(linkat(ofd, BASELINK, nfd, BASETARGET, 0) == 0);
+ ATF_REQUIRE(close(ofd) == 0);
+ ATF_REQUIRE(close(nfd) == 0);
+
+ ATF_REQUIRE(lstat(LINK, &ost) == 0);
+ ATF_REQUIRE(lstat(TARGET, &nst) == 0);
+ ATF_REQUIRE(ost.st_ino == nst.st_ino);
+
+ ATF_REQUIRE(lstat(FILE, &ost) == 0);
+ ATF_REQUIRE(lstat(TARGET, &nst) == 0);
+ ATF_REQUIRE(ost.st_ino != nst.st_ino);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, linkat_fd);
+ ATF_TP_ADD_TC(tp, linkat_fdcwd);
+ ATF_TP_ADD_TC(tp, linkat_fdcwderr);
+ ATF_TP_ADD_TC(tp, linkat_fderr);
+ ATF_TP_ADD_TC(tp, linkat_fdlink1);
+ ATF_TP_ADD_TC(tp, linkat_fdlink2);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c b/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c
new file mode 100644
index 0000000..23c53d7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c
@@ -0,0 +1,120 @@
+/* $NetBSD: t_mkdirat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_mkdirat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#define DIR "dir"
+#define SDIR "dir/openat"
+#define BASESDIR "openat"
+#define SDIRERR "dir/openaterr"
+
+ATF_TC(mkdirat_fd);
+ATF_TC_HEAD(mkdirat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that mkdirat works with fd");
+}
+ATF_TC_BODY(mkdirat_fd, tc)
+{
+ int dfd;
+ mode_t mode = 0755;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(mkdirat(dfd, BASESDIR, mode) != -1);
+ ATF_REQUIRE(close(dfd) == 0);
+ ATF_REQUIRE(access(SDIR, F_OK) == 0);
+}
+
+ATF_TC(mkdirat_fdcwd);
+ATF_TC_HEAD(mkdirat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that mkdirat works with fd as AT_FDCWD");
+}
+ATF_TC_BODY(mkdirat_fdcwd, tc)
+{
+ mode_t mode = 0755;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(mkdirat(AT_FDCWD, SDIR, mode) != -1);
+ ATF_REQUIRE(access(SDIR, F_OK) == 0);
+}
+
+ATF_TC(mkdirat_fdcwderr);
+ATF_TC_HEAD(mkdirat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that mkdirat fails with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(mkdirat_fdcwderr, tc)
+{
+ mode_t mode = 0755;
+
+ ATF_REQUIRE(mkdirat(AT_FDCWD, SDIRERR, mode) == -1);
+}
+
+ATF_TC(mkdirat_fderr);
+ATF_TC_HEAD(mkdirat_fderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that mkdirat fails with fd as -1");
+}
+ATF_TC_BODY(mkdirat_fderr, tc)
+{
+ int fd;
+ mode_t mode = 0755;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(SDIR, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(mkdirat(-1, SDIR, mode) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mkdirat_fd);
+ ATF_TP_ADD_TC(tp, mkdirat_fdcwd);
+ ATF_TP_ADD_TC(tp, mkdirat_fdcwderr);
+ ATF_TP_ADD_TC(tp, mkdirat_fderr);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c b/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c
new file mode 100644
index 0000000..1ae023c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c
@@ -0,0 +1,124 @@
+/* $NetBSD: t_mkfifoat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_mkfifoat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#define DIR "dir"
+#define FIFO "dir/openat"
+#define BASEFIFO "openat"
+#define FIFOERR "dir/openaterr"
+
+ATF_TC(mkfifoat_fd);
+ATF_TC_HEAD(mkfifoat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that mkfifoat works with fd");
+}
+ATF_TC_BODY(mkfifoat_fd, tc)
+{
+ int dfd;
+ int fd;
+ mode_t mode = 0600;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE((fd = mkfifoat(dfd, BASEFIFO, mode)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(access(FIFO, F_OK) == 0);
+}
+
+ATF_TC(mkfifoat_fdcwd);
+ATF_TC_HEAD(mkfifoat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that mkfifoat works with fd as AT_FDCWD");
+}
+ATF_TC_BODY(mkfifoat_fdcwd, tc)
+{
+ int fd;
+ mode_t mode = 0600;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = mkfifoat(AT_FDCWD, FIFO, mode)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(access(FIFO, F_OK) == 0);
+}
+
+ATF_TC(mkfifoat_fdcwderr);
+ATF_TC_HEAD(mkfifoat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that mkfifoat fails with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(mkfifoat_fdcwderr, tc)
+{
+ int fd;
+ mode_t mode = 0600;
+
+ ATF_REQUIRE((fd = mkfifoat(AT_FDCWD, FIFOERR, mode)) == -1);
+}
+
+ATF_TC(mkfifoat_fderr);
+ATF_TC_HEAD(mkfifoat_fderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that mkfifoat fails with fd as -1");
+}
+ATF_TC_BODY(mkfifoat_fderr, tc)
+{
+ int fd;
+ mode_t mode = 0600;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FIFO, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE((fd = mkfifoat(-1, FIFO, mode)) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mkfifoat_fd);
+ ATF_TP_ADD_TC(tp, mkfifoat_fdcwd);
+ ATF_TP_ADD_TC(tp, mkfifoat_fdcwderr);
+ ATF_TP_ADD_TC(tp, mkfifoat_fderr);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c b/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c
new file mode 100644
index 0000000..b04a159
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_mknodat.c
@@ -0,0 +1,150 @@
+/* $NetBSD: t_mknodat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_mknodat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#define DIR "dir"
+#define FILE "dir/openat"
+#define BASEFILE "openat"
+#define FILEERR "dir/openaterr"
+
+static dev_t get_devnull(void);
+
+static dev_t
+get_devnull(void)
+{
+ struct stat st;
+
+ if (stat(_PATH_DEVNULL, &st) != 0)
+ return NODEV;
+
+ return st.st_rdev;
+}
+
+
+ATF_TC(mknodat_fd);
+ATF_TC_HEAD(mknodat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that mknodat works with fd");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(mknodat_fd, tc)
+{
+ int dfd;
+ int fd;
+ dev_t dev;
+ mode_t mode = S_IFCHR|0600;
+
+ ATF_REQUIRE((dev = get_devnull()) != NODEV);
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE((fd = mknodat(dfd, BASEFILE, mode, dev)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(access(FILE, F_OK) == 0);
+}
+
+ATF_TC(mknodat_fdcwd);
+ATF_TC_HEAD(mknodat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that mknodat works with fd as AT_FDCWD");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(mknodat_fdcwd, tc)
+{
+ int fd;
+ dev_t dev;
+ mode_t mode = S_IFCHR|0600;
+
+ ATF_REQUIRE((dev = get_devnull()) != NODEV);
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = mknodat(AT_FDCWD, FILE, mode, dev)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(access(FILE, F_OK) == 0);
+}
+
+ATF_TC(mknodat_fdcwderr);
+ATF_TC_HEAD(mknodat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that mknodat fails with fd as AT_FDCWD and bad path");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(mknodat_fdcwderr, tc)
+{
+ int fd;
+ dev_t dev;
+ mode_t mode = S_IFCHR|0600;
+
+ ATF_REQUIRE((dev = get_devnull()) != NODEV);
+ ATF_REQUIRE((fd = mknodat(AT_FDCWD, FILEERR, mode, dev)) == -1);
+}
+
+ATF_TC(mknodat_fderr);
+ATF_TC_HEAD(mknodat_fderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that mknodat fails with fd as -1");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(mknodat_fderr, tc)
+{
+ int fd;
+ dev_t dev;
+ mode_t mode = S_IFCHR|0600;
+
+ ATF_REQUIRE((dev = get_devnull()) != NODEV);
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE((fd = mknodat(-1, FILE, mode, dev)) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mknodat_fd);
+ ATF_TP_ADD_TC(tp, mknodat_fdcwd);
+ ATF_TP_ADD_TC(tp, mknodat_fdcwderr);
+ ATF_TP_ADD_TC(tp, mknodat_fderr);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_o_search.c b/contrib/netbsd-tests/lib/libc/c063/t_o_search.c
new file mode 100644
index 0000000..d9dbe19
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_o_search.c
@@ -0,0 +1,278 @@
+/* $NetBSD: t_o_search.c,v 1.4 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_o_search.c,v 1.4 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/param.h>
+
+/*
+ * dholland 20130112: disable tests that require O_SEARCH semantics
+ * until a decision is reached about the semantics of O_SEARCH and a
+ * non-broken implementation is available.
+ */
+#if (O_MASK & O_SEARCH) != 0
+#define USE_O_SEARCH
+#endif
+
+#define DIR "dir"
+#define FILE "dir/o_search"
+#define BASEFILE "o_search"
+
+
+ATF_TC(o_search_perm1);
+ATF_TC_HEAD(o_search_perm1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that openat enforces search permission");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+ATF_TC_BODY(o_search_perm1, tc)
+{
+ int dfd;
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+
+ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(fchmod(dfd, 644) == 0);
+
+ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) == -1);
+ ATF_REQUIRE(errno == EACCES);
+
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+#ifdef USE_O_SEARCH
+
+ATF_TC(o_search_root_flag1);
+ATF_TC_HEAD(o_search_root_flag1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that root openat honours O_SEARCH");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(o_search_root_flag1, tc)
+{
+ int dfd;
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1);
+
+ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(fchmod(dfd, 644) == 0);
+
+ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(fchmod(dfd, 444) == 0);
+
+ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1);
+
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(o_search_unpriv_flag1);
+ATF_TC_HEAD(o_search_unpriv_flag1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that openat honours O_SEARCH");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+ATF_TC_BODY(o_search_unpriv_flag1, tc)
+{
+ int dfd;
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1);
+
+ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(fchmod(dfd, 644) == 0);
+
+ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(fchmod(dfd, 444) == 0);
+
+ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) != -1);
+
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+#endif /* USE_O_SEARCH */
+
+ATF_TC(o_search_perm2);
+ATF_TC_HEAD(o_search_perm2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that faccessat enforces search permission");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+ATF_TC_BODY(o_search_perm2, tc)
+{
+ int dfd;
+ int fd;
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+
+ ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0);
+
+ ATF_REQUIRE(fchmod(dfd, 644) == 0);
+
+ ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == -1);
+ ATF_REQUIRE(errno == EACCES);
+
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+#ifdef USE_O_SEARCH
+
+ATF_TC(o_search_root_flag2);
+ATF_TC_HEAD(o_search_root_flag2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that root fstatat honours O_SEARCH");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(o_search_root_flag2, tc)
+{
+ int dfd;
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1);
+
+ ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0);
+
+ ATF_REQUIRE(fchmod(dfd, 644) == 0);
+
+ ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0);
+
+ ATF_REQUIRE(fchmod(dfd, 444) == 0);
+
+ ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0);
+
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(o_search_unpriv_flag2);
+ATF_TC_HEAD(o_search_unpriv_flag2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that fstatat honours O_SEARCH");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+ATF_TC_BODY(o_search_unpriv_flag2, tc)
+{
+ int dfd;
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY|O_SEARCH, 0)) != -1);
+
+ ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0);
+
+ ATF_REQUIRE(fchmod(dfd, 644) == 0);
+
+ ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0);
+
+ ATF_REQUIRE(fchmod(dfd, 444) == 0);
+
+ ATF_REQUIRE(faccessat(dfd, BASEFILE, W_OK, 0) == 0);
+
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+#endif /* USE_O_SEARCH */
+
+
+ATF_TC(o_search_notdir);
+ATF_TC_HEAD(o_search_notdir, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that openat fails with non dir fd");
+}
+ATF_TC_BODY(o_search_notdir, tc)
+{
+ int dfd;
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(FILE, O_CREAT|O_RDWR|O_SEARCH, 0644)) != -1);
+ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDWR, 0)) == -1);
+ ATF_REQUIRE(errno == ENOTDIR);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, o_search_perm1);
+#ifdef USE_O_SEARCH
+ ATF_TP_ADD_TC(tp, o_search_root_flag1);
+ ATF_TP_ADD_TC(tp, o_search_unpriv_flag1);
+#endif
+ ATF_TP_ADD_TC(tp, o_search_perm2);
+#ifdef USE_O_SEARCH
+ ATF_TP_ADD_TC(tp, o_search_root_flag2);
+ ATF_TP_ADD_TC(tp, o_search_unpriv_flag2);
+#endif
+ ATF_TP_ADD_TC(tp, o_search_notdir);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_openat.c b/contrib/netbsd-tests/lib/libc/c063/t_openat.c
new file mode 100644
index 0000000..79b5f38
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_openat.c
@@ -0,0 +1,165 @@
+/* $NetBSD: t_openat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_openat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#define DIR "dir"
+#define FILE "dir/openat"
+#define BASEFILE "openat"
+#define FILEERR "dir/openaterr"
+
+ATF_TC(openat_fd);
+ATF_TC_HEAD(openat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that openat works with fd");
+}
+ATF_TC_BODY(openat_fd, tc)
+{
+ int dfd;
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(close(dfd) == 0);
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC(openat_fdcwd);
+ATF_TC_HEAD(openat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that openat works with fd as AT_FDCWD");
+}
+ATF_TC_BODY(openat_fdcwd, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(chdir(DIR) == 0);
+ ATF_REQUIRE((fd = openat(AT_FDCWD, BASEFILE, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC(openat_fdcwderr);
+ATF_TC_HEAD(openat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that openat fails with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(openat_fdcwderr, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = openat(AT_FDCWD, FILEERR, O_RDONLY, 0)) == -1);
+}
+
+ATF_TC(openat_fderr1);
+ATF_TC_HEAD(openat_fderr1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that openat fail with bad path");
+}
+ATF_TC_BODY(openat_fderr1, tc)
+{
+ int dfd;
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE((fd = openat(dfd, FILEERR, O_RDONLY, 0)) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(openat_fderr2);
+ATF_TC_HEAD(openat_fderr2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that openat fails with bad fdat");
+}
+ATF_TC_BODY(openat_fderr2, tc)
+{
+ int dfd;
+ int fd;
+ char cwd[MAXPATHLEN];
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1);
+ ATF_REQUIRE((fd = openat(dfd, BASEFILE, O_RDONLY, 0)) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(openat_fderr3);
+ATF_TC_HEAD(openat_fderr3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that openat fails with fd as -1");
+}
+ATF_TC_BODY(openat_fderr3, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((fd = openat(-1, FILE, O_RDONLY, 0)) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, openat_fd);
+ ATF_TP_ADD_TC(tp, openat_fdcwd);
+ ATF_TP_ADD_TC(tp, openat_fdcwderr);
+ ATF_TP_ADD_TC(tp, openat_fderr1);
+ ATF_TP_ADD_TC(tp, openat_fderr2);
+ ATF_TP_ADD_TC(tp, openat_fderr3);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c
new file mode 100644
index 0000000..d354ff5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c
@@ -0,0 +1,157 @@
+/* $NetBSD: t_readlinkat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_readlinkat.c,v 1.3 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#define DIR "dir"
+#define FILE "dir/readlinkat"
+#define BASEFILE "readlinkat"
+#define LINK "dir/symlink"
+#define BASELINK "symlink"
+#define FILEERR "dir/readlinkaterr"
+
+ATF_TC(readlinkat_fd);
+ATF_TC_HEAD(readlinkat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that readlinkat works with fd");
+}
+ATF_TC_BODY(readlinkat_fd, tc)
+{
+ int dfd;
+ int fd;
+ ssize_t len;
+ char buf[MAXPATHLEN];
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(symlink(FILE, LINK) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ len = readlinkat(dfd, BASELINK, buf, sizeof(buf)-1);
+ ATF_REQUIRE(len != -1);
+ buf[len] = 0;
+ ATF_REQUIRE(close(dfd) == 0);
+
+ ATF_REQUIRE(strcmp(buf, FILE) == 0);
+}
+
+ATF_TC(readlinkat_fdcwd);
+ATF_TC_HEAD(readlinkat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that readlinkat works with fd as AT_FDCWD");
+}
+ATF_TC_BODY(readlinkat_fdcwd, tc)
+{
+ int fd;
+ ssize_t len;
+ char buf[MAXPATHLEN];
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(symlink(FILE, LINK) == 0);
+
+ len = readlinkat(AT_FDCWD, LINK, buf, sizeof(buf)-1);
+ ATF_REQUIRE(len != -1);
+ buf[len] = 0;
+
+ ATF_REQUIRE(strcmp(buf, FILE) == 0);
+}
+
+ATF_TC(readlinkat_fdcwderr);
+ATF_TC_HEAD(readlinkat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that readlinkat fails with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(readlinkat_fdcwderr, tc)
+{
+ char buf[MAXPATHLEN];
+
+ ATF_REQUIRE(readlinkat(AT_FDCWD, LINK, buf, sizeof(buf)) == -1);
+}
+
+ATF_TC(readlinkat_fderr1);
+ATF_TC_HEAD(readlinkat_fderr1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that readlinkat fail with bad path");
+}
+ATF_TC_BODY(readlinkat_fderr1, tc)
+{
+ int dfd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(readlinkat(dfd, FILEERR, F_OK, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(readlinkat_fderr2);
+ATF_TC_HEAD(readlinkat_fderr2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that readlinkat fails with fd as -1");
+}
+ATF_TC_BODY(readlinkat_fderr2, tc)
+{
+ int fd;
+ char buf[MAXPATHLEN];
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(symlink(FILE, LINK) == 0);
+
+ ATF_REQUIRE(readlinkat(-1, LINK, buf, sizeof(buf)) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, readlinkat_fd);
+ ATF_TP_ADD_TC(tp, readlinkat_fdcwd);
+ ATF_TP_ADD_TC(tp, readlinkat_fdcwderr);
+ ATF_TP_ADD_TC(tp, readlinkat_fderr1);
+ ATF_TP_ADD_TC(tp, readlinkat_fderr2);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_renameat.c b/contrib/netbsd-tests/lib/libc/c063/t_renameat.c
new file mode 100644
index 0000000..e297f2a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_renameat.c
@@ -0,0 +1,152 @@
+/* $NetBSD: t_renameat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_renameat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#define ODIR "olddir"
+#define NDIR "newdir"
+#define FILE "olddir/old"
+#define BASEFILE "old"
+#define RELFILE "../olddir/old"
+#define TARGET "newdir/new"
+#define BASETARGET "new"
+#define FILEERR "olddir/olderr"
+
+ATF_TC(renameat_fd);
+ATF_TC_HEAD(renameat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that renameat works with fd");
+}
+ATF_TC_BODY(renameat_fd, tc)
+{
+ int ofd, nfd, fd;
+ struct stat ost, nst;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE(stat(FILE, &ost) == 0);
+
+ ATF_REQUIRE((ofd = open(ODIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE((nfd = open(NDIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(renameat(ofd, BASEFILE, nfd, BASETARGET) == 0);
+ ATF_REQUIRE(close(ofd) == 0);
+ ATF_REQUIRE(close(nfd) == 0);
+
+ ATF_REQUIRE(stat(TARGET, &nst) == 0);
+ ATF_REQUIRE(ost.st_ino == nst.st_ino);
+}
+
+ATF_TC(renameat_fdcwd);
+ATF_TC_HEAD(renameat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that renameat works with fd as AT_FDCWD");
+}
+
+ATF_TC_BODY(renameat_fdcwd, tc)
+{
+ int fd;
+ struct stat ost, nst;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE(stat(FILE, &ost) == 0);
+
+ ATF_REQUIRE(renameat(AT_FDCWD, FILE, AT_FDCWD, TARGET) == 0);
+
+ ATF_REQUIRE(stat(TARGET, &nst) == 0);
+ ATF_REQUIRE(ost.st_ino == nst.st_ino);
+}
+
+ATF_TC(renameat_fdcwderr);
+ATF_TC_HEAD(renameat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that renameat fails with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(renameat_fdcwderr, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE(renameat(AT_FDCWD, FILEERR, AT_FDCWD, TARGET) == -1);
+}
+
+ATF_TC(renameat_fderr);
+ATF_TC_HEAD(renameat_fderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that renameat fails with fd as -1");
+}
+ATF_TC_BODY(renameat_fderr, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE(renameat(-1, FILE, AT_FDCWD, TARGET) == -1);
+ ATF_REQUIRE(renameat(AT_FDCWD, FILE, -1, TARGET) == -1);
+ ATF_REQUIRE(renameat(-1, FILE, -1, TARGET) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, renameat_fd);
+ ATF_TP_ADD_TC(tp, renameat_fdcwd);
+ ATF_TP_ADD_TC(tp, renameat_fdcwderr);
+ ATF_TP_ADD_TC(tp, renameat_fderr);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c
new file mode 100644
index 0000000..d62f289
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c
@@ -0,0 +1,150 @@
+/* $NetBSD: t_symlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_symlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#define ODIR "olddir"
+#define NDIR "newdir"
+#define FILE "olddir/old"
+#define BASEFILE "old"
+#define RELFILE "../olddir/old"
+#define LINK "newdir/symlink"
+#define BASELINK "symlink"
+#define FILEERR "olddir/olderr"
+
+ATF_TC(symlinkat_fd);
+ATF_TC_HEAD(symlinkat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that symlinkat works with fd");
+}
+ATF_TC_BODY(symlinkat_fd, tc)
+{
+ int dfd, fd;
+ struct stat ost, nst;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE((dfd = open(NDIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(symlinkat(RELFILE, dfd, BASELINK) == 0);
+ ATF_REQUIRE(close(dfd) == 0);
+
+ ATF_REQUIRE(stat(FILE, &ost) == 0);
+ ATF_REQUIRE(stat(LINK, &nst) == 0);
+ ATF_REQUIRE(ost.st_ino == nst.st_ino);
+}
+
+ATF_TC(symlinkat_fdcwd);
+ATF_TC_HEAD(symlinkat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that symlinkat works with fd as AT_FDCWD");
+}
+ATF_TC_BODY(symlinkat_fdcwd, tc)
+{
+ int fd;
+ struct stat ost, nst;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE(symlinkat(RELFILE, AT_FDCWD, LINK) == 0);
+
+ ATF_REQUIRE(stat(FILE, &ost) == 0);
+ ATF_REQUIRE(stat(LINK, &nst) == 0);
+ ATF_REQUIRE(ost.st_ino == nst.st_ino);
+}
+
+ATF_TC(symlinkat_fdcwderr);
+ATF_TC_HEAD(symlinkat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that symlinkat works with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(symlinkat_fdcwderr, tc)
+{
+ int fd;
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE(symlinkat(FILEERR, AT_FDCWD, LINK) == 0);
+ ATF_REQUIRE(lstat(LINK, &st) == 0);
+ ATF_REQUIRE(stat(LINK, &st) == -1);
+ ATF_REQUIRE(errno == ENOENT);
+
+}
+
+ATF_TC(symlinkat_fderr);
+ATF_TC_HEAD(symlinkat_fderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that symlinkat fails with fd as -1");
+}
+ATF_TC_BODY(symlinkat_fderr, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(ODIR, 0755) == 0);
+ ATF_REQUIRE(mkdir(NDIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) != -1);
+
+ ATF_REQUIRE(symlinkat(RELFILE, -1, LINK) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, symlinkat_fd);
+ ATF_TP_ADD_TC(tp, symlinkat_fdcwd);
+ ATF_TP_ADD_TC(tp, symlinkat_fdcwderr);
+ ATF_TP_ADD_TC(tp, symlinkat_fderr);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c b/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c
new file mode 100644
index 0000000..79aa7aa
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c
@@ -0,0 +1,176 @@
+/* $NetBSD: t_unlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_unlinkat.c,v 1.2 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+
+#define DIR "dir"
+#define FILE "dir/unlinkat"
+#define BASEFILE "unlinkat"
+#define FILEERR "dir/unlinkaterr"
+
+ATF_TC(unlinkat_fd);
+ATF_TC_HEAD(unlinkat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that unlinkat works with fd");
+}
+ATF_TC_BODY(unlinkat_fd, tc)
+{
+ int dfd;
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(unlinkat(dfd, BASEFILE, 0) == 0);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(unlinkat_fdcwd);
+ATF_TC_HEAD(unlinkat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that unlinkat works with fd as AT_FDCWD");
+}
+ATF_TC_BODY(unlinkat_fdcwd, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(chdir(DIR) == 0);
+ ATF_REQUIRE(unlinkat(AT_FDCWD, BASEFILE, 0) == 0);
+}
+
+ATF_TC(unlinkat_fdcwderr);
+ATF_TC_HEAD(unlinkat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that unlinkat fails with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(unlinkat_fdcwderr, tc)
+{
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(unlinkat(AT_FDCWD, FILEERR, 0) == -1);
+}
+
+ATF_TC(unlinkat_fderr1);
+ATF_TC_HEAD(unlinkat_fderr1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that unlinkat fail with bad path");
+}
+ATF_TC_BODY(unlinkat_fderr1, tc)
+{
+ int dfd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(unlinkat(dfd, FILEERR, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(unlinkat_fderr2);
+ATF_TC_HEAD(unlinkat_fderr2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that unlinkat fails with bad fdat");
+}
+ATF_TC_BODY(unlinkat_fderr2, tc)
+{
+ int dfd;
+ int fd;
+ char cwd[MAXPATHLEN];
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(unlinkat(dfd, BASEFILE, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(unlinkat_fderr3);
+ATF_TC_HEAD(unlinkat_fderr3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that unlinkat fails with fd as -1");
+}
+ATF_TC_BODY(unlinkat_fderr3, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(unlinkat(-1, FILE, 0) == -1);
+}
+
+ATF_TC(unlinkat_dir);
+ATF_TC_HEAD(unlinkat_dir, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that unlinkat can remove directories");
+}
+ATF_TC_BODY(unlinkat_dir, tc)
+{
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+
+ ATF_REQUIRE(unlinkat(AT_FDCWD, DIR, 0) == -1);
+ ATF_REQUIRE(errno == EPERM);
+ ATF_REQUIRE(unlinkat(AT_FDCWD, DIR, AT_REMOVEDIR) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, unlinkat_fd);
+ ATF_TP_ADD_TC(tp, unlinkat_fdcwd);
+ ATF_TP_ADD_TC(tp, unlinkat_fdcwderr);
+ ATF_TP_ADD_TC(tp, unlinkat_fderr1);
+ ATF_TP_ADD_TC(tp, unlinkat_fderr2);
+ ATF_TP_ADD_TC(tp, unlinkat_fderr3);
+ ATF_TP_ADD_TC(tp, unlinkat_dir);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c b/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c
new file mode 100644
index 0000000..9f21fd6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/c063/t_utimensat.c
@@ -0,0 +1,212 @@
+/* $NetBSD: t_utimensat.c,v 1.5 2013/03/17 04:46:06 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_utimensat.c,v 1.5 2013/03/17 04:46:06 jmmv Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/time.h>
+
+#define DIR "dir"
+#define FILE "dir/utimensat"
+#define BASEFILE "utimensat"
+#define LINK "dir/symlink"
+#define BASELINK "symlink"
+#define FILEERR "dir/symlink"
+
+const struct timespec tptr[] = {
+ { 0x12345678, 987654321 },
+ { 0x15263748, 123456789 },
+};
+
+ATF_TC(utimensat_fd);
+ATF_TC_HEAD(utimensat_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that utimensat works with fd");
+}
+ATF_TC_BODY(utimensat_fd, tc)
+{
+ int dfd;
+ int fd;
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(utimensat(dfd, BASEFILE, tptr, 0) == 0);
+ ATF_REQUIRE(close(dfd) == 0);
+
+ ATF_REQUIRE(stat(FILE, &st) == 0);
+ ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec);
+ ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec);
+ ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec);
+ ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec);
+}
+
+ATF_TC(utimensat_fdcwd);
+ATF_TC_HEAD(utimensat_fdcwd, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that utimensat works with fd as AT_FDCWD");
+}
+ATF_TC_BODY(utimensat_fdcwd, tc)
+{
+ int fd;
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(chdir(DIR) == 0);
+ ATF_REQUIRE(utimensat(AT_FDCWD, BASEFILE, tptr, 0) == 0);
+
+ ATF_REQUIRE(stat(BASEFILE, &st) == 0);
+ ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec);
+ ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec);
+ ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec);
+ ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec);
+}
+
+ATF_TC(utimensat_fdcwderr);
+ATF_TC_HEAD(utimensat_fdcwderr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "See that utimensat fails with fd as AT_FDCWD and bad path");
+}
+ATF_TC_BODY(utimensat_fdcwderr, tc)
+{
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(utimensat(AT_FDCWD, FILEERR, tptr, 0) == -1);
+}
+
+ATF_TC(utimensat_fderr1);
+ATF_TC_HEAD(utimensat_fderr1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that utimensat fail with bad path");
+}
+ATF_TC_BODY(utimensat_fderr1, tc)
+{
+ int dfd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(utimensat(dfd, FILEERR, tptr, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(utimensat_fderr2);
+ATF_TC_HEAD(utimensat_fderr2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that utimensat fails with bad fdat");
+}
+ATF_TC_BODY(utimensat_fderr2, tc)
+{
+ int dfd;
+ int fd;
+ char cwd[MAXPATHLEN];
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1);
+ ATF_REQUIRE(utimensat(dfd, BASEFILE, tptr, 0) == -1);
+ ATF_REQUIRE(close(dfd) == 0);
+}
+
+ATF_TC(utimensat_fderr3);
+ATF_TC_HEAD(utimensat_fderr3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that utimensat fails with fd as -1");
+}
+ATF_TC_BODY(utimensat_fderr3, tc)
+{
+ int fd;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(utimensat(-1, FILE, tptr, 0) == -1);
+}
+
+ATF_TC(utimensat_fdlink);
+ATF_TC_HEAD(utimensat_fdlink, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that utimensat works on symlink");
+}
+ATF_TC_BODY(utimensat_fdlink, tc)
+{
+ int dfd;
+ struct stat st;
+
+ ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+ ATF_REQUIRE(symlink(FILE, LINK) == 0); /* NB: FILE does not exists */
+
+ ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+
+ ATF_REQUIRE(utimensat(dfd, BASELINK, tptr, 0) == -1);
+ ATF_REQUIRE(errno = ENOENT);
+
+ ATF_REQUIRE(utimensat(dfd, BASELINK, tptr, AT_SYMLINK_NOFOLLOW) == 0);
+
+ ATF_REQUIRE(close(dfd) == 0);
+
+ ATF_REQUIRE(lstat(LINK, &st) == 0);
+ ATF_REQUIRE(st.st_atimespec.tv_sec == tptr[0].tv_sec);
+ ATF_REQUIRE(st.st_atimespec.tv_nsec == tptr[0].tv_nsec);
+ ATF_REQUIRE(st.st_mtimespec.tv_sec == tptr[1].tv_sec);
+ ATF_REQUIRE(st.st_mtimespec.tv_nsec == tptr[1].tv_nsec);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, utimensat_fd);
+ ATF_TP_ADD_TC(tp, utimensat_fdcwd);
+ ATF_TP_ADD_TC(tp, utimensat_fdcwderr);
+ ATF_TP_ADD_TC(tp, utimensat_fderr1);
+ ATF_TP_ADD_TC(tp, utimensat_fderr2);
+ ATF_TP_ADD_TC(tp, utimensat_fderr3);
+ ATF_TP_ADD_TC(tp, utimensat_fdlink);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/common/exec_prot.h b/contrib/netbsd-tests/lib/libc/common/exec_prot.h
new file mode 100644
index 0000000..6e17f97
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/common/exec_prot.h
@@ -0,0 +1,61 @@
+/* $NetBSD: exec_prot.h,v 1.1 2011/07/18 23:16:11 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * 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.
+ */
+
+#ifndef _TESTS_EXEC_PROT_H_
+#define _TESTS_EXEC_PROT_H_
+
+/*
+ * Prototype definitions of external helper functions for executable
+ * mapping tests.
+ */
+
+/*
+ * Trivial MD shellcode that justs returns 1.
+ */
+int return_one(void); /* begin marker -- shellcode entry */
+int return_one_end(void); /* end marker */
+
+/*
+ * MD callback to verify whether host offers executable space protection.
+ * Returns execute protection level.
+ */
+int exec_prot_support(void);
+
+/* execute protection level */
+enum {
+ NOTIMPL = -1, /* callback not implemented */
+ NO_XP, /* no execute protection */
+ PERPAGE_XP, /* per-page execute protection */
+ PARTIAL_XP /* partial execute protection. Depending on where the
+ page is located in virtual memory, executable space
+ protection may be enforced or not. */
+};
+#endif
diff --git a/contrib/netbsd-tests/lib/libc/db/README b/contrib/netbsd-tests/lib/libc/db/README
new file mode 100644
index 0000000..68f0ec7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/db/README
@@ -0,0 +1,66 @@
+# $NetBSD: README,v 1.1 2011/01/07 15:05:58 pgoyette Exp $
+# @(#)README 8.8 (Berkeley) 7/31/94
+
+Fairly large files (the command files) are built in this directory during
+the test runs, and even larger files (the database files) are created in
+"/var/tmp". If the latter directory doesn't exist, set the environmental
+variable TMPDIR to a directory where the files can be built.
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+The script file consists of lines with an initial character which is
+the command for that line, or an initial character indicating a key
+or data entry for a previous command.
+
+Legal command characters are as follows:
+
+c: compare a record
+ + must be followed by [kK][dD]; the data value in the database
+ associated with the specified key is compared to the specified
+ data value.
+e: echo a string
+ + writes out the rest of the line into the output file; if the
+ last character is not a carriage-return, a newline is appended.
+f: set the flags for the next command
+ + no value zero's the flags
+g: do a get command
+ + must be followed by [kK]
+ + writes out the retrieved data DBT.
+o [r]: dump [reverse]
+ + dump the database out, if 'r' is set, in reverse order.
+p: do a put command
+ + must be followed by [kK][dD]
+r: do a del command
+ + must be followed by [kK] unless R_CURSOR flag set.
+S: sync the database
+s: do a seq command
+ + must be followed by [kK] if R_CURSOR flag set.
+ + writes out the retrieved data DBT.
+
+Legal key/data characters are as follows:
+
+D [file]: data file
+ + set the current data value to the contents of the file
+d [data]:
+ + set the current key value to the contents of the line.
+K [file]: key file
+ + set the current key value to the contents of the file
+k [data]:
+ + set the current key value to the contents of the line.
+
+Blank lines, lines with leading white space, and lines with leading
+hash marks (#) are ignored.
+
+Options to dbtest are as follows:
+
+ -d: Set the DB_LOCK flag.
+ -f: Use the file argument as the database file.
+ -i: Use the rest of the argument to set elements in the info
+ structure. If the type is btree, then "-i cachesize=10240"
+ will set BTREEINFO.cachesize to 10240.
+ -o: The rest of the argument is the output file instead of
+ using stdout.
+ -s: Don't delete the database file before opening it, i.e.
+ use the database file from a previous run.
+
+Dbtest requires two arguments, the type of access "hash", "recno"
+or "btree", and the script name or "-" to indicate stdin.
diff --git a/contrib/netbsd-tests/lib/libc/db/h_db.c b/contrib/netbsd-tests/lib/libc/db/h_db.c
new file mode 100644
index 0000000..dfb1385
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/db/h_db.c
@@ -0,0 +1,731 @@
+/* $NetBSD: h_db.c,v 1.1 2011/01/07 15:05:58 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993, 1994
+ * The Regents of the University of California. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1992, 1993, 1994\
+ The Regents of the University of California. All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)dbtest.c 8.17 (Berkeley) 9/1/94";
+#else
+__RCSID("$NetBSD: h_db.c,v 1.1 2011/01/07 15:05:58 pgoyette Exp $");
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <err.h>
+#include <db.h>
+
+enum S { COMMAND, COMPARE, GET, PUT, REMOVE, SEQ, SEQFLAG, KEY, DATA };
+
+static void compare(DBT *, DBT *);
+static DBTYPE dbtype(const char *);
+static void dump(DB *, int);
+static void get(DB *, DBT *);
+static void getdata(DB *, DBT *, DBT *);
+static void put(DB *, DBT *, DBT *);
+static void rem(DB *, DBT *);
+static const char *sflags(int);
+static void synk(DB *);
+static void *rfile(char *, size_t *);
+static void seq(DB *, DBT *);
+static u_int setflags(char *);
+static void *setinfo(DBTYPE, char *);
+static void usage(void) __attribute__((__noreturn__));
+static void *xcopy(void *, size_t);
+static void chkcmd(enum S);
+static void chkdata(enum S);
+static void chkkey(enum S);
+
+#ifdef STATISTICS
+extern void __bt_stat(DB *);
+#endif
+
+static DBTYPE type; /* Database type. */
+static void *infop; /* Iflags. */
+static size_t lineno; /* Current line in test script. */
+static u_int flags; /* Current DB flags. */
+static int ofd = STDOUT_FILENO; /* Standard output fd. */
+
+static DB *XXdbp; /* Global for gdb. */
+static size_t XXlineno; /* Fast breakpoint for gdb. */
+
+int
+main(int argc, char *argv[])
+{
+ extern int optind;
+ extern char *optarg;
+ enum S command = COMMAND, state;
+ DB *dbp;
+ DBT data, key, keydata;
+ size_t len;
+ int ch, oflags, sflag;
+ char *fname, *infoarg, *p, *t, buf[8 * 1024];
+ bool unlink_dbfile;
+
+ infoarg = NULL;
+ fname = NULL;
+ unlink_dbfile = false;
+ oflags = O_CREAT | O_RDWR;
+ sflag = 0;
+ while ((ch = getopt(argc, argv, "f:i:lo:s")) != -1)
+ switch (ch) {
+ case 'f':
+ fname = optarg;
+ break;
+ case 'i':
+ infoarg = optarg;
+ break;
+ case 'l':
+ oflags |= DB_LOCK;
+ break;
+ case 'o':
+ if ((ofd = open(optarg,
+ O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
+ err(1, "Cannot create `%s'", optarg);
+ break;
+ case 's':
+ sflag = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 2)
+ usage();
+
+ /* Set the type. */
+ type = dbtype(*argv++);
+
+ /* Open the descriptor file. */
+ if (strcmp(*argv, "-") && freopen(*argv, "r", stdin) == NULL)
+ err(1, "Cannot reopen `%s'", *argv);
+
+ /* Set up the db structure as necessary. */
+ if (infoarg == NULL)
+ infop = NULL;
+ else
+ for (p = strtok(infoarg, ",\t "); p != NULL;
+ p = strtok(0, ",\t "))
+ if (*p != '\0')
+ infop = setinfo(type, p);
+
+ /*
+ * Open the DB. Delete any preexisting copy, you almost never
+ * want it around, and it often screws up tests.
+ */
+ if (fname == NULL) {
+ const char *q = getenv("TMPDIR");
+ if (q == NULL)
+ q = "/var/tmp";
+ (void)snprintf(buf, sizeof(buf), "%s/__dbtest", q);
+ fname = buf;
+ (void)unlink(buf);
+ unlink_dbfile = true;
+ } else if (!sflag)
+ (void)unlink(fname);
+
+ if ((dbp = dbopen(fname,
+ oflags, S_IRUSR | S_IWUSR, type, infop)) == NULL)
+ err(1, "Cannot dbopen `%s'", fname);
+ XXdbp = dbp;
+ if (unlink_dbfile)
+ (void)unlink(fname);
+
+ state = COMMAND;
+ for (lineno = 1;
+ (p = fgets(buf, sizeof(buf), stdin)) != NULL; ++lineno) {
+ /* Delete the newline, displaying the key/data is easier. */
+ if (ofd == STDOUT_FILENO && (t = strchr(p, '\n')) != NULL)
+ *t = '\0';
+ if ((len = strlen(buf)) == 0 || isspace((unsigned char)*p) ||
+ *p == '#')
+ continue;
+
+ /* Convenient gdb break point. */
+ if (XXlineno == lineno)
+ XXlineno = 1;
+ switch (*p) {
+ case 'c': /* compare */
+ chkcmd(state);
+ state = KEY;
+ command = COMPARE;
+ break;
+ case 'e': /* echo */
+ chkcmd(state);
+ /* Don't display the newline, if CR at EOL. */
+ if (p[len - 2] == '\r')
+ --len;
+ if (write(ofd, p + 1, len - 1) != (ssize_t)len - 1 ||
+ write(ofd, "\n", 1) != 1)
+ err(1, "write failed");
+ break;
+ case 'g': /* get */
+ chkcmd(state);
+ state = KEY;
+ command = GET;
+ break;
+ case 'p': /* put */
+ chkcmd(state);
+ state = KEY;
+ command = PUT;
+ break;
+ case 'r': /* remove */
+ chkcmd(state);
+ if (flags == R_CURSOR) {
+ rem(dbp, &key);
+ state = COMMAND;
+ } else {
+ state = KEY;
+ command = REMOVE;
+ }
+ break;
+ case 'S': /* sync */
+ chkcmd(state);
+ synk(dbp);
+ state = COMMAND;
+ break;
+ case 's': /* seq */
+ chkcmd(state);
+ if (flags == R_CURSOR) {
+ state = KEY;
+ command = SEQ;
+ } else
+ seq(dbp, &key);
+ break;
+ case 'f':
+ flags = setflags(p + 1);
+ break;
+ case 'D': /* data file */
+ chkdata(state);
+ data.data = rfile(p + 1, &data.size);
+ goto ldata;
+ case 'd': /* data */
+ chkdata(state);
+ data.data = xcopy(p + 1, len - 1);
+ data.size = len - 1;
+ldata: switch (command) {
+ case COMPARE:
+ compare(&keydata, &data);
+ break;
+ case PUT:
+ put(dbp, &key, &data);
+ break;
+ default:
+ errx(1, "line %zu: command doesn't take data",
+ lineno);
+ }
+ if (type != DB_RECNO)
+ free(key.data);
+ free(data.data);
+ state = COMMAND;
+ break;
+ case 'K': /* key file */
+ chkkey(state);
+ if (type == DB_RECNO)
+ errx(1, "line %zu: 'K' not available for recno",
+ lineno);
+ key.data = rfile(p + 1, &key.size);
+ goto lkey;
+ case 'k': /* key */
+ chkkey(state);
+ if (type == DB_RECNO) {
+ static recno_t recno;
+ recno = atoi(p + 1);
+ key.data = &recno;
+ key.size = sizeof(recno);
+ } else {
+ key.data = xcopy(p + 1, len - 1);
+ key.size = len - 1;
+ }
+lkey: switch (command) {
+ case COMPARE:
+ getdata(dbp, &key, &keydata);
+ state = DATA;
+ break;
+ case GET:
+ get(dbp, &key);
+ if (type != DB_RECNO)
+ free(key.data);
+ state = COMMAND;
+ break;
+ case PUT:
+ state = DATA;
+ break;
+ case REMOVE:
+ rem(dbp, &key);
+ if ((type != DB_RECNO) && (flags != R_CURSOR))
+ free(key.data);
+ state = COMMAND;
+ break;
+ case SEQ:
+ seq(dbp, &key);
+ if ((type != DB_RECNO) && (flags != R_CURSOR))
+ free(key.data);
+ state = COMMAND;
+ break;
+ default:
+ errx(1, "line %zu: command doesn't take a key",
+ lineno);
+ }
+ break;
+ case 'o':
+ dump(dbp, p[1] == 'r');
+ break;
+ default:
+ errx(1, "line %zu: %s: unknown command character",
+ lineno, p);
+ }
+ }
+#ifdef STATISTICS
+ /*
+ * -l must be used (DB_LOCK must be set) for this to be
+ * used, otherwise a page will be locked and it will fail.
+ */
+ if (type == DB_BTREE && oflags & DB_LOCK)
+ __bt_stat(dbp);
+#endif
+ if ((*dbp->close)(dbp))
+ err(1, "db->close failed");
+ (void)close(ofd);
+ return 0;
+}
+
+#define NOOVERWRITE "put failed, would overwrite key\n"
+
+static void
+compare(DBT *db1, DBT *db2)
+{
+ size_t len;
+ u_char *p1, *p2;
+
+ if (db1->size != db2->size)
+ printf("compare failed: key->data len %zu != data len %zu\n",
+ db1->size, db2->size);
+
+ len = MIN(db1->size, db2->size);
+ for (p1 = db1->data, p2 = db2->data; len--;)
+ if (*p1++ != *p2++) {
+ printf("compare failed at offset %lu\n",
+ (unsigned long)(p1 - (u_char *)db1->data));
+ break;
+ }
+}
+
+static void
+get(DB *dbp, DBT *kp)
+{
+ DBT data;
+
+ switch ((*dbp->get)(dbp, kp, &data, flags)) {
+ case 0:
+ (void)write(ofd, data.data, data.size);
+ if (ofd == STDOUT_FILENO)
+ (void)write(ofd, "\n", 1);
+ break;
+ case -1:
+ err(1, "line %zu: get failed", lineno);
+ /* NOTREACHED */
+ case 1:
+#define NOSUCHKEY "get failed, no such key\n"
+ if (ofd != STDOUT_FILENO)
+ (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
+ else
+ (void)fprintf(stderr, "%zu: %.*s: %s",
+ lineno, (int)MIN(kp->size, 20),
+ (const char *)kp->data,
+ NOSUCHKEY);
+#undef NOSUCHKEY
+ break;
+ }
+}
+
+static void
+getdata(DB *dbp, DBT *kp, DBT *dp)
+{
+ switch ((*dbp->get)(dbp, kp, dp, flags)) {
+ case 0:
+ return;
+ case -1:
+ err(1, "line %zu: getdata failed", lineno);
+ /* NOTREACHED */
+ case 1:
+ errx(1, "line %zu: getdata failed, no such key", lineno);
+ /* NOTREACHED */
+ }
+}
+
+static void
+put(DB *dbp, DBT *kp, DBT *dp)
+{
+ switch ((*dbp->put)(dbp, kp, dp, flags)) {
+ case 0:
+ break;
+ case -1:
+ err(1, "line %zu: put failed", lineno);
+ /* NOTREACHED */
+ case 1:
+ (void)write(ofd, NOOVERWRITE, sizeof(NOOVERWRITE) - 1);
+ break;
+ }
+}
+
+static void
+rem(DB *dbp, DBT *kp)
+{
+ switch ((*dbp->del)(dbp, kp, flags)) {
+ case 0:
+ break;
+ case -1:
+ err(1, "line %zu: rem failed", lineno);
+ /* NOTREACHED */
+ case 1:
+#define NOSUCHKEY "rem failed, no such key\n"
+ if (ofd != STDOUT_FILENO)
+ (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
+ else if (flags != R_CURSOR)
+ (void)fprintf(stderr, "%zu: %.*s: %s",
+ lineno, (int)MIN(kp->size, 20),
+ (const char *)kp->data, NOSUCHKEY);
+ else
+ (void)fprintf(stderr,
+ "%zu: rem of cursor failed\n", lineno);
+#undef NOSUCHKEY
+ break;
+ }
+}
+
+static void
+synk(DB *dbp)
+{
+ switch ((*dbp->sync)(dbp, flags)) {
+ case 0:
+ break;
+ case -1:
+ err(1, "line %zu: synk failed", lineno);
+ /* NOTREACHED */
+ }
+}
+
+static void
+seq(DB *dbp, DBT *kp)
+{
+ DBT data;
+
+ switch (dbp->seq(dbp, kp, &data, flags)) {
+ case 0:
+ (void)write(ofd, data.data, data.size);
+ if (ofd == STDOUT_FILENO)
+ (void)write(ofd, "\n", 1);
+ break;
+ case -1:
+ err(1, "line %zu: seq failed", lineno);
+ /* NOTREACHED */
+ case 1:
+#define NOSUCHKEY "seq failed, no such key\n"
+ if (ofd != STDOUT_FILENO)
+ (void)write(ofd, NOSUCHKEY, sizeof(NOSUCHKEY) - 1);
+ else if (flags == R_CURSOR)
+ (void)fprintf(stderr, "%zu: %.*s: %s",
+ lineno, (int)MIN(kp->size, 20),
+ (const char *)kp->data, NOSUCHKEY);
+ else
+ (void)fprintf(stderr,
+ "%zu: seq (%s) failed\n", lineno, sflags(flags));
+#undef NOSUCHKEY
+ break;
+ }
+}
+
+static void
+dump(DB *dbp, int rev)
+{
+ DBT key, data;
+ int xflags, nflags;
+
+ if (rev) {
+ xflags = R_LAST;
+ nflags = R_PREV;
+ } else {
+ xflags = R_FIRST;
+ nflags = R_NEXT;
+ }
+ for (;; xflags = nflags)
+ switch (dbp->seq(dbp, &key, &data, xflags)) {
+ case 0:
+ (void)write(ofd, data.data, data.size);
+ if (ofd == STDOUT_FILENO)
+ (void)write(ofd, "\n", 1);
+ break;
+ case 1:
+ goto done;
+ case -1:
+ err(1, "line %zu: (dump) seq failed", lineno);
+ /* NOTREACHED */
+ }
+done: return;
+}
+
+static u_int
+setflags(char *s)
+{
+ char *p;
+
+ for (; isspace((unsigned char)*s); ++s);
+ if (*s == '\n' || *s == '\0')
+ return 0;
+ if ((p = strchr(s, '\n')) != NULL)
+ *p = '\0';
+ if (!strcmp(s, "R_CURSOR")) return R_CURSOR;
+ if (!strcmp(s, "R_FIRST")) return R_FIRST;
+ if (!strcmp(s, "R_IAFTER")) return R_IAFTER;
+ if (!strcmp(s, "R_IBEFORE")) return R_IBEFORE;
+ if (!strcmp(s, "R_LAST")) return R_LAST;
+ if (!strcmp(s, "R_NEXT")) return R_NEXT;
+ if (!strcmp(s, "R_NOOVERWRITE")) return R_NOOVERWRITE;
+ if (!strcmp(s, "R_PREV")) return R_PREV;
+ if (!strcmp(s, "R_SETCURSOR")) return R_SETCURSOR;
+
+ errx(1, "line %zu: %s: unknown flag", lineno, s);
+ /* NOTREACHED */
+}
+
+static const char *
+sflags(int xflags)
+{
+ switch (xflags) {
+ case R_CURSOR: return "R_CURSOR";
+ case R_FIRST: return "R_FIRST";
+ case R_IAFTER: return "R_IAFTER";
+ case R_IBEFORE: return "R_IBEFORE";
+ case R_LAST: return "R_LAST";
+ case R_NEXT: return "R_NEXT";
+ case R_NOOVERWRITE: return "R_NOOVERWRITE";
+ case R_PREV: return "R_PREV";
+ case R_SETCURSOR: return "R_SETCURSOR";
+ }
+
+ return "UNKNOWN!";
+}
+
+static DBTYPE
+dbtype(const char *s)
+{
+ if (!strcmp(s, "btree"))
+ return DB_BTREE;
+ if (!strcmp(s, "hash"))
+ return DB_HASH;
+ if (!strcmp(s, "recno"))
+ return DB_RECNO;
+ errx(1, "%s: unknown type (use btree, hash or recno)", s);
+ /* NOTREACHED */
+}
+
+static void *
+setinfo(DBTYPE dtype, char *s)
+{
+ static BTREEINFO ib;
+ static HASHINFO ih;
+ static RECNOINFO rh;
+ char *eq;
+
+ if ((eq = strchr(s, '=')) == NULL)
+ errx(1, "%s: illegal structure set statement", s);
+ *eq++ = '\0';
+ if (!isdigit((unsigned char)*eq))
+ errx(1, "%s: structure set statement must be a number", s);
+
+ switch (dtype) {
+ case DB_BTREE:
+ if (!strcmp("flags", s)) {
+ ib.flags = atoi(eq);
+ return &ib;
+ }
+ if (!strcmp("cachesize", s)) {
+ ib.cachesize = atoi(eq);
+ return &ib;
+ }
+ if (!strcmp("maxkeypage", s)) {
+ ib.maxkeypage = atoi(eq);
+ return &ib;
+ }
+ if (!strcmp("minkeypage", s)) {
+ ib.minkeypage = atoi(eq);
+ return &ib;
+ }
+ if (!strcmp("lorder", s)) {
+ ib.lorder = atoi(eq);
+ return &ib;
+ }
+ if (!strcmp("psize", s)) {
+ ib.psize = atoi(eq);
+ return &ib;
+ }
+ break;
+ case DB_HASH:
+ if (!strcmp("bsize", s)) {
+ ih.bsize = atoi(eq);
+ return &ih;
+ }
+ if (!strcmp("ffactor", s)) {
+ ih.ffactor = atoi(eq);
+ return &ih;
+ }
+ if (!strcmp("nelem", s)) {
+ ih.nelem = atoi(eq);
+ return &ih;
+ }
+ if (!strcmp("cachesize", s)) {
+ ih.cachesize = atoi(eq);
+ return &ih;
+ }
+ if (!strcmp("lorder", s)) {
+ ih.lorder = atoi(eq);
+ return &ih;
+ }
+ break;
+ case DB_RECNO:
+ if (!strcmp("flags", s)) {
+ rh.flags = atoi(eq);
+ return &rh;
+ }
+ if (!strcmp("cachesize", s)) {
+ rh.cachesize = atoi(eq);
+ return &rh;
+ }
+ if (!strcmp("lorder", s)) {
+ rh.lorder = atoi(eq);
+ return &rh;
+ }
+ if (!strcmp("reclen", s)) {
+ rh.reclen = atoi(eq);
+ return &rh;
+ }
+ if (!strcmp("bval", s)) {
+ rh.bval = atoi(eq);
+ return &rh;
+ }
+ if (!strcmp("psize", s)) {
+ rh.psize = atoi(eq);
+ return &rh;
+ }
+ break;
+ }
+ errx(1, "%s: unknown structure value", s);
+ /* NOTREACHED */
+}
+
+static void *
+rfile(char *name, size_t *lenp)
+{
+ struct stat sb;
+ void *p;
+ int fd;
+ char *np;
+
+ for (; isspace((unsigned char)*name); ++name)
+ continue;
+ if ((np = strchr(name, '\n')) != NULL)
+ *np = '\0';
+ if ((fd = open(name, O_RDONLY, 0)) == -1 || fstat(fd, &sb) == -1)
+ err(1, "Cannot open `%s'", name);
+#ifdef NOT_PORTABLE
+ if (sb.st_size > (off_t)SIZE_T_MAX) {
+ errno = E2BIG;
+ err("Cannot process `%s'", name);
+ }
+#endif
+ if ((p = malloc((size_t)sb.st_size)) == NULL)
+ err(1, "Cannot allocate %zu bytes", (size_t)sb.st_size);
+ if (read(fd, p, (ssize_t)sb.st_size) != (ssize_t)sb.st_size)
+ err(1, "read failed");
+ *lenp = (size_t)sb.st_size;
+ (void)close(fd);
+ return p;
+}
+
+static void *
+xcopy(void *text, size_t len)
+{
+ void *p;
+
+ if ((p = malloc(len)) == NULL)
+ err(1, "Cannot allocate %zu bytes", len);
+ (void)memmove(p, text, len);
+ return p;
+}
+
+static void
+chkcmd(enum S state)
+{
+ if (state != COMMAND)
+ errx(1, "line %zu: not expecting command", lineno);
+}
+
+static void
+chkdata(enum S state)
+{
+ if (state != DATA)
+ errx(1, "line %zu: not expecting data", lineno);
+}
+
+static void
+chkkey(enum S state)
+{
+ if (state != KEY)
+ errx(1, "line %zu: not expecting a key", lineno);
+}
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr,
+ "Usage: %s [-l] [-f file] [-i info] [-o file] type script\n",
+ getprogname());
+ exit(1);
+}
diff --git a/contrib/netbsd-tests/lib/libc/db/t_db.sh b/contrib/netbsd-tests/lib/libc/db/t_db.sh
new file mode 100755
index 0000000..d256508
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/db/t_db.sh
@@ -0,0 +1,940 @@
+# $NetBSD: t_db.sh,v 1.4 2013/07/29 10:43:15 skrll Exp $
+#
+# 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.
+#
+
+prog()
+{
+ echo $(atf_get_srcdir)/h_db
+}
+
+dict()
+{
+ if [ -f /usr/share/dict/words ]; then
+ echo /usr/share/dict/words
+ elif [ -f /usr/dict/words ]; then
+ echo /usr/dict/words
+ else
+ atf_fail "no dictionary found"
+ fi
+}
+
+# Begin FreeBSD
+dict()
+{
+ if [ -f /usr/share/dict/words ]; then
+ echo /usr/share/dict/words
+ else
+ echo /nonexistent
+ atf_skip "Test requires dict/words"
+ fi
+}
+# End FreeBSD
+
+SEVEN_SEVEN="abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg"
+
+atf_test_case small_btree
+small_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database using small keys and small data" \
+ "pairs: takes the first hundred entries in the dictionary," \
+ "and makes them be key/data pairs."
+}
+small_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ sed 200q $(dict) >exp
+
+ for i in `sed 200q $(dict)`; do
+ echo p
+ echo k$i
+ echo d$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" btree in
+}
+
+atf_test_case small_hash
+small_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database using small keys and small data" \
+ "pairs: takes the first hundred entries in the dictionary," \
+ "and makes them be key/data pairs."
+}
+small_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ sed 200q $(dict) >exp
+
+ for i in `sed 200q $(dict)`; do
+ echo p
+ echo k$i
+ echo d$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" hash in
+}
+
+atf_test_case small_recno
+small_recno_head()
+{
+ atf_set "descr" \
+ "Checks recno database using small keys and small data" \
+ "pairs: takes the first hundred entries in the dictionary," \
+ "and makes them be key/data pairs."
+}
+small_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ sed 200q $(dict) >exp
+
+ sed 200q $(dict) |
+ awk '{
+ ++i;
+ printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case medium_btree
+medium_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database using small keys and medium" \
+ "data pairs: takes the first 200 entries in the" \
+ "dictionary, and gives them each a medium size data entry."
+}
+medium_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
+
+ for i in $(sed 200q $(dict)); do
+ echo p
+ echo k$i
+ echo d$mdata
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" btree in
+}
+
+atf_test_case medium_hash
+medium_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database using small keys and medium" \
+ "data pairs: takes the first 200 entries in the" \
+ "dictionary, and gives them each a medium size data entry."
+}
+medium_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
+
+ for i in $(sed 200q $(dict)); do
+ echo p
+ echo k$i
+ echo d$mdata
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" hash in
+}
+
+atf_test_case medium_recno
+medium_recno_head()
+{
+ atf_set "descr" \
+ "Checks recno database using small keys and medium" \
+ "data pairs: takes the first 200 entries in the" \
+ "dictionary, and gives them each a medium size data entry."
+}
+medium_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
+
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i)
+ printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case big_btree
+big_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database using small keys and big data" \
+ "pairs: inserts the programs in /bin with their paths" \
+ "as their keys."
+}
+big_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ (find /bin -type f -print | xargs cat) >exp
+
+ for psize in 512 16384 65536; do
+ echo "checking page size: $psize"
+
+ for i in `find /bin -type f -print`; do
+ echo p
+ echo k$i
+ echo D$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check "$(prog)" -o out btree in
+ cmp -s exp out || atf_fail "test failed for page size: $psize"
+ done
+}
+
+atf_test_case big_hash
+big_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database using small keys and big data" \
+ "pairs: inserts the programs in /bin with their paths" \
+ "as their keys."
+}
+big_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ (find /bin -type f -print | xargs cat) >exp
+
+ for i in `find /bin -type f -print`; do
+ echo p
+ echo k$i
+ echo D$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check "$(prog)" -o out hash in
+ cmp -s exp out || atf_fail "test failed"
+}
+
+atf_test_case big_recno
+big_recno_head()
+{
+ atf_set "descr" \
+ "Checks recno database using small keys and big data" \
+ "pairs: inserts the programs in /bin with their paths" \
+ "as their keys."
+}
+big_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ (find /bin -type f -print | xargs cat) >exp
+
+ find /bin -type f -print |
+ awk '{
+ ++i;
+ printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
+ }' >in
+
+ for psize in 512 16384 65536; do
+ echo "checking page size: $psize"
+
+ atf_check "$(prog)" -o out recno in
+ cmp -s exp out || atf_fail "test failed for page size: $psize"
+ done
+}
+
+atf_test_case random_recno
+random_recno_head()
+{
+ atf_set "descr" "Checks recno database using random entries"
+}
+random_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 37; i <= 37 + 88 * 17; i += 17) {
+ if (i % 41)
+ s = substr($0, 1, i % 41);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ for (i = 1; i <= 15; ++i) {
+ if (i % 41)
+ s = substr($0, 1, i % 41);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ for (i = 19234; i <= 19234 + 61 * 27; i += 27) {
+ if (i % 41)
+ s = substr($0, 1, i % 41);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ exit
+ }' >exp
+
+ cat exp |
+ awk 'BEGIN {
+ i = 37;
+ incr = 17;
+ }
+ {
+ printf("p\nk%d\nd%s\n", i, $0);
+ if (i == 19234 + 61 * 27)
+ exit;
+ if (i == 37 + 88 * 17) {
+ i = 1;
+ incr = 1;
+ } else if (i == 15) {
+ i = 19234;
+ incr = 27;
+ } else
+ i += incr;
+ }
+ END {
+ for (i = 37; i <= 37 + 88 * 17; i += 17)
+ printf("g\nk%d\n", i);
+ for (i = 1; i <= 15; ++i)
+ printf("g\nk%d\n", i);
+ for (i = 19234; i <= 19234 + 61 * 27; i += 27)
+ printf("g\nk%d\n", i);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case reverse_recno
+reverse_recno_head()
+{
+ atf_set "descr" "Checks recno database using reverse order entries"
+}
+reverse_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk ' {
+ for (i = 1500; i; --i) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ exit;
+ }' >exp
+
+ cat exp |
+ awk 'BEGIN {
+ i = 1500;
+ }
+ {
+ printf("p\nk%d\nd%s\n", i, $0);
+ --i;
+ }
+ END {
+ for (i = 1500; i; --i)
+ printf("g\nk%d\n", i);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case alternate_recno
+alternate_recno_head()
+{
+ atf_set "descr" "Checks recno database using alternating order entries"
+}
+alternate_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk ' {
+ for (i = 1; i < 1200; i += 2) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ for (i = 2; i < 1200; i += 2) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ exit;
+ }' >exp
+
+ cat exp |
+ awk 'BEGIN {
+ i = 1;
+ even = 0;
+ }
+ {
+ printf("p\nk%d\nd%s\n", i, $0);
+ i += 2;
+ if (i >= 1200) {
+ if (even == 1)
+ exit;
+ even = 1;
+ i = 2;
+ }
+ }
+ END {
+ for (i = 1; i < 1200; ++i)
+ printf("g\nk%d\n", i);
+ }' >in
+
+ atf_check "$(prog)" -o out recno in
+
+ sort -o exp exp
+ sort -o out out
+
+ cmp -s exp out || atf_fail "test failed"
+}
+
+h_delete()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ type=$1
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 120; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ }' >exp
+
+ cat exp |
+ awk '{
+ printf("p\nk%d\nd%s\n", ++i, $0);
+ }
+ END {
+ printf("fR_NEXT\n");
+ for (i = 1; i <= 120; ++i)
+ printf("s\n");
+ printf("fR_CURSOR\ns\nkXX\n");
+ printf("r\n");
+ printf("fR_NEXT\ns\n");
+ printf("fR_CURSOR\ns\nk1\n");
+ printf("r\n");
+ printf("fR_FIRST\ns\n");
+ }' >in
+
+ # For btree, the records are ordered by the string representation
+ # of the key value. So sort the expected output file accordingly,
+ # and set the seek_last key to the last expected key value.
+
+ if [ "$type" = "btree" ] ; then
+ sed -e 's/kXX/k99/' < in > tmp
+ mv tmp in
+ sort -d -k4 < exp > tmp
+ mv tmp exp
+ echo $SEVEN_SEVEN |
+ awk '{
+ printf("%05d: input key %d: %s\n", 99, 99, $0);
+ printf("seq failed, no such key\n");
+ printf("%05d: input key %d: %s\n", 1, 1, $0);
+ printf("%05d: input key %d: %s\n", 10, 10, $0);
+ exit;
+ }' >> exp
+ else
+ # For recno, records are ordered by numerical key value. No sort
+ # is needed, but still need to set proper seek_last key value.
+ sed -e 's/kXX/k120/' < in > tmp
+ mv tmp in
+ echo $SEVEN_SEVEN |
+ awk '{
+ printf("%05d: input key %d: %s\n", 120, 120, $0);
+ printf("seq failed, no such key\n");
+ printf("%05d: input key %d: %s\n", 1, 1, $0);
+ printf("%05d: input key %d: %s\n", 2, 2, $0);
+ exit;
+ }' >> exp
+ fi
+
+ atf_check "$(prog)" -o out $type in
+ atf_check -o file:exp cat out
+}
+
+atf_test_case delete_btree
+delete_btree_head()
+{
+ atf_set "descr" "Checks removing records in btree database"
+}
+delete_btree_body()
+{
+ h_delete btree
+}
+
+atf_test_case delete_recno
+delete_recno_head()
+{
+ atf_set "descr" "Checks removing records in recno database"
+}
+delete_recno_body()
+{
+ h_delete recno
+}
+
+h_repeated()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo "" |
+ awk 'BEGIN {
+ for (i = 1; i <= 10; ++i) {
+ printf("p\nkkey1\nD/bin/sh\n");
+ printf("p\nkkey2\nD/bin/csh\n");
+ if (i % 8 == 0) {
+ printf("c\nkkey2\nD/bin/csh\n");
+ printf("c\nkkey1\nD/bin/sh\n");
+ printf("e\t%d of 10 (comparison)\n", i);
+ } else
+ printf("e\t%d of 10 \n", i);
+ printf("r\nkkey1\nr\nkkey2\n");
+ }
+ }' >in
+
+ $(prog) btree in
+}
+
+atf_test_case repeated_btree
+repeated_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database with repeated small keys and" \
+ "big data pairs. Makes sure that overflow pages are reused"
+}
+repeated_btree_body()
+{
+ h_repeated btree
+}
+
+atf_test_case repeated_hash
+repeated_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database with repeated small keys and" \
+ "big data pairs. Makes sure that overflow pages are reused"
+}
+repeated_hash_body()
+{
+ h_repeated hash
+}
+
+atf_test_case duplicate_btree
+duplicate_btree_head()
+{
+ atf_set "descr" "Checks btree database with duplicate keys"
+}
+duplicate_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 543; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' >exp
+
+ cat exp |
+ awk '{
+ if (i++ % 2)
+ printf("p\nkduplicatekey\nd%s\n", $0);
+ else
+ printf("p\nkunique%dkey\nd%s\n", i, $0);
+ }
+ END {
+ printf("o\n");
+ }' >in
+
+ atf_check -o file:exp -x "$(prog) -iflags=1 btree in | sort"
+}
+
+h_cursor_flags()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ type=$1
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 20; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' >exp
+
+ # Test that R_CURSOR doesn't succeed before cursor initialized
+ cat exp |
+ awk '{
+ if (i == 10)
+ exit;
+ printf("p\nk%d\nd%s\n", ++i, $0);
+ }
+ END {
+ printf("fR_CURSOR\nr\n");
+ printf("eR_CURSOR SHOULD HAVE FAILED\n");
+ }' >in
+
+ atf_check -o ignore -e ignore -s ne:0 "$(prog)" -o out $type in
+ atf_check -s ne:0 test -s out
+
+ cat exp |
+ awk '{
+ if (i == 10)
+ exit;
+ printf("p\nk%d\nd%s\n", ++i, $0);
+ }
+ END {
+ printf("fR_CURSOR\np\nk1\ndsome data\n");
+ printf("eR_CURSOR SHOULD HAVE FAILED\n");
+ }' >in
+
+ atf_check -o ignore -e ignore -s ne:0 "$(prog)" -o out $type in
+ atf_check -s ne:0 test -s out
+}
+
+atf_test_case cursor_flags_btree
+cursor_flags_btree_head()
+{
+ atf_set "descr" \
+ "Checks use of cursor flags without initialization in btree database"
+}
+cursor_flags_btree_body()
+{
+ h_cursor_flags btree
+}
+
+atf_test_case cursor_flags_recno
+cursor_flags_recno_head()
+{
+ atf_set "descr" \
+ "Checks use of cursor flags without initialization in recno database"
+}
+cursor_flags_recno_body()
+{
+ h_cursor_flags recno
+}
+
+atf_test_case reverse_order_recno
+reverse_order_recno_head()
+{
+ atf_set "descr" "Checks reverse order inserts in recno database"
+}
+reverse_order_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 779; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' >exp
+
+ cat exp |
+ awk '{
+ if (i == 0) {
+ i = 1;
+ printf("p\nk1\nd%s\n", $0);
+ printf("%s\n", "fR_IBEFORE");
+ } else
+ printf("p\nk1\nd%s\n", $0);
+ }
+ END {
+ printf("or\n");
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case small_page_btree
+small_page_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database with lots of keys and small page" \
+ "size: takes the first 20000 entries in the dictionary," \
+ "reverses them, and gives them each a small size data" \
+ "entry. Uses a small page size to make sure the btree" \
+ "split code gets hammered."
+}
+small_page_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxy
+ echo $mdata |
+ awk '{ for (i = 1; i < 20001; ++i) print $0 }' >exp
+
+ for i in `sed 20000q $(dict) | rev`; do
+ echo p
+ echo k$i
+ echo d$mdata
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" -i psize=512 btree in
+}
+
+h_byte_orders()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ type=$1
+
+ sed 50q $(dict) >exp
+ for order in 1234 4321; do
+ for i in `sed 50q $(dict)`; do
+ echo p
+ echo k$i
+ echo d$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" -ilorder=$order -f byte.file $type in
+
+ for i in `sed 50q $(dict)`; do
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" -s -ilorder=$order -f byte.file $type in
+ done
+}
+
+atf_test_case byte_orders_btree
+byte_orders_btree_head()
+{
+ atf_set "descr" "Checks btree database using differing byte orders"
+}
+byte_orders_btree_body()
+{
+ h_byte_orders btree
+}
+
+atf_test_case byte_orders_hash
+byte_orders_hash_head()
+{
+ atf_set "descr" "Checks hash database using differing byte orders"
+}
+byte_orders_hash_body()
+{
+ h_byte_orders hash
+}
+
+h_bsize_ffactor()
+{
+ bsize=$1
+ ffactor=$2
+
+ echo "bucketsize $bsize, fill factor $ffactor"
+ atf_check -o file:exp "$(prog)" "-ibsize=$bsize,\
+ffactor=$ffactor,nelem=25000,cachesize=65536" hash in
+}
+
+atf_test_case bsize_ffactor
+bsize_ffactor_head()
+{
+ atf_set "timeout" "480"
+ atf_set "descr" "Checks hash database with various" \
+ "bucketsizes and fill factors"
+}
+bsize_ffactor_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 10000; ++i) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("%s\n", s);
+ }
+ exit;
+
+ }' >exp
+
+ sed 10000q $(dict) |
+ awk 'BEGIN {
+ ds="'$SEVEN_SEVEN'"
+ }
+ {
+ if (++i % 34)
+ s = substr(ds, 1, i % 34);
+ else
+ s = substr(ds, 1);
+ printf("p\nk%s\nd%s\n", $0, s);
+ }' >in
+
+ sed 10000q $(dict) |
+ awk '{
+ ++i;
+ printf("g\nk%s\n", $0);
+ }' >>in
+
+ h_bsize_ffactor 256 11
+ h_bsize_ffactor 256 14
+ h_bsize_ffactor 256 21
+
+ h_bsize_ffactor 512 21
+ h_bsize_ffactor 512 28
+ h_bsize_ffactor 512 43
+
+ h_bsize_ffactor 1024 43
+ h_bsize_ffactor 1024 57
+ h_bsize_ffactor 1024 85
+
+ h_bsize_ffactor 2048 85
+ h_bsize_ffactor 2048 114
+ h_bsize_ffactor 2048 171
+
+ h_bsize_ffactor 4096 171
+ h_bsize_ffactor 4096 228
+ h_bsize_ffactor 4096 341
+
+ h_bsize_ffactor 8192 341
+ h_bsize_ffactor 8192 455
+ h_bsize_ffactor 8192 683
+}
+
+# FIXME: what does it test?
+atf_test_case four_char_hash
+four_char_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database with 4 char key and" \
+ "value insert on a 65536 bucket size"
+}
+four_char_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ cat >in <<EOF
+p
+k1234
+d1234
+r
+k1234
+EOF
+
+ # Begin FreeBSD
+ if true; then
+ atf_check "$(prog)" -i bsize=32768 hash in
+ else
+ # End FreeBSD
+ atf_check "$(prog)" -i bsize=65536 hash in
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case small_btree
+ atf_add_test_case small_hash
+ atf_add_test_case small_recno
+ atf_add_test_case medium_btree
+ atf_add_test_case medium_hash
+ atf_add_test_case medium_recno
+ atf_add_test_case big_btree
+ atf_add_test_case big_hash
+ atf_add_test_case big_recno
+ atf_add_test_case random_recno
+ atf_add_test_case reverse_recno
+ atf_add_test_case alternate_recno
+ atf_add_test_case delete_btree
+ atf_add_test_case delete_recno
+ atf_add_test_case repeated_btree
+ atf_add_test_case repeated_hash
+ atf_add_test_case duplicate_btree
+ atf_add_test_case cursor_flags_btree
+ atf_add_test_case cursor_flags_recno
+ atf_add_test_case reverse_order_recno
+ atf_add_test_case small_page_btree
+ atf_add_test_case byte_orders_btree
+ atf_add_test_case byte_orders_hash
+ atf_add_test_case bsize_ffactor
+ atf_add_test_case four_char_hash
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c b/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c
new file mode 100644
index 0000000..32de6e7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c
@@ -0,0 +1,58 @@
+/* $NetBSD: t_execve.c,v 1.1 2014/04/29 06:29:02 uebayasi Exp $ */
+
+/*-
+ * Copyright (c) 2014 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 <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <unistd.h>
+
+ATF_TC(t_execve_null);
+
+ATF_TC_HEAD(t_execve_null, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Tests an empty execve(2) executing");
+}
+
+ATF_TC_BODY(t_execve_null, tc)
+{
+ int err;
+
+ err = execve(NULL, NULL, NULL);
+ ATF_REQUIRE(err == -1);
+ ATF_REQUIRE(errno == EFAULT);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_execve_null);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/isqemu.h b/contrib/netbsd-tests/lib/libc/gen/isqemu.h
new file mode 100644
index 0000000..7d73a22
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/isqemu.h
@@ -0,0 +1,63 @@
+/* $NetBSD: isqemu.h,v 1.3 2013/04/14 12:46:29 martin Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ * 3. Neither the name of The NetBSD Foundation 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 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/param.h>
+#include <sys/sysctl.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <err.h>
+
+static __inline bool
+isQEMU(void) {
+#if defined(__i386__) || defined(__x86_64__)
+ char name[1024];
+ size_t len = sizeof(name);
+
+ if (sysctlbyname("machdep.cpu_brand", name, &len, NULL, 0) == -1) {
+ if (errno == ENOENT)
+ return false;
+ err(EXIT_FAILURE, "sysctl");
+ }
+ return strstr(name, "QEMU") != NULL;
+#else
+ return false;
+#endif
+}
+
+#ifdef TEST
+int
+main(void) {
+ return isQEMU();
+}
+#endif
diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c
new file mode 100644
index 0000000..d923370
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c
@@ -0,0 +1,104 @@
+/* $NetBSD: h_fileactions.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles Zhang <charles@NetBSD.org> and
+ * Martin Husemann <martin@NetBSD.org>.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#define BUFSIZE 16
+
+/*
+ * This checks (hardcoded) the assumptions that are setup from the
+ * main test program via posix spawn file actions.
+ * Program exits with EXIT_SUCCESS or EXIT_FAILURE accordingly
+ * (and does some stderr diagnostics in case of errors).
+ */
+int
+main(int argc, char **argv)
+{
+ int res = EXIT_SUCCESS;
+ char buf[BUFSIZE];
+ struct stat sb0, sb1;
+
+ strcpy(buf, "test...");
+ /* file desc 3 should be closed via addclose */
+ if (read(3, buf, BUFSIZE) != -1 || errno != EBADF) {
+ fprintf(stderr, "%s: filedesc 3 is not closed\n",
+ getprogname());
+ res = EXIT_FAILURE;
+ }
+ /* file desc 4 should be closed via closeonexec */
+ if (read(4, buf, BUFSIZE) != -1 || errno != EBADF) {
+ fprintf(stderr, "%s: filedesc 4 is not closed\n",
+ getprogname());
+ res = EXIT_FAILURE;
+ }
+ /* file desc 5 remains open */
+ if (write(5, buf, BUFSIZE) <= 0) {
+ fprintf(stderr, "%s: could not write to filedesc 5\n",
+ getprogname());
+ res = EXIT_FAILURE;
+ }
+ /* file desc 6 should be open (via addopen) */
+ if (write(6, buf, BUFSIZE) <= 0) {
+ fprintf(stderr, "%s: could not write to filedesc 6\n",
+ getprogname());
+ res = EXIT_FAILURE;
+ }
+ /* file desc 7 should refer to stdout */
+ fflush(stdout);
+ if (fstat(fileno(stdout), &sb0) != 0) {
+ fprintf(stderr, "%s: could not fstat stdout\n",
+ getprogname());
+ res = EXIT_FAILURE;
+ }
+ if (fstat(7, &sb1) != 0) {
+ fprintf(stderr, "%s: could not fstat filedesc 7\n",
+ getprogname());
+ res = EXIT_FAILURE;
+ }
+ if (write(7, buf, strlen(buf)) <= 0) {
+ fprintf(stderr, "%s: could not write to filedesc 7\n",
+ getprogname());
+ res = EXIT_FAILURE;
+ }
+ if (memcmp(&sb0, &sb1, sizeof sb0) != 0) {
+ fprintf(stderr, "%s: stat results differ\n", getprogname());
+ res = EXIT_FAILURE;
+ }
+
+ return res;
+}
+
diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh
new file mode 100755
index 0000000..deee6fe
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh
@@ -0,0 +1,3 @@
+#! /nonexistent
+
+# this is just a dummy script, trying to be non-executable
diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c
new file mode 100644
index 0000000..dbf5da5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c
@@ -0,0 +1,50 @@
+/* $NetBSD: h_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles Zhang <charles@NetBSD.org> and
+ * Martin Husemann <martin@NetBSD.org>.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+
+int
+main(int argc, char **argv)
+{
+ unsigned long ret;
+ char *endp;
+
+ if (argc < 2) {
+ fprintf(stderr, "usage:\n\t%s (retcode)\n", getprogname());
+ exit(255);
+ }
+ ret = strtoul(argv[1], &endp, 10);
+
+ fprintf(stderr, "%s exiting with status %lu\n", getprogname(), ret);
+ return ret;
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c
new file mode 100644
index 0000000..1f13c54
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c
@@ -0,0 +1,90 @@
+/* $NetBSD: h_spawnattr.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles Zhang <charles@NetBSD.org> and
+ * Martin Husemann <martin@NetBSD.org>.
+ *
+ * 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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+
+/*
+ * Helper to test the hardcoded assumptions from t_spawnattr.c
+ * Exit with apropriate exit status and print diagnostics to
+ * stderr explaining what is wrong.
+ */
+int
+main(int argc, char **argv)
+{
+ int parent_pipe, res = EXIT_SUCCESS;
+ sigset_t sig;
+ struct sigaction act;
+ ssize_t rd;
+ char tmp;
+
+ sigemptyset(&sig);
+ if (sigprocmask(0, NULL, &sig) < 0) {
+ fprintf(stderr, "%s: sigprocmask error\n", getprogname());
+ res = EXIT_FAILURE;
+ }
+ if (!sigismember(&sig, SIGUSR1)) {
+ fprintf(stderr, "%s: SIGUSR not in procmask\n", getprogname());
+ res = EXIT_FAILURE;
+ }
+ if (sigaction(SIGUSR1, NULL, &act) < 0) {
+ fprintf(stderr, "%s: sigaction error\n", getprogname());
+ res = EXIT_FAILURE;
+ }
+ if (act.sa_sigaction != (void *)SIG_DFL) {
+ fprintf(stderr, "%s: SIGUSR1 action != SIG_DFL\n",
+ getprogname());
+ res = EXIT_FAILURE;
+ }
+
+ if (argc >= 2) {
+ parent_pipe = atoi(argv[1]);
+ if (parent_pipe > 2) {
+ printf("%s: waiting for command from parent on pipe "
+ "%d\n", getprogname(), parent_pipe);
+ rd = read(parent_pipe, &tmp, 1);
+ if (rd == 1) {
+ printf("%s: got command %c from parent\n",
+ getprogname(), tmp);
+ } else if (rd == -1) {
+ printf("%s: %d is no pipe, errno %d\n",
+ getprogname(), parent_pipe, errno);
+ res = EXIT_FAILURE;
+ }
+ }
+ }
+
+ return res;
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c
new file mode 100644
index 0000000..5bbf337
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c
@@ -0,0 +1,392 @@
+/* $NetBSD: t_fileactions.c,v 1.5 2012/04/09 19:42:07 martin Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles Zhang <charles@NetBSD.org> and
+ * Martin Husemann <martin@NetBSD.org>.
+ *
+ * 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.
+ */
+
+
+#ifdef __FreeBSD__
+#include <sys/stat.h>
+#endif
+#include <atf-c.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <spawn.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+
+ATF_TC(t_spawn_openmode);
+
+ATF_TC_HEAD(t_spawn_openmode, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test the proper handling of 'mode' for 'open' fileactions");
+ atf_tc_set_md_var(tc, "require.progs", "/bin/cat");
+}
+
+static off_t
+filesize(const char * restrict fname)
+{
+ struct stat st;
+ int err;
+
+ err = stat(fname, &st);
+ ATF_REQUIRE(err == 0);
+ return st.st_size;
+}
+
+#define TESTFILE "./the_input_data"
+#define CHECKFILE "./the_output_data"
+#define TESTCONTENT "marry has a little lamb"
+
+static void
+make_testfile(const char *restrict file)
+{
+ FILE *f;
+ size_t written;
+
+ f = fopen(file, "w");
+ ATF_REQUIRE(f != NULL);
+ written = fwrite(TESTCONTENT, 1, strlen(TESTCONTENT), f);
+ fclose(f);
+ ATF_REQUIRE(written == strlen(TESTCONTENT));
+}
+
+static void
+empty_outfile(const char *restrict filename)
+{
+ FILE *f;
+
+ f = fopen(filename, "w");
+ ATF_REQUIRE(f != NULL);
+ fclose(f);
+}
+
+ATF_TC_BODY(t_spawn_openmode, tc)
+{
+ int status, err;
+ pid_t pid;
+ size_t insize, outsize;
+ char * const args[2] = { __UNCONST("cat"), NULL };
+ posix_spawn_file_actions_t fa;
+
+ /*
+ * try a "cat < testfile > checkfile"
+ */
+ make_testfile(TESTFILE);
+ unlink(CHECKFILE);
+
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdin),
+ TESTFILE, O_RDONLY, 0);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdout),
+ CHECKFILE, O_WRONLY|O_CREAT, 0600);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ /* ok, wait for the child to finish */
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
+
+ /* now check that input and output have the same size */
+ insize = filesize(TESTFILE);
+ outsize = filesize(CHECKFILE);
+ ATF_REQUIRE(insize == strlen(TESTCONTENT));
+ ATF_REQUIRE(insize == outsize);
+
+ /*
+ * try a "cat < testfile >> checkfile"
+ */
+ make_testfile(TESTFILE);
+ make_testfile(CHECKFILE);
+
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdin),
+ TESTFILE, O_RDONLY, 0);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdout),
+ CHECKFILE, O_WRONLY|O_APPEND, 0);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ /* ok, wait for the child to finish */
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
+
+ /* now check that output is twice as long as input */
+ insize = filesize(TESTFILE);
+ outsize = filesize(CHECKFILE);
+ ATF_REQUIRE(insize == strlen(TESTCONTENT));
+ ATF_REQUIRE(insize*2 == outsize);
+
+ /*
+ * try a "cat < testfile > checkfile" with input and output swapped
+ */
+ make_testfile(TESTFILE);
+ empty_outfile(CHECKFILE);
+
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdout),
+ TESTFILE, O_RDONLY, 0);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdin),
+ CHECKFILE, O_WRONLY, 0);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ /* ok, wait for the child to finish */
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_FAILURE);
+
+ /* now check that input and output are still the same size */
+ insize = filesize(TESTFILE);
+ outsize = filesize(CHECKFILE);
+ ATF_REQUIRE(insize == strlen(TESTCONTENT));
+ ATF_REQUIRE(outsize == 0);
+}
+
+ATF_TC(t_spawn_reopen);
+
+ATF_TC_HEAD(t_spawn_reopen, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "an open filehandle can be replaced by a 'open' fileaction");
+ atf_tc_set_md_var(tc, "require.progs", "/bin/cat");
+}
+
+ATF_TC_BODY(t_spawn_reopen, tc)
+{
+ int status, err;
+ pid_t pid;
+ char * const args[2] = { __UNCONST("cat"), NULL };
+ posix_spawn_file_actions_t fa;
+
+ /*
+ * make sure stdin is open in the parent
+ */
+ freopen("/dev/zero", "r", stdin);
+ /*
+ * now request an open for this fd again in the child
+ */
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdin),
+ "/dev/null", O_RDONLY, 0);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
+}
+
+ATF_TC(t_spawn_open_nonexistent);
+
+ATF_TC_HEAD(t_spawn_open_nonexistent, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "posix_spawn fails when a file to open does not exist");
+ atf_tc_set_md_var(tc, "require.progs", "/bin/cat");
+}
+
+ATF_TC_BODY(t_spawn_open_nonexistent, tc)
+{
+ int err, status;
+ pid_t pid;
+ char * const args[2] = { __UNCONST("cat"), NULL };
+ posix_spawn_file_actions_t fa;
+
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, STDIN_FILENO,
+ "./non/ex/ist/ent", O_RDONLY, 0);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ if (err == 0) {
+ /*
+ * The child has been created - it should fail and
+ * return exit code 127
+ */
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 127);
+ } else {
+ /*
+ * The error has been noticed early enough, no child has
+ * been run
+ */
+ ATF_REQUIRE(err == ENOENT);
+ }
+ posix_spawn_file_actions_destroy(&fa);
+}
+
+#ifdef __NetBSD__
+ATF_TC(t_spawn_open_nonexistent_diag);
+
+ATF_TC_HEAD(t_spawn_open_nonexistent_diag, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "posix_spawn fails when a file to open does not exist "
+ "and delivers proper diagnostic");
+ atf_tc_set_md_var(tc, "require.progs", "/bin/cat");
+}
+
+ATF_TC_BODY(t_spawn_open_nonexistent_diag, tc)
+{
+ int err;
+ pid_t pid;
+ char * const args[2] = { __UNCONST("cat"), NULL };
+ posix_spawnattr_t attr;
+ posix_spawn_file_actions_t fa;
+
+ posix_spawnattr_init(&attr);
+ /*
+ * POSIX_SPAWN_RETURNERROR is a NetBSD specific flag that
+ * will cause a "proper" return value from posix_spawn(2)
+ * instead of a (potential) success there and a 127 exit
+ * status from the child process (c.f. the non-diag variant
+ * of this test).
+ */
+ posix_spawnattr_setflags(&attr, POSIX_SPAWN_RETURNERROR);
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, STDIN_FILENO,
+ "./non/ex/ist/ent", O_RDONLY, 0);
+ err = posix_spawn(&pid, "/bin/cat", &fa, &attr, args, NULL);
+ ATF_REQUIRE(err == ENOENT);
+ posix_spawn_file_actions_destroy(&fa);
+ posix_spawnattr_destroy(&attr);
+}
+#endif
+
+ATF_TC(t_spawn_fileactions);
+
+ATF_TC_HEAD(t_spawn_fileactions, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Tests various complex fileactions");
+}
+
+ATF_TC_BODY(t_spawn_fileactions, tc)
+{
+ int fd1, fd2, fd3, status, err;
+ pid_t pid;
+ char * const args[2] = { __UNCONST("h_fileactions"), NULL };
+ char helper[FILENAME_MAX];
+ posix_spawn_file_actions_t fa;
+
+ posix_spawn_file_actions_init(&fa);
+
+ closefrom(fileno(stderr)+1);
+
+ fd1 = open("/dev/null", O_RDONLY);
+ ATF_REQUIRE(fd1 == 3);
+
+ fd2 = open("/dev/null", O_WRONLY, O_CLOEXEC);
+ ATF_REQUIRE(fd2 == 4);
+
+ fd3 = open("/dev/null", O_WRONLY);
+ ATF_REQUIRE(fd3 == 5);
+
+ posix_spawn_file_actions_addclose(&fa, fd1);
+ posix_spawn_file_actions_addopen(&fa, 6, "/dev/null", O_RDWR, 0);
+ posix_spawn_file_actions_adddup2(&fa, 1, 7);
+
+ snprintf(helper, sizeof helper, "%s/h_fileactions",
+ atf_tc_get_config_var(tc, "srcdir"));
+ err = posix_spawn(&pid, helper, &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
+}
+
+ATF_TC(t_spawn_empty_fileactions);
+
+ATF_TC_HEAD(t_spawn_empty_fileactions, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "posix_spawn with empty fileactions (PR kern/46038)");
+ atf_tc_set_md_var(tc, "require.progs", "/bin/cat");
+}
+
+ATF_TC_BODY(t_spawn_empty_fileactions, tc)
+{
+ int status, err;
+ pid_t pid;
+ char * const args[2] = { __UNCONST("cat"), NULL };
+ posix_spawn_file_actions_t fa;
+ size_t insize, outsize;
+
+ /*
+ * try a "cat < testfile > checkfile", but set up stdin/stdout
+ * already in the parent and pass empty file actions to the child.
+ */
+ make_testfile(TESTFILE);
+ unlink(CHECKFILE);
+
+ freopen(TESTFILE, "r", stdin);
+ freopen(CHECKFILE, "w", stdout);
+
+ posix_spawn_file_actions_init(&fa);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ /* ok, wait for the child to finish */
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
+
+ /* now check that input and output have the same size */
+ insize = filesize(TESTFILE);
+ outsize = filesize(CHECKFILE);
+ ATF_REQUIRE(insize == strlen(TESTCONTENT));
+ ATF_REQUIRE(insize == outsize);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_spawn_fileactions);
+ ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent_diag);
+#endif
+ ATF_TP_ADD_TC(tp, t_spawn_reopen);
+ ATF_TP_ADD_TC(tp, t_spawn_openmode);
+ ATF_TP_ADD_TC(tp, t_spawn_empty_fileactions);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c
new file mode 100644
index 0000000..178374b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c
@@ -0,0 +1,184 @@
+/* $NetBSD: t_spawn.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles Zhang <charles@NetBSD.org> and
+ * Martin Husemann <martin@NetBSD.org>.
+ *
+ * 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 <spawn.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+ATF_TC(t_spawn_ls);
+
+ATF_TC_HEAD(t_spawn_ls, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Tests a simple posix_spawn executing /bin/ls");
+}
+
+ATF_TC_BODY(t_spawn_ls, tc)
+{
+ char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL };
+ int err;
+
+ err = posix_spawn(NULL, "/bin/ls", NULL, NULL, args, NULL);
+ ATF_REQUIRE(err == 0);
+}
+
+ATF_TC(t_spawnp_ls);
+
+ATF_TC_HEAD(t_spawnp_ls, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Tests a simple posix_spawnp executing ls via $PATH");
+}
+
+ATF_TC_BODY(t_spawnp_ls, tc)
+{
+ char * const args[] = { __UNCONST("ls"), __UNCONST("-la"), NULL };
+ int err;
+
+ err = posix_spawnp(NULL, "ls", NULL, NULL, args, NULL);
+ ATF_REQUIRE(err == 0);
+}
+
+ATF_TC(t_spawn_zero);
+
+ATF_TC_HEAD(t_spawn_zero, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "posix_spawn an invalid binary");
+}
+
+ATF_TC_BODY(t_spawn_zero, tc)
+{
+ char buf[FILENAME_MAX];
+ char * const args[] = { __UNCONST("h_zero"), NULL };
+ int err;
+
+ snprintf(buf, sizeof buf, "%s/h_zero", atf_tc_get_config_var(tc, "srcdir"));
+ err = posix_spawn(NULL, buf, NULL, NULL, args, NULL);
+ ATF_REQUIRE_MSG(err == ENOEXEC, "expected error %d, got %d when spawning %s", ENOEXEC, err, buf);
+}
+
+ATF_TC(t_spawn_missing);
+
+ATF_TC_HEAD(t_spawn_missing, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "posix_spawn a non existant binary");
+}
+
+ATF_TC_BODY(t_spawn_missing, tc)
+{
+ char buf[FILENAME_MAX];
+ char * const args[] = { __UNCONST("h_nonexist"), NULL };
+ int err;
+
+ snprintf(buf, sizeof buf, "%s/h_nonexist",
+ atf_tc_get_config_var(tc, "srcdir"));
+ err = posix_spawn(NULL, buf, NULL, NULL, args, NULL);
+ ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf);
+}
+
+ATF_TC(t_spawn_nonexec);
+
+ATF_TC_HEAD(t_spawn_nonexec, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "posix_spawn a script with non existing interpreter");
+}
+
+ATF_TC_BODY(t_spawn_nonexec, tc)
+{
+ char buf[FILENAME_MAX];
+ char * const args[] = { __UNCONST("h_nonexec"), NULL };
+ int err;
+
+ snprintf(buf, sizeof buf, "%s/h_nonexec",
+ atf_tc_get_config_var(tc, "srcdir"));
+ err = posix_spawn(NULL, buf, NULL, NULL, args, NULL);
+ ATF_REQUIRE_MSG(err == ENOENT, "expected error %d, got %d when spawning %s", ENOENT, err, buf);
+}
+
+ATF_TC(t_spawn_child);
+
+ATF_TC_HEAD(t_spawn_child, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "posix_spawn a child and get it's return code");
+}
+
+ATF_TC_BODY(t_spawn_child, tc)
+{
+ char buf[FILENAME_MAX];
+ char * const args0[] = { __UNCONST("h_spawn"), __UNCONST("0"), NULL };
+ char * const args1[] = { __UNCONST("h_spawn"), __UNCONST("1"), NULL };
+ char * const args7[] = { __UNCONST("h_spawn"), __UNCONST("7"), NULL };
+ int err, status;
+ pid_t pid;
+
+ snprintf(buf, sizeof buf, "%s/h_spawn",
+ atf_tc_get_config_var(tc, "srcdir"));
+
+ err = posix_spawn(&pid, buf, NULL, NULL, args0, NULL);
+ ATF_REQUIRE(err == 0);
+ ATF_REQUIRE(pid > 0);
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
+
+ err = posix_spawn(&pid, buf, NULL, NULL, args1, NULL);
+ ATF_REQUIRE(err == 0);
+ ATF_REQUIRE(pid > 0);
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 1);
+
+ err = posix_spawn(&pid, buf, NULL, NULL, args7, NULL);
+ ATF_REQUIRE(err == 0);
+ ATF_REQUIRE(pid > 0);
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 7);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_spawn_ls);
+ ATF_TP_ADD_TC(tp, t_spawnp_ls);
+ ATF_TP_ADD_TC(tp, t_spawn_zero);
+ ATF_TP_ADD_TC(tp, t_spawn_missing);
+ ATF_TP_ADD_TC(tp, t_spawn_nonexec);
+ ATF_TP_ADD_TC(tp, t_spawn_child);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c
new file mode 100644
index 0000000..eb99c41
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c
@@ -0,0 +1,173 @@
+/* $NetBSD: t_spawnattr.c,v 1.1 2012/02/13 21:03:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles Zhang <charles@NetBSD.org> and
+ * Martin Husemann <martin@NetBSD.org>.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <signal.h>
+#include <spawn.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#define MAX(a, b) (a) > (b) ? (a) : (b)
+#define MIN(a, b) (a) > (b) ? (b) : (a)
+
+static int get_different_scheduler(void);
+static int get_different_priority(void);
+
+static int
+get_different_scheduler()
+{
+ int scheduler, max, min, new;
+
+ max = MAX(MAX(SCHED_FIFO, SCHED_OTHER), SCHED_RR);
+ min = MIN(MIN(SCHED_FIFO, SCHED_OTHER), SCHED_RR);
+
+ /* get current schedule policy */
+ scheduler = sched_getscheduler(0);
+
+ /* new scheduler */
+ new = (scheduler + 1);
+ if (new > max)
+ new = min;
+
+ return new;
+}
+
+static int
+get_different_priority()
+{
+ int scheduler, max, min, new, priority;
+ struct sched_param param;
+
+ /* get current schedule policy */
+ scheduler = sched_getscheduler(0);
+
+ max = sched_get_priority_max(scheduler);
+ min = sched_get_priority_min(scheduler);
+
+ sched_getparam(0, &param);
+ priority = param.sched_priority;
+
+ /* new schedule policy */
+ new = (priority + 1);
+ if (new > max)
+ new = min;
+
+ return new;
+}
+
+ATF_TC(t_spawnattr);
+
+ATF_TC_HEAD(t_spawnattr, tc)
+{
+ atf_tc_set_md_var(tc, "require.user", "root");
+ atf_tc_set_md_var(tc, "descr",
+ "Tests posix_spawn with scheduler attributes");
+}
+
+ATF_TC_BODY(t_spawnattr, tc)
+{
+ int pid, scheduler, child_scheduler, priority, status, err, pfd[2];
+ char helper_arg[128];
+ char * const args[] = { __UNCONST("h_spawnattr"), helper_arg, NULL };
+ struct sched_param sp, child_sp;
+ sigset_t sig;
+ posix_spawnattr_t attr;
+ char helper[FILENAME_MAX];
+
+ /*
+ * create a pipe to controll the child
+ */
+ err = pipe(pfd);
+ ATF_REQUIRE_MSG(err == 0, "could not create pipe, errno %d", errno);
+ sprintf(helper_arg, "%d", pfd[0]);
+
+ posix_spawnattr_init(&attr);
+
+ scheduler = get_different_scheduler();
+ priority = get_different_priority();
+ sp.sched_priority = priority;
+
+ sigemptyset(&sig);
+ sigaddset(&sig, SIGUSR1);
+
+ posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSCHEDULER |
+ POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETPGROUP |
+ POSIX_SPAWN_SETSIGMASK | POSIX_SPAWN_SETSIGDEF |
+ POSIX_SPAWN_SETSIGDEF);
+ posix_spawnattr_setpgroup(&attr, 0);
+ posix_spawnattr_setschedparam(&attr, &sp);
+ posix_spawnattr_setschedpolicy(&attr, scheduler);
+ posix_spawnattr_setsigmask(&attr, &sig);
+ posix_spawnattr_setsigdefault(&attr, &sig);
+
+ sprintf(helper, "%s/h_spawnattr",
+ atf_tc_get_config_var(tc, "srcdir"));
+ err = posix_spawn(&pid, helper, NULL, &attr, args, NULL);
+ ATF_REQUIRE_MSG(err == 0, "error %d", err);
+
+ child_scheduler = sched_getscheduler(pid);
+ ATF_REQUIRE_MSG(scheduler == child_scheduler,
+ "scheduler = %d, child_scheduler = %d, pid %d, errno %d",
+ scheduler, child_scheduler, pid, errno);
+
+ sched_getparam(pid, &child_sp);
+ ATF_REQUIRE_MSG(child_sp.sched_priority == sp.sched_priority,
+ "priority is: %d, but we requested: %d",
+ child_sp.sched_priority, sp.sched_priority);
+
+ ATF_REQUIRE_MSG(pid == getpgid(pid), "child pid: %d, child pgid: %d",
+ pid, getpgid(pid));
+
+ /* ready, let child go */
+ write(pfd[1], "q", 1);
+ close(pfd[0]);
+ close(pfd[1]);
+
+ /* wait and check result from child */
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
+
+ posix_spawnattr_destroy(&attr);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_spawnattr);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_alarm.c b/contrib/netbsd-tests/lib/libc/gen/t_alarm.c
new file mode 100644
index 0000000..d9e903d1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_alarm.c
@@ -0,0 +1,150 @@
+/* $NetBSD: t_alarm.c,v 1.2 2011/05/10 06:58:17 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_alarm.c,v 1.2 2011/05/10 06:58:17 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+
+static bool fail;
+static void handler(int);
+
+static void
+handler(int signo)
+{
+
+ if (signo == SIGALRM)
+ fail = false;
+}
+
+ATF_TC(alarm_basic);
+ATF_TC_HEAD(alarm_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of alarm(3)");
+}
+
+ATF_TC_BODY(alarm_basic, tc)
+{
+
+ ATF_REQUIRE(signal(SIGALRM, handler) == 0);
+
+ fail = true;
+
+ (void)alarm(1);
+ (void)sleep(2);
+
+ if (fail != false)
+ atf_tc_fail("alarm(3) failed to deliver signal");
+}
+
+ATF_TC(alarm_fork);
+ATF_TC_HEAD(alarm_fork, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Does fork(2) clear a pending alarm?");
+}
+
+ATF_TC_BODY(alarm_fork, tc)
+{
+ unsigned int rv;
+ pid_t pid;
+ int sta;
+
+ /*
+ * Any pending alarms should be
+ * cleared in the child process.
+ */
+ (void)alarm(60);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ rv = alarm(0);
+
+ if (rv != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)alarm(0);
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("pending alarm was not cleared for child");
+}
+
+ATF_TC(alarm_previous);
+ATF_TC_HEAD(alarm_previous, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test return value from alarm(3)");
+}
+
+ATF_TC_BODY(alarm_previous, tc)
+{
+ unsigned int rv;
+
+ /*
+ * See that alarm(3) returns the amount
+ * left on the timer from the previous call.
+ */
+ rv = alarm(60);
+
+ if (rv != 0)
+ goto fail;
+
+ rv = alarm(0);
+
+ if (rv < 50)
+ goto fail;
+
+ (void)alarm(0);
+
+ return;
+
+fail:
+ atf_tc_fail("invalid return value from alarm(3)");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, alarm_basic);
+ ATF_TP_ADD_TC(tp, alarm_fork);
+ ATF_TP_ADD_TC(tp, alarm_previous);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_assert.c b/contrib/netbsd-tests/lib/libc/gen/t_assert.c
new file mode 100644
index 0000000..140417a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_assert.c
@@ -0,0 +1,132 @@
+/* $NetBSD: t_assert.c,v 1.2 2011/06/14 05:28:00 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_assert.c,v 1.2 2011/06/14 05:28:00 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <assert.h>
+#include <atf-c.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void handler(int);
+
+static void
+handler(int signo)
+{
+ /* Nothing. */
+}
+
+ATF_TC(assert_false);
+ATF_TC_HEAD(assert_false, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that assert(3) works, #1");
+}
+
+ATF_TC_BODY(assert_false, tc)
+{
+ struct sigaction sa;
+ pid_t pid;
+ int sta;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ (void)closefrom(0);
+ (void)memset(&sa, 0, sizeof(struct sigaction));
+
+ sa.sa_flags = 0;
+ sa.sa_handler = handler;
+
+ (void)sigemptyset(&sa.sa_mask);
+ (void)sigaction(SIGABRT, &sa, 0);
+
+ assert(1 == 1);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFSIGNALED(sta) != 0 || WIFEXITED(sta) == 0)
+ atf_tc_fail("assert(3) fired haphazardly");
+}
+
+ATF_TC(assert_true);
+ATF_TC_HEAD(assert_true, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that assert(3) works, #2");
+}
+
+ATF_TC_BODY(assert_true, tc)
+{
+ struct sigaction sa;
+ pid_t pid;
+ int sta;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ (void)closefrom(0);
+ (void)memset(&sa, 0, sizeof(struct sigaction));
+
+ sa.sa_flags = 0;
+ sa.sa_handler = handler;
+
+ (void)sigemptyset(&sa.sa_mask);
+ (void)sigaction(SIGABRT, &sa, 0);
+
+ assert(1 == 2);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGABRT)
+ atf_tc_fail("assert(3) did not fire");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, assert_false);
+ ATF_TP_ADD_TC(tp, assert_true);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c b/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c
new file mode 100644
index 0000000..6c82cb4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_basedirname.c
@@ -0,0 +1,200 @@
+/* $NetBSD: t_basedirname.c,v 1.2 2011/07/07 09:49:59 jruoho Exp $ */
+
+/*
+ * Regression test for basename(3).
+ *
+ * Written by Jason R. Thorpe <thorpej@NetBSD.org>, Oct. 2002.
+ * Public domain.
+ */
+
+#include <atf-c.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libgen.h>
+
+struct {
+ const char *input;
+ const char *output;
+} test_basename_table[] = {
+/*
+ * The following are taken from the "Sample Input and Output Strings
+ * for basename()" table in IEEE Std 1003.1-2001.
+ */
+ { "/usr/lib", "lib" },
+ { "/usr/", "usr" },
+ { "/", "/" },
+ { "///", "/" },
+ { "//usr//lib//", "lib" },
+/*
+ * IEEE Std 1003.1-2001:
+ *
+ * If path is a null pointer or points to an empty string,
+ * basename() shall return a pointer to the string "." .
+ */
+ { "", "." },
+ { NULL, "." },
+/*
+ * IEEE Std 1003.1-2001:
+ *
+ * If the string is exactly "//", it is implementation-defined
+ * whether "/" or "//" is returned.
+ *
+ * The NetBSD implementation returns "/".
+ */
+ { "//", "/" },
+
+ { NULL, NULL }
+};
+
+struct {
+ const char *input;
+ const char *output;
+} test_dirname_table[] = {
+/*
+ * The following are taken from the "Sample Input and Output Strings
+ * for dirname()" table in IEEE Std 1003.1-2001.
+ */
+ { "/usr/lib", "/usr" },
+ { "/usr/", "/" },
+ { "usr", "." },
+ { "/", "/" },
+ { ".", "." },
+ { "..", "." },
+/*
+ * IEEE Std 1003.1-2001:
+ *
+ * If path is a null pointer or points to an empty string,
+ * dirname() shall return a pointer to the string "." .
+ */
+ { "", "." },
+ { NULL, "." },
+/*
+ * IEEE Std 1003.1-2001:
+ *
+ * Since the meaning of the leading "//" is implementation-defined,
+ * dirname("//foo") may return either "//" or "/" (but nothing else).
+ *
+ * The NetBSD implementation returns "/".
+ */
+ { "//foo", "/" },
+/*
+ * Make sure the trailing slashes after the directory name component
+ * get trimmed. The Std does not talk about this, but this is what
+ * Solaris 8's dirname(3) does.
+ */
+ { "/usr///lib", "/usr" },
+
+ { NULL, NULL }
+};
+
+ATF_TC(basename_posix);
+ATF_TC_HEAD(basename_posix, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test basename(3) with POSIX examples");
+}
+
+ATF_TC_BODY(basename_posix, tc)
+{
+ char testbuf[32], *base;
+ int i;
+
+ for (i = 0; test_basename_table[i].output != NULL; i++) {
+ if (test_basename_table[i].input != NULL) {
+ if (strlen(test_basename_table[i].input) >=
+ sizeof(testbuf))
+ atf_tc_skip("Testbuf too small!");
+ strcpy(testbuf, test_basename_table[i].input);
+ base = basename(testbuf);
+ } else
+ base = basename(NULL);
+
+ /*
+ * basename(3) is allowed to modify the input buffer.
+ * However, that is considered hostile by some programs,
+ * and so we elect to consider this an error.
+ *
+ * This is not a problem, as basename(3) is also allowed
+ * to return a pointer to a statically-allocated buffer
+ * (it is explicitly not required to be reentrant).
+ */
+ if (test_basename_table[i].input != NULL &&
+ strcmp(test_basename_table[i].input, testbuf) != 0) {
+ fprintf(stderr,
+ "Input buffer for \"%s\" was modified\n",
+ test_basename_table[i].input);
+ atf_tc_fail("Input buffer was modified.");
+ }
+
+ /* Make sure the result is correct. */
+ if (strcmp(test_basename_table[i].output, base) != 0) {
+ fprintf(stderr,
+ "Input \"%s\", output \"%s\", expected \"%s\"\n",
+ test_basename_table[i].input ==
+ NULL ? "(null)" : test_basename_table[i].input,
+ base, test_basename_table[i].output);
+ atf_tc_fail("Output does not match expected value.");
+ }
+ }
+}
+
+
+ATF_TC(dirname_posix);
+ATF_TC_HEAD(dirname_posix, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test dirname(3) with POSIX examples");
+}
+
+ATF_TC_BODY(dirname_posix, tc)
+{
+ char testbuf[32], *base;
+ int i;
+
+ for (i = 0; test_dirname_table[i].output != NULL; i++) {
+ if (test_dirname_table[i].input != NULL) {
+ if (strlen(test_dirname_table[i].input) >=
+ sizeof(testbuf))
+ atf_tc_skip("Testbuf too small!");
+ strcpy(testbuf, test_dirname_table[i].input);
+ base = dirname(testbuf);
+ } else
+ base = dirname(NULL);
+
+ /*
+ * dirname(3) is allowed to modify the input buffer.
+ * However, that is considered hostile by some programs,
+ * and so we elect to consider this an error.
+ *
+ * This is not a problem, as dirname(3) is also allowed
+ * to return a pointer to a statically-allocated buffer
+ * (it is explicitly not required to be reentrant).
+ */
+ if (test_dirname_table[i].input != NULL &&
+ strcmp(test_dirname_table[i].input, testbuf) != 0) {
+ fprintf(stderr,
+ "Input buffer for \"%s\" was modified\n",
+ test_dirname_table[i].input);
+ atf_tc_fail("Input buffer was modified.");
+ }
+
+ /* Make sure the result is correct. */
+ if (strcmp(test_dirname_table[i].output, base) != 0) {
+ fprintf(stderr,
+ "Input \"%s\", output \"%s\", expected \"%s\"\n",
+ test_dirname_table[i].input ==
+ NULL ? "(null)" : test_dirname_table[i].input,
+ base, test_dirname_table[i].output);
+ atf_tc_fail("Output does not match expected value.");
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, basename_posix);
+ ATF_TP_ADD_TC(tp, dirname_posix);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c b/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c
new file mode 100644
index 0000000..75ebabb
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_closefrom.c
@@ -0,0 +1,173 @@
+/* $NetBSD: t_closefrom.c,v 1.4 2011/05/11 08:11:36 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_closefrom.c,v 1.4 2011/05/11 08:11:36 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+
+static const char path[] = "closefrom";
+
+ATF_TC_WITH_CLEANUP(closefrom_basic);
+ATF_TC_HEAD(closefrom_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of closefrom(3), #1");
+}
+
+ATF_TC_BODY(closefrom_basic, tc)
+{
+ int fd, cur1, cur2;
+
+ (void)closefrom(STDERR_FILENO + 1);
+
+ fd = open(path, O_RDONLY | O_CREAT, 0400);
+ ATF_REQUIRE(fd >= 0);
+
+ cur1 = fcntl(0, F_MAXFD);
+
+ ATF_REQUIRE(cur1 == STDERR_FILENO + 1);
+ ATF_REQUIRE(closefrom(cur1) == 0);
+
+ cur2 = fcntl(0, F_MAXFD);
+
+ ATF_REQUIRE(cur1 - 1 == cur2);
+ ATF_REQUIRE(close(fd) == -1);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(closefrom_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(closefrom_buffer);
+ATF_TC_HEAD(closefrom_buffer, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of closefrom(3), #2");
+}
+
+ATF_TC_BODY(closefrom_buffer, tc)
+{
+ int buf[16], cur, half;
+ size_t i;
+
+ /*
+ * Open a buffer of descriptors, close the half of
+ * these and verify that the result is consistent.
+ */
+ ATF_REQUIRE(closefrom(STDERR_FILENO + 1) == 0);
+
+ cur = fcntl(0, F_MAXFD);
+ ATF_REQUIRE(cur == STDERR_FILENO);
+
+ for (i = 0; i < __arraycount(buf); i++) {
+ buf[i] = open(path, O_RDWR | O_CREAT, 0600);
+ ATF_REQUIRE(buf[i] >= 0);
+ }
+
+ cur = fcntl(0, F_MAXFD);
+ ATF_REQUIRE(cur == __arraycount(buf) + STDERR_FILENO);
+
+ half = STDERR_FILENO + __arraycount(buf) / 2;
+ ATF_REQUIRE(closefrom(half) == 0);
+
+ cur = fcntl(0, F_MAXFD);
+ ATF_REQUIRE(cur == half - 1);
+
+ for (i = 0; i < __arraycount(buf); i++)
+ (void)close(buf[i]);
+}
+
+ATF_TC_CLEANUP(closefrom_buffer, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(closefrom_err);
+ATF_TC_HEAD(closefrom_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from closefrom(3)");
+}
+
+ATF_TC_BODY(closefrom_err, tc)
+{
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, closefrom(-INT_MAX) == -1);
+}
+
+ATF_TC(closefrom_one);
+ATF_TC_HEAD(closefrom_one, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test closefrom(1)");
+}
+
+ATF_TC_BODY(closefrom_one, tc)
+{
+ pid_t pid;
+ int sta;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (closefrom(1) != 0)
+ _exit(10);
+
+ _exit(fcntl(0, F_MAXFD));
+ }
+
+
+ (void)wait(&sta);
+
+ /*
+ * STDIN_FILENO sould still be open; WEXITSTATUS(1) == 0.
+ */
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != 0)
+ atf_tc_fail("not all descriptors were closed");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, closefrom_basic);
+ ATF_TP_ADD_TC(tp, closefrom_buffer);
+ ATF_TP_ADD_TC(tp, closefrom_err);
+ ATF_TP_ADD_TC(tp, closefrom_one);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c b/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c
new file mode 100644
index 0000000..9eca03b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_cpuset.c
@@ -0,0 +1,114 @@
+/* $NetBSD: t_cpuset.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_cpuset.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $");
+
+#include <atf-c.h>
+#include <limits.h>
+#include <stdio.h>
+#include <sched.h>
+
+ATF_TC(cpuset_err);
+ATF_TC_HEAD(cpuset_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from cpuset(3)");
+}
+
+ATF_TC_BODY(cpuset_err, tc)
+{
+ cpuset_t *set;
+
+ set = cpuset_create();
+ ATF_REQUIRE(set != NULL);
+
+ ATF_CHECK(cpuset_set(-1, set) == -1);
+ ATF_CHECK(cpuset_clr(-1, set) == -1);
+ ATF_CHECK(cpuset_isset(-1, set) == -1);
+
+ ATF_CHECK(cpuset_set(INT_MAX, set) == -1);
+ ATF_CHECK(cpuset_clr(INT_MAX, set) == -1);
+ ATF_CHECK(cpuset_isset(INT_MAX, set) == -1);
+
+ cpuset_destroy(set);
+}
+
+ATF_TC(cpuset_set);
+ATF_TC_HEAD(cpuset_set, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cpuset_set(3)");
+}
+
+ATF_TC_BODY(cpuset_set, tc)
+{
+ cpuset_t *set;
+
+ set = cpuset_create();
+ ATF_REQUIRE(set != NULL);
+
+ ATF_REQUIRE(cpuset_set(0, set) == 0);
+ ATF_REQUIRE(cpuset_isset(0, set) > 0);
+ ATF_REQUIRE(cpuset_clr(0, set) == 0);
+ ATF_REQUIRE(cpuset_isset(0, set) == 0);
+
+ cpuset_destroy(set);
+}
+
+ATF_TC(cpuset_size);
+ATF_TC_HEAD(cpuset_size, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test puset_size(3)");
+}
+
+ATF_TC_BODY(cpuset_size, tc)
+{
+ cpuset_t *set;
+ size_t size;
+
+ set = cpuset_create();
+ ATF_REQUIRE(set != NULL);
+
+ size = cpuset_size(set);
+
+ ATF_CHECK(cpuset_set((size * 8) - 1, set) == 0);
+ ATF_CHECK(cpuset_set((size * 8) + 1, set) == -1);
+
+ cpuset_destroy(set);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, cpuset_err);
+ ATF_TP_ADD_TC(tp, cpuset_set);
+ ATF_TP_ADD_TC(tp, cpuset_size);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_dir.c b/contrib/netbsd-tests/lib/libc/gen/t_dir.c
new file mode 100644
index 0000000..81412c1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_dir.c
@@ -0,0 +1,165 @@
+/* $NetBSD: t_dir.c,v 1.6 2013/10/19 17:45:00 christos Exp $ */
+
+/*-
+ * 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.h>
+
+#include <assert.h>
+#include <dirent.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/stat.h>
+
+ATF_TC(seekdir_basic);
+ATF_TC_HEAD(seekdir_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Check telldir(3) and seekdir(3) "
+ "for correct behavior (PR lib/24324)");
+}
+
+ATF_TC_BODY(seekdir_basic, tc)
+{
+ DIR *dp;
+ char *wasname;
+ struct dirent *entry;
+ long here;
+
+ mkdir("t", 0755);
+ creat("t/a", 0600);
+ creat("t/b", 0600);
+ creat("t/c", 0600);
+
+ dp = opendir("t");
+ if ( dp == NULL)
+ atf_tc_fail("Could not open temp directory.");
+
+ /* skip two for . and .. */
+ entry = readdir(dp);
+ entry = readdir(dp);
+
+ /* get first entry */
+ entry = readdir(dp);
+ here = telldir(dp);
+
+ /* get second entry */
+ entry = readdir(dp);
+ wasname = strdup(entry->d_name);
+ if (wasname == NULL)
+ atf_tc_fail("cannot allocate memory");
+
+ /* get third entry */
+ entry = readdir(dp);
+
+ /* try to return to the position after the first entry */
+ seekdir(dp, here);
+ entry = readdir(dp);
+
+ if (entry == NULL)
+ atf_tc_fail("entry 1 not found");
+ if (strcmp(entry->d_name, wasname) != 0)
+ atf_tc_fail("1st seekdir found wrong name");
+
+ /* try again, and throw in a telldir() for good measure */
+ seekdir(dp, here);
+ here = telldir(dp);
+ entry = readdir(dp);
+
+ if (entry == NULL)
+ atf_tc_fail("entry 2 not found");
+ if (strcmp(entry->d_name, wasname) != 0)
+ atf_tc_fail("2nd seekdir found wrong name");
+
+ /* One more time, to make sure that telldir() doesn't affect result */
+ seekdir(dp, here);
+ entry = readdir(dp);
+
+ if (entry == NULL)
+ atf_tc_fail("entry 3 not found");
+ if (strcmp(entry->d_name, wasname) != 0)
+ atf_tc_fail("3rd seekdir found wrong name");
+
+ closedir(dp);
+}
+
+ATF_TC(telldir_leak);
+ATF_TC_HEAD(telldir_leak, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Check telldir(3) for memory leakage (PR lib/24324)");
+}
+
+ATF_TC_BODY(telldir_leak, tc)
+{
+ DIR *dp;
+ char *memused;
+ int i;
+ int oktouse = 4096;
+
+ dp = opendir(".");
+ if (dp == NULL)
+ atf_tc_fail("Could not open current directory");
+
+ (void)telldir(dp);
+ memused = sbrk(0);
+ closedir(dp);
+
+ for (i = 0; i < 1000; i++) {
+ dp = opendir(".");
+ if (dp == NULL)
+ atf_tc_fail("Could not open current directory");
+
+ (void)telldir(dp);
+ closedir(dp);
+
+ if ((char *)sbrk(0) - memused > oktouse) {
+ (void)printf("Used %td extra bytes for %d telldir "
+ "calls", ((char *)sbrk(0) - memused), i);
+ oktouse = (char *)sbrk(0) - memused;
+ }
+ }
+ if (oktouse > 4096) {
+ atf_tc_fail("Failure: leaked %d bytes", oktouse);
+ } else {
+ (void)printf("OK: used %td bytes\n", (char *)(sbrk(0))-memused);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, seekdir_basic);
+ ATF_TP_ADD_TC(tp, telldir_leak);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c b/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c
new file mode 100644
index 0000000..ef372f7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c
@@ -0,0 +1,135 @@
+/* $NetBSD: t_floatunditf.c,v 1.6 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 2014 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 <inttypes.h>
+#include <math.h>
+
+#ifdef __HAVE_LONG_DOUBLE
+static const struct {
+ uint64_t u64;
+ long double ld;
+} testcases[] = {
+ { 0xffffffffffffffffULL, 0xf.fffffffffffffffp+60L },
+ { 0xfffffffffffffffeULL, 0xf.ffffffffffffffep+60L },
+ { 0xfffffffffffffffdULL, 0xf.ffffffffffffffdp+60L },
+ { 0xfffffffffffffffcULL, 0xf.ffffffffffffffcp+60L },
+ { 0x7fffffffffffffffULL, 0xf.ffffffffffffffep+59L },
+ { 0x3fffffffffffffffULL, 0xf.ffffffffffffffcp+58L },
+ { 0x1fffffffffffffffULL, 0xf.ffffffffffffff8p+57L },
+ { 0xfffffffffffffffULL, 0xf.ffffffffffffffp+56L },
+ { 0x7ffffffffffffffULL, 0xf.fffffffffffffep+55L },
+ { 0x3ffffffffffffffULL, 0xf.fffffffffffffcp+54L },
+ { 0x1ffffffffffffffULL, 0xf.fffffffffffff8p+53L },
+ { 0xffffffffffffffULL, 0xf.fffffffffffffp+52L },
+ { 0x7fffffffffffffULL, 0xf.ffffffffffffep+51L },
+ { 0x3fffffffffffffULL, 0xf.ffffffffffffcp+50L },
+ { 0x1fffffffffffffULL, 0xf.ffffffffffff8p+49L },
+ { 0xfffffffffffffULL, 0xf.ffffffffffffp+48L },
+ { 0x7ffffffffffffULL, 0xf.fffffffffffep+47L },
+ { 0x3ffffffffffffULL, 0xf.fffffffffffcp+46L },
+ { 0x1ffffffffffffULL, 0xf.fffffffffff8p+45L },
+ { 0xffffffffffffULL, 0xf.fffffffffffp+44L },
+ { 0x7fffffffffffULL, 0xf.ffffffffffep+43L },
+ { 0x3fffffffffffULL, 0xf.ffffffffffcp+42L },
+ { 0x1fffffffffffULL, 0xf.ffffffffff8p+41L },
+ { 0xfffffffffffULL, 0xf.ffffffffffp+40L },
+ { 0x7ffffffffffULL, 0xf.fffffffffep+39L },
+ { 0x3ffffffffffULL, 0xf.fffffffffcp+38L },
+ { 0x1ffffffffffULL, 0xf.fffffffff8p+37L },
+ { 0xffffffffffULL, 0xf.fffffffffp+36L },
+ { 0x7fffffffffULL, 0xf.ffffffffep+35L },
+ { 0x3fffffffffULL, 0xf.ffffffffcp+34L },
+ { 0x1fffffffffULL, 0xf.ffffffff8p+33L },
+ { 0xfffffffffULL, 0xf.ffffffffp+32L },
+ { 0x7ffffffffULL, 0xf.fffffffep+31L },
+ { 0x3ffffffffULL, 0xf.fffffffcp+30L },
+ { 0x1ffffffffULL, 0xf.fffffff8p+29L },
+ { 0xffffffffULL, 0xf.fffffffp+28L },
+ { 0x7fffffffULL, 0xf.ffffffep+27L },
+ { 0x3fffffffULL, 0xf.ffffffcp+26L },
+ { 0x1fffffffULL, 0xf.ffffff8p+25L },
+ { 0xfffffffULL, 0xf.ffffffp+24L },
+ { 0x7ffffffULL, 0xf.fffffep+23L },
+ { 0x3ffffffULL, 0xf.fffffcp+22L },
+ { 0x1ffffffULL, 0xf.fffff8p+21L },
+ { 0xffffffULL, 0xf.fffffp+20L },
+ { 0x7fffffULL, 0xf.ffffep+19L },
+ { 0x3fffffULL, 0xf.ffffcp+18L },
+ { 0x1fffffULL, 0xf.ffff8p+17L },
+ { 0xfffffULL, 0xf.ffffp+16L },
+ { 0x7ffffULL, 0xf.fffep+15L },
+ { 0x3ffffULL, 0xf.fffcp+14L },
+ { 0x1ffffULL, 0xf.fff8p+13L },
+ { 0xffffULL, 0xf.fffp+12L },
+ { 0x7fffULL, 0xf.ffep+11L },
+ { 0x3fffULL, 0xf.ffcp+10L },
+ { 0x1fffULL, 0xf.ff8p+9L },
+ { 0xfffULL, 0xf.ffp+8L },
+ { 0x7ffULL, 0xf.fep+7L },
+ { 0x3ffULL, 0xf.fcp+6L },
+ { 0x1ffULL, 0xf.f8p+5L },
+ { 0xffULL, 0xf.fp+4L },
+ { 0x7fULL, 0xf.ep+3L },
+ { 0x3fULL, 0xf.cp+2L },
+ { 0x1fULL, 0xf.8p+1L },
+ { 0xfULL, 0xfp+0L },
+ { 0x7ULL, 0xep-1L },
+ { 0x3ULL, 0xcp-2L },
+ { 0x1ULL, 0x8p-3L },
+};
+#endif
+
+ATF_TC(floatunditf);
+ATF_TC_HEAD(floatunditf, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Verify that uint64 -> long double conversion works");
+}
+
+ATF_TC_BODY(floatunditf, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ size_t i;
+
+ for (i = 0; i < __arraycount(testcases); ++i)
+ ATF_CHECK_MSG(
+ testcases[i].ld == (long double)testcases[i].u64,
+ "#%zu: expected %.20Lf, got %.20Lf\n", i,
+ testcases[i].ld,
+ (long double)testcases[i].u64);
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, floatunditf);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c b/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c
new file mode 100644
index 0000000..ab95400
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c
@@ -0,0 +1,117 @@
+/* $NetBSD: t_fmtcheck.c,v 1.3 2014/06/14 08:19:02 apb Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Allen Briggs.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+
+const char *fmtcheck(const char *f1, const char *f2)
+ __attribute__((__format_arg__(2)));
+
+#include <err.h>
+
+struct test_fmt {
+ const char *fmt1;
+ const char *fmt2;
+ int correct;
+} test_fmts[] = {
+ { "%d", "%d", 1 },
+ { "%2d", "%2.2d", 1 },
+ { "%x", "%d", 1 },
+ { "%u", "%d", 1 },
+ { "%03d", "%d", 1 },
+ { "%-2d", "%d", 1 },
+ { "%d", "%-12.1d", 1 },
+ { "%d", "%-01.3d", 1 },
+ { "%X", "%-01.3d", 1 },
+ { "%D", "%ld", 1 },
+ { "%s", "%s", 1 },
+ { "%s", "This is a %s test", 1 },
+ { "Hi, there. This is a %s test", "%s", 1 },
+ { "%d", "%s", 2 },
+ { "%e", "%s", 2 },
+ { "%r", "%d", 2 },
+ { "%*.2d", "%*d", 1 },
+ { "%2.*d", "%*d", 2 },
+ { "%*d", "%*d", 1 },
+ { "%-3", "%d", 2 },
+ { "%d %s", "%d", 2 },
+ { "%*.*.*d", "%*.*.*d", 2 },
+ { "%d", "%d %s", 1 },
+ { "%40s", "%20s", 1 },
+ { "%x %x %x", "%o %u %d", 1 },
+ { "%o %u %d", "%x %x %X", 1 },
+ { "%#o %u %#-d", "%x %#x %X", 1 },
+ { "%qd", "%llx", 1 },
+ { "%%", "%llx", 1 },
+ { "%ld %30s %#llx %-10.*e", "This number %lu%% and string %s has %qd numbers and %.*g floats", 1 },
+ { "%o", "%lx", 2 },
+ { "%p", "%lu", 2 },
+};
+
+ATF_TC(fmtcheck_basic);
+ATF_TC_HEAD(fmtcheck_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test fmtcheck(3)");
+}
+
+ATF_TC_BODY(fmtcheck_basic, tc)
+{
+ unsigned int i, r;
+ const char *f, *cf, *f1, *f2;
+
+ r = 0;
+ for (i = 0 ; i < __arraycount(test_fmts); i++) {
+ f1 = test_fmts[i].fmt1;
+ f2 = test_fmts[i].fmt2;
+ f = fmtcheck(f1, f2);
+ if (test_fmts[i].correct == 1) {
+ cf = f1;
+ } else {
+ cf = f2;
+ }
+ if (f != cf) {
+ r++;
+ atf_tc_fail_nonfatal("Test %d: (%s) vs. (%s) failed "
+ "(should have returned %s)", i, f1, f2,
+ (test_fmts[i].correct == 1) ? "1st" : "2nd");
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fmtcheck_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c b/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c
new file mode 100644
index 0000000..f90d8cf
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c
@@ -0,0 +1,167 @@
+/* $NetBSD: t_fnmatch.c,v 1.3 2012/04/08 09:58:59 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_fnmatch.c,v 1.3 2012/04/08 09:58:59 jruoho Exp $");
+
+#include <atf-c.h>
+#include <fnmatch.h>
+#include <stdio.h>
+
+ATF_TC(fnmatch_backslashes);
+ATF_TC_HEAD(fnmatch_backslashes, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test translation of '\\' with fnmatch(3) (PR lib/41558)");
+}
+
+ATF_TC_BODY(fnmatch_backslashes, tc)
+{
+ const int rv = fnmatch(/* pattern */ "\\", "\\", 0);
+
+ if (rv != FNM_NOMATCH)
+ atf_tc_fail("fnmatch(3) did not translate '\\'");
+}
+
+ATF_TC(fnmatch_casefold);
+ATF_TC_HEAD(fnmatch_casefold, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test FNM_CASEFOLD");
+}
+
+ATF_TC_BODY(fnmatch_casefold, tc)
+{
+ ATF_CHECK(fnmatch("xxx", "XXX", 0) != 0);
+ ATF_CHECK(fnmatch("XXX", "xxx", 0) != 0);
+ ATF_CHECK(fnmatch("xxx", "XxX", 0) != 0);
+ ATF_CHECK(fnmatch("XxX", "xxx", 0) != 0);
+ ATF_CHECK(fnmatch("x*x", "XXX", 0) != 0);
+ ATF_CHECK(fnmatch("**x", "XXX", 0) != 0);
+ ATF_CHECK(fnmatch("*?x", "XXX", 0) != 0);
+
+ ATF_CHECK(fnmatch("xxx", "XXX", FNM_CASEFOLD) == 0);
+ ATF_CHECK(fnmatch("XXX", "xxx", FNM_CASEFOLD) == 0);
+ ATF_CHECK(fnmatch("xxx", "XxX", FNM_CASEFOLD) == 0);
+ ATF_CHECK(fnmatch("XxX", "xxx", FNM_CASEFOLD) == 0);
+ ATF_CHECK(fnmatch("x*x", "XXX", FNM_CASEFOLD) == 0);
+ ATF_CHECK(fnmatch("**x", "XXX", FNM_CASEFOLD) == 0);
+ ATF_CHECK(fnmatch("*?x", "XXX", FNM_CASEFOLD) == 0);
+}
+
+ATF_TC(fnmatch_leadingdir);
+ATF_TC_HEAD(fnmatch_leadingdir, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test FNM_LEADING_DIR");
+}
+
+ATF_TC_BODY(fnmatch_leadingdir, tc)
+{
+ ATF_CHECK(fnmatch("", "/*", 0) != 0);
+ ATF_CHECK(fnmatch(" ", " /*", 0) != 0);
+ ATF_CHECK(fnmatch("x", "x/*", 0) != 0);
+ ATF_CHECK(fnmatch("///", "////*", 0) != 0);
+
+ ATF_CHECK(fnmatch("", "/*", FNM_LEADING_DIR) == 0);
+ ATF_CHECK(fnmatch(" ", " /*", FNM_LEADING_DIR) == 0);
+ ATF_CHECK(fnmatch("x", "x/*", FNM_LEADING_DIR) == 0);
+ ATF_CHECK(fnmatch("///", "////*", FNM_LEADING_DIR) == 0);
+}
+
+ATF_TC(fnmatch_noescape);
+ATF_TC_HEAD(fnmatch_noescape, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test FNM_NOESCAPE");
+}
+
+ATF_TC_BODY(fnmatch_noescape, tc)
+{
+ ATF_CHECK(fnmatch(" \\x", " \\x", 0) != 0);
+ ATF_CHECK(fnmatch("xx\\x", "xx\\x", 0) != 0);
+ ATF_CHECK(fnmatch("\\xxx", "\\xxx", 0) != 0);
+
+ ATF_CHECK(fnmatch(" \\x", " \\x", FNM_NOESCAPE) == 0);
+ ATF_CHECK(fnmatch("xx\\x", "xx\\x", FNM_NOESCAPE) == 0);
+ ATF_CHECK(fnmatch("\\xxx", "\\xxx", FNM_NOESCAPE) == 0);
+}
+
+ATF_TC(fnmatch_pathname);
+ATF_TC_HEAD(fnmatch_pathname, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test FNM_PATHNAME");
+}
+
+ATF_TC_BODY(fnmatch_pathname, tc)
+{
+ ATF_CHECK(fnmatch("???x", "xxx/x", FNM_PATHNAME) != 0);
+ ATF_CHECK(fnmatch("***x", "xxx/x", FNM_PATHNAME) != 0);
+
+ ATF_CHECK(fnmatch("???x", "xxxx", FNM_PATHNAME) == 0);
+ ATF_CHECK(fnmatch("*/xxx", "/xxx", FNM_PATHNAME) == 0);
+ ATF_CHECK(fnmatch("x/*.y", "x/z.y", FNM_PATHNAME) == 0);
+}
+
+ATF_TC(fnmatch_period);
+ATF_TC_HEAD(fnmatch_period, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test FNM_PERIOD");
+}
+
+ATF_TC_BODY(fnmatch_period, tc)
+{
+ ATF_CHECK(fnmatch("*x*", "X", FNM_PERIOD) != 0);
+ ATF_CHECK(fnmatch("*x*", "X", FNM_PERIOD | FNM_CASEFOLD) == 0);
+
+ ATF_CHECK(fnmatch("x?y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0);
+ ATF_CHECK(fnmatch("x*y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0);
+ ATF_CHECK(fnmatch("*.c", "x.c", FNM_PATHNAME | FNM_PERIOD) == 0);
+ ATF_CHECK(fnmatch("*/?", "x/y", FNM_PATHNAME | FNM_PERIOD) == 0);
+ ATF_CHECK(fnmatch("*/*", "x/y", FNM_PATHNAME | FNM_PERIOD) == 0);
+ ATF_CHECK(fnmatch(".*/?", ".x/y", FNM_PATHNAME | FNM_PERIOD) == 0);
+ ATF_CHECK(fnmatch("*/.?", "x/.y", FNM_PATHNAME | FNM_PERIOD) == 0);
+ ATF_CHECK(fnmatch("x[.]y", "x.y", FNM_PATHNAME | FNM_PERIOD) == 0);
+
+ ATF_CHECK(fnmatch("?x/y", ".x/y", FNM_PATHNAME | FNM_PERIOD) != 0);
+ ATF_CHECK(fnmatch("*x/y", ".x/y", FNM_PATHNAME | FNM_PERIOD) != 0);
+ ATF_CHECK(fnmatch("x/?y", "x/.y", FNM_PATHNAME | FNM_PERIOD) != 0);
+ ATF_CHECK(fnmatch("x/*y", "x/.y", FNM_PATHNAME | FNM_PERIOD) != 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fnmatch_backslashes);
+ ATF_TP_ADD_TC(tp, fnmatch_casefold);
+ ATF_TP_ADD_TC(tp, fnmatch_leadingdir);
+ ATF_TP_ADD_TC(tp, fnmatch_noescape);
+ ATF_TP_ADD_TC(tp, fnmatch_pathname);
+ ATF_TP_ADD_TC(tp, fnmatch_period);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c b/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c
new file mode 100644
index 0000000..21dea9e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c
@@ -0,0 +1,206 @@
+/* $NetBSD: t_fpclassify.c,v 1.3 2011/10/01 21:47:08 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 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 <float.h>
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifndef _FLOAT_IEEE754
+
+ATF_TC(no_test);
+ATF_TC_HEAD(no_test, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Dummy test");
+}
+
+ATF_TC_BODY(no_test,tc)
+{
+ atf_tc_skip("Test not available on this architecture");
+}
+
+#else /* defined(_FLOAT_IEEE754) */
+
+ATF_TC(fpclassify_float);
+ATF_TC_HEAD(fpclassify_float, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test float operations");
+}
+
+ATF_TC_BODY(fpclassify_float, tc)
+{
+ float d0, d1, d2, f, ip;
+ int e, i;
+
+ d0 = FLT_MIN;
+ ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL);
+ f = frexpf(d0, &e);
+ ATF_REQUIRE_EQ(e, FLT_MIN_EXP);
+ ATF_REQUIRE_EQ(f, 0.5);
+ d1 = d0;
+
+ /* shift a "1" bit through the mantissa (skip the implicit bit) */
+ for (i = 1; i < FLT_MANT_DIG; i++) {
+ d1 /= 2;
+ ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL);
+ ATF_REQUIRE(d1 > 0 && d1 < d0);
+
+ d2 = ldexpf(d0, -i);
+ ATF_REQUIRE_EQ(d2, d1);
+
+ d2 = modff(d1, &ip);
+ ATF_REQUIRE_EQ(d2, d1);
+ ATF_REQUIRE_EQ(ip, 0);
+
+ f = frexpf(d1, &e);
+ ATF_REQUIRE_EQ(e, FLT_MIN_EXP - i);
+ ATF_REQUIRE_EQ(f, 0.5);
+ }
+
+ d1 /= 2;
+ ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO);
+ f = frexpf(d1, &e);
+ ATF_REQUIRE_EQ(e, 0);
+ ATF_REQUIRE_EQ(f, 0);
+}
+
+ATF_TC(fpclassify_double);
+ATF_TC_HEAD(fpclassify_double, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test double operations");
+}
+
+ATF_TC_BODY(fpclassify_double, tc)
+{
+ double d0, d1, d2, f, ip;
+ int e, i;
+
+ d0 = DBL_MIN;
+ ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL);
+ f = frexp(d0, &e);
+ ATF_REQUIRE_EQ(e, DBL_MIN_EXP);
+ ATF_REQUIRE_EQ(f, 0.5);
+ d1 = d0;
+
+ /* shift a "1" bit through the mantissa (skip the implicit bit) */
+ for (i = 1; i < DBL_MANT_DIG; i++) {
+ d1 /= 2;
+ ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL);
+ ATF_REQUIRE(d1 > 0 && d1 < d0);
+
+ d2 = ldexp(d0, -i);
+ ATF_REQUIRE_EQ(d2, d1);
+
+ d2 = modf(d1, &ip);
+ ATF_REQUIRE_EQ(d2, d1);
+ ATF_REQUIRE_EQ(ip, 0);
+
+ f = frexp(d1, &e);
+ ATF_REQUIRE_EQ(e, DBL_MIN_EXP - i);
+ ATF_REQUIRE_EQ(f, 0.5);
+ }
+
+ d1 /= 2;
+ ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO);
+ f = frexp(d1, &e);
+ ATF_REQUIRE_EQ(e, 0);
+ ATF_REQUIRE_EQ(f, 0);
+}
+
+/*
+ * XXX NetBSD doesn't have long-double flavors of frexp, ldexp, and modf,
+ * XXX so this test is disabled.
+ */
+
+#ifdef TEST_LONG_DOUBLE
+
+ATF_TC(fpclassify_long_double);
+ATF_TC_HEAD(fpclassify_long_double, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test long double operations");
+}
+
+ATF_TC_BODY(fpclassify_long_double, tc)
+{
+ long double d0, d1, d2, f, ip;
+ int e, i;
+
+ d0 = LDBL_MIN;
+ ATF_REQUIRE_EQ(fpclassify(d0), FP_NORMAL);
+ f = frexpl(d0, &e);
+ ATF_REQUIRE_EQ(e, LDBL_MIN_EXP);
+ ATF_REQUIRE_EQ(f, 0.5);
+ d1 = d0;
+
+ /* shift a "1" bit through the mantissa (skip the implicit bit) */
+ for (i = 1; i < LDBL_MANT_DIG; i++) {
+ d1 /= 2;
+ ATF_REQUIRE_EQ(fpclassify(d1), FP_SUBNORMAL);
+ ATF_REQUIRE(d1 > 0 && d1 < d0);
+
+ d2 = ldexpl(d0, -i);
+ ATF_REQUIRE_EQ(d2, d1);
+
+ d2 = modfl(d1, &ip);
+ ATF_REQUIRE_EQ(d2, d1);
+ ATF_REQUIRE_EQ(ip, 0);
+
+ f = frexpl(d1, &e);
+ ATF_REQUIRE_EQ(e, LDBL_MIN_EXP - i);
+ ATF_REQUIRE_EQ(f, 0.5);
+ }
+
+ d1 /= 2;
+ ATF_REQUIRE_EQ(fpclassify(d1), FP_ZERO);
+ f = frexpl(d1, &e);
+ ATF_REQUIRE_EQ(e, 0);
+ ATF_REQUIRE_EQ(f, 0);
+}
+#endif /* TEST_LONG_DOUBLE */
+#endif /* _FLOAT_IEEE754 */
+
+ATF_TP_ADD_TCS(tp)
+{
+
+#ifndef _FLOAT_IEEE754
+ ATF_TP_ADD_TC(tp, no_test);
+#else
+ ATF_TP_ADD_TC(tp, fpclassify_float);
+ ATF_TP_ADD_TC(tp, fpclassify_double);
+#ifdef TEST_LONG_DOUBLE
+ ATF_TP_ADD_TC(tp, fpclassify_long_double);
+#endif /* TEST_LONG_DOUBLE */
+#endif /* _FLOAT_IEEE754 */
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c
new file mode 100644
index 0000000..3366c1f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c
@@ -0,0 +1,354 @@
+/* $NetBSD: t_fpsetmask.c,v 1.14 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 1995 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/param.h>
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <signal.h>
+#include <float.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "isqemu.h"
+
+#ifndef _FLOAT_IEEE754
+
+ATF_TC(no_test);
+ATF_TC_HEAD(no_test, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Dummy test case");
+}
+
+ATF_TC_BODY(no_test, tc)
+{
+
+ atf_tc_skip("Test not available on this architecture.");
+}
+
+#else /* defined(_FLOAT_IEEE754) */
+
+#include <ieeefp.h>
+
+const char *skip_mesg;
+const char *skip_arch;
+
+void sigfpe(int, siginfo_t *, void *);
+
+volatile sig_atomic_t signal_caught;
+volatile int sicode;
+
+static volatile const float f_one = 1.0;
+static volatile const float f_zero = 0.0;
+static volatile const double d_one = 1.0;
+static volatile const double d_zero = 0.0;
+static volatile const long double ld_one = 1.0;
+static volatile const long double ld_zero = 0.0;
+
+static volatile const float f_huge = FLT_MAX;
+static volatile const float f_tiny = FLT_MIN;
+static volatile const double d_huge = DBL_MAX;
+static volatile const double d_tiny = DBL_MIN;
+static volatile const long double ld_huge = LDBL_MAX;
+static volatile const long double ld_tiny = LDBL_MIN;
+
+static volatile float f_x;
+static volatile double d_x;
+static volatile long double ld_x;
+
+/* trip divide by zero */
+static void
+f_dz(void)
+{
+
+ f_x = f_one / f_zero;
+}
+
+static void
+d_dz(void)
+{
+
+ d_x = d_one / d_zero;
+}
+
+static void
+ld_dz(void)
+{
+
+ ld_x = ld_one / ld_zero;
+}
+
+/* trip invalid operation */
+static void
+d_inv(void)
+{
+
+ d_x = d_zero / d_zero;
+}
+
+static void
+ld_inv(void)
+{
+
+ ld_x = ld_zero / ld_zero;
+}
+
+static void
+f_inv(void)
+{
+
+ f_x = f_zero / f_zero;
+}
+
+/* trip overflow */
+static void
+f_ofl(void)
+{
+
+ f_x = f_huge * f_huge;
+}
+
+static void
+d_ofl(void)
+{
+
+ d_x = d_huge * d_huge;
+}
+
+static void
+ld_ofl(void)
+{
+
+ ld_x = ld_huge * ld_huge;
+}
+
+/* trip underflow */
+static void
+f_ufl(void)
+{
+
+ f_x = f_tiny * f_tiny;
+}
+
+static void
+d_ufl(void)
+{
+
+ d_x = d_tiny * d_tiny;
+}
+
+static void
+ld_ufl(void)
+{
+
+ ld_x = ld_tiny * ld_tiny;
+}
+
+struct ops {
+ void (*op)(void);
+ fp_except mask;
+ int sicode;
+};
+
+static const struct ops float_ops[] = {
+ { f_dz, FP_X_DZ, FPE_FLTDIV },
+ { f_inv, FP_X_INV, FPE_FLTINV },
+ { f_ofl, FP_X_OFL, FPE_FLTOVF },
+ { f_ufl, FP_X_UFL, FPE_FLTUND },
+ { NULL, 0, 0 }
+};
+
+static const struct ops double_ops[] = {
+ { d_dz, FP_X_DZ, FPE_FLTDIV },
+ { d_inv, FP_X_INV, FPE_FLTINV },
+ { d_ofl, FP_X_OFL, FPE_FLTOVF },
+ { d_ufl, FP_X_UFL, FPE_FLTUND },
+ { NULL, 0, 0 }
+};
+
+static const struct ops long_double_ops[] = {
+ { ld_dz, FP_X_DZ, FPE_FLTDIV },
+ { ld_inv, FP_X_INV, FPE_FLTINV },
+ { ld_ofl, FP_X_OFL, FPE_FLTOVF },
+ { ld_ufl, FP_X_UFL, FPE_FLTUND },
+ { NULL, 0, 0 }
+};
+
+static sigjmp_buf b;
+
+static void
+fpsetmask_masked(const struct ops *test_ops)
+{
+ struct sigaction sa;
+ fp_except ex1, ex2;
+ const struct ops *t;
+
+ /* mask all exceptions, clear history */
+ fpsetmask(0);
+ fpsetsticky(0);
+
+ /* set up signal handler */
+ sa.sa_sigaction = sigfpe;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+ sigaction(SIGFPE, &sa, 0);
+ signal_caught = 0;
+
+ /*
+ * exceptions masked, check whether "sticky" bits are set correctly
+ */
+ for (t = test_ops; t->op != NULL; t++) {
+ (*t->op)();
+ ex1 = fpgetsticky();
+ ATF_CHECK_EQ(ex1 & t->mask, t->mask);
+ ATF_CHECK_EQ(signal_caught, 0);
+
+ /* check correct fpsetsticky() behaviour */
+ ex2 = fpsetsticky(0);
+ ATF_CHECK_EQ(fpgetsticky(), 0);
+ ATF_CHECK_EQ(ex1, ex2);
+ }
+}
+
+/* force delayed exceptions to be delivered */
+#define BARRIER() fpsetmask(0); f_x = f_one * f_one
+
+static void
+fpsetmask_unmasked(const struct ops *test_ops)
+{
+ struct sigaction sa;
+ int r;
+ const struct ops *volatile t;
+
+ /* mask all exceptions, clear history */
+ fpsetmask(0);
+ fpsetsticky(0);
+
+ /* set up signal handler */
+ sa.sa_sigaction = sigfpe;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+ sigaction(SIGFPE, &sa, 0);
+ signal_caught = 0;
+
+ /*
+ * exception unmasked, check SIGFPE delivery and correct siginfo
+ */
+ for (t = test_ops; t->op != NULL; t++) {
+ fpsetmask(t->mask);
+ r = sigsetjmp(b, 1);
+ if (!r) {
+ (*t->op)();
+ BARRIER();
+ }
+ ATF_CHECK_EQ(signal_caught, 1);
+ ATF_CHECK_EQ(sicode, t->sicode);
+ signal_caught = 0;
+ }
+}
+
+void
+sigfpe(int s, siginfo_t *si, void *c)
+{
+ signal_caught = 1;
+ sicode = si->si_code;
+ siglongjmp(b, 1);
+}
+
+#define TEST(m, t) \
+ ATF_TC(m##_##t); \
+ \
+ ATF_TC_HEAD(m##_##t, tc) \
+ { \
+ \
+ atf_tc_set_md_var(tc, "descr", \
+ "Test " ___STRING(m) " exceptions for " \
+ ___STRING(t) "values"); \
+ } \
+ \
+ ATF_TC_BODY(m##_##t, tc) \
+ { \
+ if (strcmp(MACHINE, "macppc") == 0) \
+ atf_tc_expect_fail("PR port-macppc/46319"); \
+ \
+ if (isQEMU()) \
+ atf_tc_expect_fail("PR misc/44767"); \
+ \
+ m(t##_ops); \
+ }
+
+TEST(fpsetmask_masked, float)
+TEST(fpsetmask_masked, double)
+TEST(fpsetmask_masked, long_double)
+TEST(fpsetmask_unmasked, float)
+TEST(fpsetmask_unmasked, double)
+TEST(fpsetmask_unmasked, long_double)
+
+ATF_TC(fpsetmask_basic);
+ATF_TC_HEAD(fpsetmask_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of fpsetmask(3)");
+}
+
+ATF_TC_BODY(fpsetmask_basic, tc)
+{
+ size_t i;
+ fp_except_t msk, lst[] = { FP_X_INV, FP_X_DZ, FP_X_OFL, FP_X_UFL };
+
+ msk = fpgetmask();
+ for (i = 0; i < __arraycount(lst); i++) {
+ fpsetmask(msk | lst[i]);
+ ATF_CHECK((fpgetmask() & lst[i]) != 0);
+ fpsetmask(msk & lst[i]);
+ ATF_CHECK((fpgetmask() & lst[i]) == 0);
+ }
+
+}
+
+#endif /* defined(_FLOAT_IEEE754) */
+
+ATF_TP_ADD_TCS(tp)
+{
+
+#ifndef _FLOAT_IEEE754
+ ATF_TP_ADD_TC(tp, no_test);
+#else
+ ATF_TP_ADD_TC(tp, fpsetmask_basic);
+ ATF_TP_ADD_TC(tp, fpsetmask_masked_float);
+ ATF_TP_ADD_TC(tp, fpsetmask_masked_double);
+ ATF_TP_ADD_TC(tp, fpsetmask_masked_long_double);
+ ATF_TP_ADD_TC(tp, fpsetmask_unmasked_float);
+ ATF_TP_ADD_TC(tp, fpsetmask_unmasked_double);
+ ATF_TP_ADD_TC(tp, fpsetmask_unmasked_long_double);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c b/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c
new file mode 100644
index 0000000..0f23e74
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c
@@ -0,0 +1,163 @@
+/* $NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 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/cdefs.h>
+__RCSID("$NetBSD: t_fpsetround.c,v 1.6 2011/10/01 17:46:10 christos Exp $");
+
+#include <float.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <atf-c.h>
+
+ATF_TC(fpsetround_basic);
+ATF_TC_HEAD(fpsetround_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Minimal testing of fpgetround(3) and fpsetround(3)");
+}
+
+#ifdef _FLOAT_IEEE754
+#include <ieeefp.h>
+
+static const struct {
+ const char *n;
+ int rm;
+ int rf;
+} rnd[] = {
+ { "RN", FP_RN, 1 },
+ { "RP", FP_RP, 2 },
+ { "RM", FP_RM, 3 },
+ { "RZ", FP_RZ, 0 },
+
+};
+
+static const struct {
+ const char *n;
+ int v[4];
+} tst[] = { /* RN RP RM RZ */
+ { "1.1", { 1, 1, 2, 1 } },
+ { "1.5", { 1, 2, 2, 1 } },
+ { "1.9", { 1, 2, 2, 1 } },
+ { "2.1", { 2, 2, 3, 2 } },
+ { "2.5", { 2, 2, 3, 2 } },
+ { "2.9", { 2, 3, 3, 2 } },
+ { "-1.1", { -1, -1, -1, -2 } },
+ { "-1.5", { -1, -2, -1, -2 } },
+ { "-1.9", { -1, -2, -1, -2 } },
+ { "-2.1", { -2, -2, -2, -3 } },
+ { "-2.5", { -2, -2, -2, -3 } },
+ { "-2.9", { -2, -3, -2, -3 } },
+};
+
+static const char *
+getname(int r)
+{
+ for (size_t i = 0; i < __arraycount(rnd); i++)
+ if (rnd[i].rm == r)
+ return rnd[i].n;
+ return "*unknown*";
+}
+
+static void
+test(int r)
+{
+ int did = 0;
+ for (size_t i = 0; i < __arraycount(tst); i++) {
+ double d = strtod(tst[i].n, NULL);
+ int g = (int)rint(d);
+ int e = tst[i].v[r];
+ ATF_CHECK_EQ(g, e);
+ if (g != e) {
+ if (!did) {
+ fprintf(stderr, "Mode Value Result Expected\n");
+ did = 1;
+ }
+ fprintf(stderr, "%4.4s %-5.5s %6d %8d\n", rnd[r].n,
+ tst[i].n, (int)rint(d), tst[i].v[r]);
+ }
+ }
+}
+#endif
+
+
+ATF_TC_BODY(fpsetround_basic, tc)
+{
+
+#ifndef _FLOAT_IEEE754
+ atf_tc_skip("Test not applicable on this architecture.");
+#else
+ int r;
+
+ ATF_CHECK_EQ(r = fpgetround(), FP_RN);
+ if (FP_RN != r)
+ fprintf(stderr, "default expected=%s got=%s\n", getname(FP_RN),
+ getname(r));
+ ATF_CHECK_EQ(FLT_ROUNDS, 1);
+
+ for (size_t i = 0; i < __arraycount(rnd); i++) {
+ const size_t j = (i + 1) & 3;
+ const int o = rnd[i].rm;
+ const int n = rnd[j].rm;
+
+ ATF_CHECK_EQ(r = fpsetround(n), o);
+ if (o != r)
+ fprintf(stderr, "set %s expected=%s got=%s\n",
+ getname(n), getname(o), getname(r));
+ ATF_CHECK_EQ(r = fpgetround(), n);
+ if (n != r)
+ fprintf(stderr, "get expected=%s got=%s\n", getname(n),
+ getname(r));
+ ATF_CHECK_EQ(r = FLT_ROUNDS, rnd[j].rf);
+ if (r != rnd[j].rf)
+ fprintf(stderr, "rounds expected=%x got=%x\n",
+ rnd[j].rf, r);
+ test(r);
+ }
+#endif /* _FLOAT_IEEE754 */
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fpsetround_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ftok.c b/contrib/netbsd-tests/lib/libc/gen/t_ftok.c
new file mode 100644
index 0000000..100bd1b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_ftok.c
@@ -0,0 +1,107 @@
+/* $NetBSD: t_ftok.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_ftok.c,v 1.1 2011/11/08 05:47:00 jruoho Exp $");
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+
+#include <atf-c.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+static const char *path = "ftok";
+static const char *hlnk = "hlnk";
+static const char *slnk = "slnk";
+static const int key = 123456789;
+
+ATF_TC(ftok_err);
+ATF_TC_HEAD(ftok_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from ftok(3)");
+}
+
+ATF_TC_BODY(ftok_err, tc)
+{
+ ATF_REQUIRE(ftok("/a/b/c/d/e/f/g/h/i", key) == -1);
+}
+
+ATF_TC_WITH_CLEANUP(ftok_link);
+ATF_TC_HEAD(ftok_link, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that links return the same key");
+}
+
+ATF_TC_BODY(ftok_link, tc)
+{
+ key_t k1, k2, k3;
+ int fd;
+
+ fd = open(path, O_RDONLY | O_CREAT);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(link(path, hlnk) == 0);
+ ATF_REQUIRE(symlink(path, slnk) == 0);
+
+ k1 = ftok(path, key);
+ k2 = ftok(hlnk, key);
+ k3 = ftok(slnk, key);
+
+ ATF_REQUIRE(k1 != -1);
+ ATF_REQUIRE(k2 != -1);
+ ATF_REQUIRE(k3 != -1);
+
+ if (k1 != k2)
+ atf_tc_fail("ftok(3) gave different key for a hard link");
+
+ if (k1 != k3)
+ atf_tc_fail("ftok(3) gave different key for a symbolic link");
+
+ ATF_REQUIRE(unlink(path) == 0);
+ ATF_REQUIRE(unlink(hlnk) == 0);
+ ATF_REQUIRE(unlink(slnk) == 0);
+}
+
+ATF_TC_CLEANUP(ftok_link, tc)
+{
+ (void)unlink(path);
+ (void)unlink(hlnk);
+ (void)unlink(slnk);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, ftok_err);
+ ATF_TP_ADD_TC(tp, ftok_link);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c
new file mode 100644
index 0000000..1f39984
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c
@@ -0,0 +1,153 @@
+/* $NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $");
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fts.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+
+ATF_TC(getcwd_err);
+ATF_TC_HEAD(getcwd_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions in getcwd(3)");
+}
+
+ATF_TC_BODY(getcwd_err, tc)
+{
+ char buf[MAXPATHLEN];
+
+ errno = 0;
+
+ ATF_REQUIRE(getcwd(buf, 0) == NULL);
+ ATF_REQUIRE(errno == EINVAL);
+
+#ifdef __NetBSD__
+ errno = 0;
+
+ ATF_REQUIRE(getcwd((void *)-1, sizeof(buf)) == NULL);
+ ATF_REQUIRE(errno == EFAULT);
+#endif
+}
+
+ATF_TC(getcwd_fts);
+ATF_TC_HEAD(getcwd_fts, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of getcwd(3)");
+}
+
+ATF_TC_BODY(getcwd_fts, tc)
+{
+ const char *str = NULL;
+ char buf[MAXPATHLEN];
+ char *argv[2];
+ FTSENT *ftse;
+ FTS *fts;
+ int ops;
+ short depth;
+
+ /*
+ * Do not traverse too deep; cf. PR bin/45180.
+ */
+ depth = 2;
+
+ argv[1] = NULL;
+ argv[0] = __UNCONST("/");
+
+ /*
+ * Test that getcwd(3) works with basic
+ * system directories. Note that having
+ * no FTS_NOCHDIR specified should ensure
+ * that the current directory is visited.
+ */
+ ops = FTS_PHYSICAL | FTS_NOSTAT;
+ fts = fts_open(argv, ops, NULL);
+
+ if (fts == NULL) {
+ str = "failed to initialize fts(3)";
+ goto out;
+ }
+
+ while ((ftse = fts_read(fts)) != NULL) {
+
+ if (ftse->fts_level < 1)
+ continue;
+
+ if (ftse->fts_level > depth) {
+ (void)fts_set(fts, ftse, FTS_SKIP);
+ continue;
+ }
+
+ switch(ftse->fts_info) {
+
+ case FTS_DP:
+
+ (void)memset(buf, 0, sizeof(buf));
+
+ if (getcwd(buf, sizeof(buf)) == NULL) {
+ str = "getcwd(3) failed";
+ goto out;
+ }
+
+ if (strstr(ftse->fts_path, buf) == NULL) {
+ str = "getcwd(3) returned incorrect path";
+ goto out;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+out:
+ if (fts != NULL)
+ (void)fts_close(fts);
+
+ if (str != NULL)
+ atf_tc_fail("%s", str);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getcwd_err);
+ ATF_TP_ADD_TC(tp, getcwd_fts);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c b/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c
new file mode 100644
index 0000000..df9cdd1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c
@@ -0,0 +1,181 @@
+/* $NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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 (c) 2009, Stathis Kamperis
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_getgrent.c,v 1.2 2011/05/11 19:06:45 njoly Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <grp.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+ATF_TC(getgrent_loop);
+ATF_TC_HEAD(getgrent_loop, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sequential getgrent(2)");
+}
+
+ATF_TC_BODY(getgrent_loop, tc)
+{
+ struct group *gr;
+ size_t i, j;
+
+ /*
+ * Loop over the group database. The first
+ * call returns the first entry and subsequent
+ * calls return the rest of the entries.
+ */
+ i = j = 0;
+
+ while((gr = getgrent()) != NULL)
+ i++;
+
+ /*
+ * Rewind the database to the beginning
+ * and loop over again until the end.
+ */
+ setgrent();
+
+ while((gr = getgrent()) != NULL)
+ j++;
+
+ if (i != j)
+ atf_tc_fail("sequential getgrent(3) failed");
+
+ /*
+ * Close the database and reopen it.
+ * The getgrent(3) call should always
+ * automatically rewind the database.
+ */
+ endgrent();
+
+ j = 0;
+
+ while((gr = getgrent()) != NULL)
+ j++;
+
+ if (i != j)
+ atf_tc_fail("getgrent(3) did not rewind");
+}
+
+ATF_TC(getgrent_setgid);
+ATF_TC_HEAD(getgrent_setgid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test consistency of the group db");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(getgrent_setgid, tc)
+{
+ struct group *gr, *gr1, *gr2;
+ int rv, sta;
+ pid_t pid;
+
+ /*
+ * Verify that the database is consistent.
+ *
+ * Note that because of the static buffers
+ * used by getgrent(3), fork(2) is required,
+ * even without the setgid(2) check.
+ */
+ while((gr = getgrent()) != NULL) {
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ gr1 = getgrgid(gr->gr_gid);
+
+ if (gr1 == NULL)
+ _exit(EXIT_FAILURE);
+
+ gr2 = getgrnam(gr->gr_name);
+
+ if (gr2 == NULL)
+ _exit(EXIT_FAILURE);
+
+ rv = setgid(gr->gr_gid);
+
+ if (rv != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ goto fail;
+ }
+
+ return;
+
+fail:
+ atf_tc_fail("group database is inconsistent");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getgrent_loop);
+ ATF_TP_ADD_TC(tp, getgrent_setgid);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_glob.c b/contrib/netbsd-tests/lib/libc/gen/t_glob.c
new file mode 100644
index 0000000..198148c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_glob.c
@@ -0,0 +1,287 @@
+/* $NetBSD: t_glob.c,v 1.3 2013/01/02 11:28:48 martin Exp $ */
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_glob.c,v 1.3 2013/01/02 11:28:48 martin Exp $");
+
+#include <atf-c.h>
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <glob.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef __FreeBSD__
+#include "h_macros.h"
+#define __gl_stat_t struct stat
+#define _S_IFDIR S_IFDIR
+#else
+#include "../../../h_macros.h"
+#endif
+
+
+#ifdef DEBUG
+#define DPRINTF(a) printf a
+#else
+#define DPRINTF(a)
+#endif
+
+struct gl_file {
+ const char *name;
+ int dir;
+};
+
+static struct gl_file a[] = {
+ { "1", 0 },
+ { "b", 1 },
+ { "3", 0 },
+ { "4", 0 },
+};
+
+static struct gl_file b[] = {
+ { "x", 0 },
+ { "y", 0 },
+ { "z", 0 },
+ { "w", 0 },
+};
+
+struct gl_dir {
+ const char *name; /* directory name */
+ const struct gl_file *dir;
+ size_t len, pos;
+};
+
+static struct gl_dir d[] = {
+ { "a", a, __arraycount(a), 0 },
+ { "a/b", b, __arraycount(b), 0 },
+};
+
+static const char *glob_star[] = {
+ "a/1", "a/3", "a/4", "a/b", "a/b/w", "a/b/x", "a/b/y", "a/b/z",
+};
+
+static const char *glob_star_not[] = {
+ "a/1", "a/3", "a/4", "a/b",
+};
+
+static void
+trim(char *buf, size_t len, const char *name)
+{
+ char *path = buf, *epath = buf + len;
+ while (path < epath && (*path++ = *name++) != '\0')
+ continue;
+ path--;
+ while (path > buf && *--path == '/')
+ *path = '\0';
+}
+
+static void *
+gl_opendir(const char *dir)
+{
+ size_t i;
+ char buf[MAXPATHLEN];
+ trim(buf, sizeof(buf), dir);
+
+ for (i = 0; i < __arraycount(d); i++)
+ if (strcmp(buf, d[i].name) == 0) {
+ DPRINTF(("opendir %s %zu\n", buf, i));
+ return &d[i];
+ }
+ errno = ENOENT;
+ return NULL;
+}
+
+static struct dirent *
+gl_readdir(void *v)
+{
+ static struct dirent dir;
+ struct gl_dir *dd = v;
+ if (dd->pos < dd->len) {
+ const struct gl_file *f = &dd->dir[dd->pos++];
+ strcpy(dir.d_name, f->name);
+ dir.d_namlen = strlen(f->name);
+ dir.d_ino = dd->pos;
+ dir.d_type = f->dir ? DT_DIR : DT_REG;
+ DPRINTF(("readdir %s %d\n", dir.d_name, dir.d_type));
+#ifdef __FreeBSD__
+ dir.d_reclen = -1; /* Does not have _DIRENT_RECLEN */
+#else
+ dir.d_reclen = _DIRENT_RECLEN(&dir, dir.d_namlen);
+#endif
+ return &dir;
+ }
+ return NULL;
+}
+
+static int
+gl_stat(const char *name , __gl_stat_t *st)
+{
+ char buf[MAXPATHLEN];
+ trim(buf, sizeof(buf), name);
+ memset(st, 0, sizeof(*st));
+
+ if (strcmp(buf, "a") == 0 || strcmp(buf, "a/b") == 0) {
+ st->st_mode |= _S_IFDIR;
+ return 0;
+ }
+
+ if (buf[0] == 'a' && buf[1] == '/') {
+ struct gl_file *f;
+ size_t offs, count;
+
+ if (buf[2] == 'b' && buf[3] == '/') {
+ offs = 4;
+ count = __arraycount(b);
+ f = b;
+ } else {
+ offs = 2;
+ count = __arraycount(a);
+ f = a;
+ }
+
+ for (size_t i = 0; i < count; i++)
+ if (strcmp(f[i].name, buf + offs) == 0)
+ return 0;
+ }
+ DPRINTF(("stat %s %d\n", buf, st->st_mode));
+ errno = ENOENT;
+ return -1;
+}
+
+static int
+gl_lstat(const char *name , __gl_stat_t *st)
+{
+ return gl_stat(name, st);
+}
+
+static void
+gl_closedir(void *v)
+{
+ struct gl_dir *dd = v;
+ dd->pos = 0;
+ DPRINTF(("closedir %p\n", dd));
+}
+
+static void
+run(const char *p, int flags, const char **res, size_t len)
+{
+ glob_t gl;
+ size_t i;
+
+ memset(&gl, 0, sizeof(gl));
+ gl.gl_opendir = gl_opendir;
+ gl.gl_readdir = gl_readdir;
+ gl.gl_closedir = gl_closedir;
+ gl.gl_stat = gl_stat;
+ gl.gl_lstat = gl_lstat;
+
+ RZ(glob(p, GLOB_ALTDIRFUNC | flags, NULL, &gl));
+
+ for (i = 0; i < gl.gl_pathc; i++)
+ DPRINTF(("%s\n", gl.gl_pathv[i]));
+
+ ATF_CHECK(len == gl.gl_pathc);
+ for (i = 0; i < gl.gl_pathc; i++)
+ ATF_CHECK_STREQ(gl.gl_pathv[i], res[i]);
+
+ globfree(&gl);
+}
+
+
+#ifndef __FreeBSD__
+ATF_TC(glob_star);
+ATF_TC_HEAD(glob_star, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test glob(3) ** with GLOB_STAR");
+}
+
+ATF_TC_BODY(glob_star, tc)
+{
+ run("a/**", GLOB_STAR, glob_star, __arraycount(glob_star));
+}
+#endif
+
+ATF_TC(glob_star_not);
+ATF_TC_HEAD(glob_star_not, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test glob(3) ** without GLOB_STAR");
+}
+
+
+ATF_TC_BODY(glob_star_not, tc)
+{
+ run("a/**", 0, glob_star_not, __arraycount(glob_star_not));
+}
+
+#if 0
+ATF_TC(glob_nocheck);
+ATF_TC_HEAD(glob_nocheck, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test glob(3) pattern with backslash and GLOB_NOCHECK");
+}
+
+
+ATF_TC_BODY(glob_nocheck, tc)
+{
+ static const char pattern[] = { 'f', 'o', 'o', '\\', ';', 'b', 'a',
+ 'r', '\0' };
+ static const char *glob_nocheck[] = {
+ pattern
+ };
+ run(pattern, GLOB_NOCHECK, glob_nocheck, __arraycount(glob_nocheck));
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+#ifndef __FreeBSD__
+ ATF_TP_ADD_TC(tp, glob_star);
+#endif
+ ATF_TP_ADD_TC(tp, glob_star_not);
+/*
+ * Remove this test for now - the GLOB_NOCHECK return value has been
+ * re-defined to return a modified pattern in revision 1.33 of glob.c
+ *
+ * ATF_TP_ADD_TC(tp, glob_nocheck);
+ */
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c
new file mode 100644
index 0000000..5836c86
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c
@@ -0,0 +1,318 @@
+/* $NetBSD: t_humanize_number.c,v 1.8 2012/03/18 07:14:08 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2010, 2011 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 <err.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef __FreeBSD__
+#include <libutil.h>
+#else
+#include <util.h>
+#endif
+
+const struct hnopts {
+ size_t ho_len;
+ int64_t ho_num;
+ const char *ho_suffix;
+ int ho_scale;
+ int ho_flags;
+ int ho_retval; /* expected return value */
+ const char *ho_retstr; /* expected string in buffer */
+} hnopts[] = {
+ /*
+ * Rev. 1.6 produces "10.0".
+ */
+ { 5, 10737418236ULL * 1024, "",
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10T" },
+
+ { 5, 10450000, "",
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" },
+ { 5, 10500000, "", /* just for reference */
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" },
+
+ /*
+ * Trailing space. Rev. 1.7 produces "1 ".
+ */
+ { 5, 1, "", 0, HN_NOSPACE, 1, "1" },
+
+ { 5, 1, "", 0, 0, 2, "1 " }, /* just for reference */
+ { 5, 1, "", 0, HN_B, 3, "1 B" }, /* and more ... */
+ { 5, 1, "", 0, HN_DECIMAL, 2, "1 " },
+ { 5, 1, "", 0, HN_NOSPACE | HN_B, 2, "1B" },
+ { 5, 1, "", 0, HN_B | HN_DECIMAL, 3, "1 B" },
+ { 5, 1, "", 0, HN_NOSPACE | HN_B | HN_DECIMAL, 2, "1B" },
+
+ /*
+ * Space and HN_B. Rev. 1.7 produces "1B".
+ */
+ { 5, 1, "", HN_AUTOSCALE, HN_B, 3, "1 B" },
+ { 5, 1000, "", /* just for reference */
+ HN_AUTOSCALE, HN_B, 3, "1 K" },
+
+ /*
+ * Truncated output. Rev. 1.7 produces "1.0 K".
+ */
+#ifndef __FreeBSD__
+ { 6, 1000, "A", HN_AUTOSCALE, HN_DECIMAL, -1, "" },
+
+ /*
+ * Failure case reported by Greg Troxel <gdt@NetBSD.org>.
+ * Rev. 1.11 incorrectly returns 5 with filling the buffer
+ * with "1000".
+ */
+ { 5, 1048258238, "",
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0G" },
+ /* Similar case it prints 1000 where it shouldn't */
+ { 5, 1023488, "",
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" },
+#endif
+ { 5, 1023999, "",
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" },
+};
+
+struct hnflags {
+ int hf_flags;
+ const char *hf_name;
+};
+
+const struct hnflags scale_flags[] = {
+ { HN_GETSCALE, "HN_GETSCALE" },
+ { HN_AUTOSCALE, "HN_AUTOSCALE" },
+};
+const struct hnflags normal_flags[] = {
+ { HN_DECIMAL, "HN_DECIMAL" },
+ { HN_NOSPACE, "HN_NOSPACE" },
+ { HN_B, "HN_B" },
+ { HN_DIVISOR_1000, "HN_DIVISOR_1000" },
+};
+
+const char *formatflags(char *, size_t, const struct hnflags *, size_t, int);
+void newline(void);
+void w_printf(const char *, ...) __printflike(1, 2);
+int main(int, char *[]);
+
+const char *
+formatflags(char *buf, size_t buflen, const struct hnflags *hfs,
+ size_t hfslen, int flags)
+{
+ const struct hnflags *hf;
+ char *p = buf;
+ ssize_t len = buflen;
+ unsigned int i, found;
+ int n;
+
+ if (flags == 0) {
+ snprintf(buf, buflen, "0");
+ return (buf);
+ }
+ for (i = found = 0; i < hfslen && flags & ~found; i++) {
+ hf = &hfs[i];
+ if (flags & hf->hf_flags) {
+ found |= hf->hf_flags;
+ n = snprintf(p, len, "|%s", hf->hf_name);
+ if (n >= len) {
+ p = buf;
+ len = buflen;
+ /* Print `flags' as number */
+ goto bad;
+ }
+ p += n;
+ len -= n;
+ }
+ }
+ flags &= ~found;
+ if (flags)
+bad:
+ snprintf(p, len, "|0x%x", flags);
+ return (*buf == '|' ? buf + 1 : buf);
+}
+
+static int col, bol = 1;
+void
+newline(void)
+{
+
+ fprintf(stderr, "\n");
+ col = 0;
+ bol = 1;
+}
+
+void
+w_printf(const char *fmt, ...)
+{
+ char buf[80];
+ va_list ap;
+ int n;
+
+ va_start(ap, fmt);
+ if (col >= 0) {
+ n = vsnprintf(buf, sizeof(buf), fmt, ap);
+ if (n >= (int)sizeof(buf)) {
+ col = -1;
+ goto overflow;
+ } else if (n == 0)
+ goto out;
+
+ if (!bol) {
+ if (col + n > 75)
+ fprintf(stderr, "\n "), col = 4;
+ else
+ fprintf(stderr, " "), col++;
+ }
+ fprintf(stderr, "%s", buf);
+ col += n;
+ bol = 0;
+ } else {
+overflow:
+ vfprintf(stderr, fmt, ap);
+ }
+out:
+ va_end(ap);
+}
+
+ATF_TC(humanize_number_basic);
+ATF_TC_HEAD(humanize_number_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test humanize_number(3)");
+}
+
+ATF_TC_BODY(humanize_number_basic, tc)
+{
+ char fbuf[128];
+ const struct hnopts *ho;
+ char *buf = NULL;
+ size_t buflen = 0;
+ unsigned int i;
+ int rv = 0;
+
+ for (i = 0; i < __arraycount(hnopts); i++) {
+ ho = &hnopts[i];
+ if (buflen < ho->ho_len) {
+ buflen = ho->ho_len;
+ buf = realloc(buf, buflen);
+ if (buf == NULL)
+ atf_tc_fail("realloc(..., %zu) failed", buflen);
+ }
+
+ rv = humanize_number(buf, ho->ho_len, ho->ho_num,
+ ho->ho_suffix, ho->ho_scale, ho->ho_flags);
+
+ if (rv == ho->ho_retval &&
+ (rv == -1 || strcmp(buf, ho->ho_retstr) == 0))
+ continue;
+
+ w_printf("humanize_number(\"%s\", %zu, %" PRId64 ",",
+ ho->ho_retstr, ho->ho_len, ho->ho_num);
+ w_printf("\"%s\",", ho->ho_suffix);
+ w_printf("%s,", formatflags(fbuf, sizeof(fbuf), scale_flags,
+ sizeof(scale_flags) / sizeof(scale_flags[0]),
+ ho->ho_scale));
+ w_printf("%s)", formatflags(fbuf, sizeof(fbuf), normal_flags,
+ sizeof(normal_flags) / sizeof(normal_flags[0]),
+ ho->ho_flags));
+ w_printf("= %d,", ho->ho_retval);
+ w_printf("but got");
+ w_printf("%d/[%s]", rv, rv == -1 ? "" : buf);
+ newline();
+ atf_tc_fail_nonfatal("Failed for table entry %d", i);
+ }
+}
+
+ATF_TC(humanize_number_big);
+ATF_TC_HEAD(humanize_number_big, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test humanize "
+ "big numbers (PR lib/44097)");
+}
+
+ATF_TC_BODY(humanize_number_big, tc)
+{
+ char buf[1024];
+ int rv;
+
+ /*
+ * Seems to work.
+ */
+ (void)memset(buf, 0, sizeof(buf));
+
+ rv = humanize_number(buf, 10, 10000, "", HN_AUTOSCALE, HN_NOSPACE);
+
+ ATF_REQUIRE(rv != -1);
+ ATF_CHECK_STREQ(buf, "10000");
+
+ /*
+ * A bogus value with large number.
+ */
+ (void)memset(buf, 0, sizeof(buf));
+
+ rv = humanize_number(buf, 10, INT64_MAX, "", HN_AUTOSCALE, HN_NOSPACE);
+
+ ATF_REQUIRE(rv != -1);
+ ATF_REQUIRE(strcmp(buf, "0") != 0);
+
+ /*
+ * Large buffer with HN_AUTOSCALE. Entirely bogus.
+ */
+ (void)memset(buf, 0, sizeof(buf));
+
+ rv = humanize_number(buf, sizeof(buf), 10000, "",
+ HN_AUTOSCALE, HN_NOSPACE);
+
+ ATF_REQUIRE(rv != -1);
+ ATF_REQUIRE(strcmp(buf, "0%d%s%d%s%s%s") != 0);
+
+ /*
+ * Tight buffer.
+ *
+ * The man page says that len must be at least 4.
+ * 3 works, but anything less that will not. This
+ * is because baselen starts with 2 for positive
+ * numbers.
+ */
+ (void)memset(buf, 0, sizeof(buf));
+
+ rv = humanize_number(buf, 3, 1, "", HN_AUTOSCALE, HN_NOSPACE);
+
+ ATF_REQUIRE(rv != -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, humanize_number_basic);
+ ATF_TP_ADD_TC(tp, humanize_number_big);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_isnan.c b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c
new file mode 100644
index 0000000..2871e31
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c
@@ -0,0 +1,66 @@
+/* $NetBSD: t_isnan.c,v 1.5 2014/11/04 00:20:19 justin Exp $ */
+
+/*
+ * This file is in the Public Domain.
+ *
+ * The nan test is blatently copied by Simon Burge from the infinity
+ * test by Ben Harris.
+ */
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+
+#include <math.h>
+#include <string.h>
+
+ATF_TC(isnan_basic);
+ATF_TC_HEAD(isnan_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Verify that isnan(3) works");
+}
+
+ATF_TC_BODY(isnan_basic, tc)
+{
+#if defined(__m68k__)
+ atf_tc_skip("Test not applicable on " MACHINE_ARCH);
+#endif
+
+#ifdef NAN
+ /* NAN is meant to be a (float)NaN. */
+ ATF_CHECK(isnan(NAN) != 0);
+ ATF_CHECK(isnan((double)NAN) != 0);
+#else
+ atf_tc_skip("Test not applicable");
+#endif
+}
+
+ATF_TC(isinf_basic);
+ATF_TC_HEAD(isinf_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Verify that isinf(3) works");
+}
+
+ATF_TC_BODY(isinf_basic, tc)
+{
+#if defined(__m68k__)
+ atf_tc_skip("Test not applicable on " MACHINE_ARCH);
+#endif
+
+ /* HUGE_VAL is meant to be an infinity. */
+ ATF_CHECK(isinf(HUGE_VAL) != 0);
+
+ /* HUGE_VALF is the float analog of HUGE_VAL. */
+ ATF_CHECK(isinf(HUGE_VALF) != 0);
+
+ /* HUGE_VALL is the long double analog of HUGE_VAL. */
+ ATF_CHECK(isinf(HUGE_VALL) != 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, isnan_basic);
+ ATF_TP_ADD_TC(tp, isinf_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_nice.c b/contrib/netbsd-tests/lib/libc/gen/t_nice.c
new file mode 100644
index 0000000..10b8df7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_nice.c
@@ -0,0 +1,221 @@
+/* $NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $");
+
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static void *threadfunc(void *);
+
+static void *
+threadfunc(void *arg)
+{
+ int pri, val;
+
+ val = *(int *)arg;
+
+ errno = 0;
+ pri = getpriority(PRIO_PROCESS, 0);
+ ATF_REQUIRE(errno == 0);
+
+ if (pri != val)
+ atf_tc_fail("nice(3) value was not propagated to threads");
+
+ return NULL;
+}
+
+ATF_TC(nice_err);
+ATF_TC_HEAD(nice_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test nice(3) for invalid parameters (PR lib/42587)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(nice_err, tc)
+{
+ int i;
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("nice(incr) with incr < 0 fails with unprivileged "
+ "users and sets errno == EPERM; see PR # 189821 for more details");
+#endif
+
+ /*
+ * The call should fail with EPERM if the
+ * supplied parameter is negative and the
+ * caller does not have privileges.
+ */
+ for (i = -20; i < 0; i++) {
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EPERM, nice(i) == -1);
+ }
+}
+
+ATF_TC(nice_priority);
+ATF_TC_HEAD(nice_priority, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test nice(3) vs. getpriority(2)");
+}
+
+ATF_TC_BODY(nice_priority, tc)
+{
+#ifdef __FreeBSD__
+ int i, pri, pri2, nic;
+#else
+ int i, pri, nic;
+#endif
+ pid_t pid;
+ int sta;
+
+ for (i = 0; i <= 20; i++) {
+
+ nic = nice(i);
+ ATF_REQUIRE(nic != -1);
+
+ errno = 0;
+ pri = getpriority(PRIO_PROCESS, 0);
+ ATF_REQUIRE(errno == 0);
+
+#ifdef __NetBSD__
+ if (nic != pri)
+ atf_tc_fail("nice(3) and getpriority(2) conflict");
+#endif
+
+ /*
+ * Also verify that the nice(3) values
+ * are inherited by child processes.
+ */
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ errno = 0;
+#ifdef __FreeBSD__
+ pri = getpriority(PRIO_PROCESS, 0);
+#else
+ pri2 = getpriority(PRIO_PROCESS, 0);
+#endif
+ ATF_REQUIRE(errno == 0);
+
+#ifdef __FreeBSD__
+ if (pri != pri2)
+#else
+ if (nic != pri)
+#endif
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("nice(3) value was not inherited");
+ }
+}
+
+ATF_TC(nice_root);
+ATF_TC_HEAD(nice_root, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that nice(3) works");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(nice_root, tc)
+{
+ int i;
+
+ for (i = -20; i <= 20; i++) {
+
+ ATF_REQUIRE(nice(i) != -1);
+ }
+}
+
+ATF_TC(nice_thread);
+ATF_TC_HEAD(nice_thread, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test nice(3) with threads");
+}
+
+ATF_TC_BODY(nice_thread, tc)
+{
+ pthread_t tid[5];
+#ifdef __FreeBSD__
+ int pri, rv, val;
+#else
+ int rv, val;
+#endif
+ size_t i;
+
+ /*
+ * Test that the scheduling priority is
+ * propagated to all system scope threads.
+ */
+ for (i = 0; i < __arraycount(tid); i++) {
+
+ val = nice(i);
+ ATF_REQUIRE(val != -1);
+
+#ifdef __FreeBSD__
+ pri = getpriority(PRIO_PROCESS, 0);
+ rv = pthread_create(&tid[i], NULL, threadfunc, &pri);
+#else
+ rv = pthread_create(&tid[i], NULL, threadfunc, &val);
+#endif
+ ATF_REQUIRE(rv == 0);
+
+ rv = pthread_join(tid[i], NULL);
+ ATF_REQUIRE(rv == 0);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, nice_err);
+ ATF_TP_ADD_TC(tp, nice_priority);
+ ATF_TP_ADD_TC(tp, nice_root);
+ ATF_TP_ADD_TC(tp, nice_thread);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_pause.c b/contrib/netbsd-tests/lib/libc/gen/t_pause.c
new file mode 100644
index 0000000..62a74c9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_pause.c
@@ -0,0 +1,114 @@
+/* $NetBSD: t_pause.c,v 1.1 2011/05/10 13:03:06 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_pause.c,v 1.1 2011/05/10 13:03:06 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+
+static bool fail;
+static void handler(int);
+
+static void
+handler(int signo)
+{
+
+ if (signo == SIGALRM)
+ fail = false;
+}
+
+ATF_TC(pause_basic);
+ATF_TC_HEAD(pause_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of pause(3), #1");
+}
+
+ATF_TC_BODY(pause_basic, tc)
+{
+
+ fail = true;
+
+ ATF_REQUIRE(signal(SIGALRM, handler) == 0);
+
+ (void)alarm(1);
+
+ if (pause() != -1 || fail != false)
+ atf_tc_fail("pause(3) did not cancel out from a signal");
+}
+
+ATF_TC(pause_kill);
+ATF_TC_HEAD(pause_kill, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of pause(3), #2");
+}
+
+ATF_TC_BODY(pause_kill, tc)
+{
+ pid_t pid;
+ int sta;
+
+ fail = true;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ (void)pause();
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)sleep(1);
+
+ if (fail != true)
+ atf_tc_fail("child terminated before signal");
+
+ (void)kill(pid, SIGKILL);
+ (void)sleep(1);
+ (void)wait(&sta);
+
+ if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL)
+ atf_tc_fail("pause(3) did not cancel from SIGKILL");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, pause_basic);
+ ATF_TP_ADD_TC(tp, pause_kill);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_raise.c b/contrib/netbsd-tests/lib/libc/gen/t_raise.c
new file mode 100644
index 0000000..d6f888f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_raise.c
@@ -0,0 +1,194 @@
+/* $NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $");
+
+#include <atf-c.h>
+
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+static bool fail;
+static int count;
+static void handler_err(int);
+static void handler_ret(int);
+static void handler_stress(int);
+#ifdef __FreeBSD__
+static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2 };
+#else
+static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2, SIGPWR };
+#endif
+
+static void
+handler_stress(int signo)
+{
+ count++;
+}
+
+static void
+handler_err(int signo)
+{
+ size_t i;
+
+ for (i = 0; i < __arraycount(sig); i++) {
+
+ if (sig[i] == signo) {
+ fail = false;
+ break;
+ }
+ }
+}
+
+static void
+handler_ret(int signo)
+{
+
+ (void)sleep(1);
+
+ fail = false;
+}
+
+ATF_TC(raise_err);
+ATF_TC_HEAD(raise_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test raise(3) for invalid parameters");
+}
+
+ATF_TC_BODY(raise_err, tc)
+{
+ int i = 0;
+
+ while (i < 10) {
+
+ ATF_REQUIRE(raise(10240 + i) == -1);
+
+ i++;
+ }
+}
+
+ATF_TC(raise_ret);
+ATF_TC_HEAD(raise_ret, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test return order of raise(3)");
+}
+
+ATF_TC_BODY(raise_ret, tc)
+{
+ struct sigaction sa;
+
+ fail = true;
+
+ sa.sa_flags = 0;
+ sa.sa_handler = handler_ret;
+
+ /*
+ * Verify that raise(3) does not return
+ * before the signal handler returns.
+ */
+ ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
+ ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0);
+ ATF_REQUIRE(raise(SIGUSR1) == 0);
+
+ if (fail != false)
+ atf_tc_fail("raise(3) returned before signal handler");
+}
+
+ATF_TC(raise_sig);
+ATF_TC_HEAD(raise_sig, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of raise(3)");
+}
+
+ATF_TC_BODY(raise_sig, tc)
+{
+ struct timespec tv, tr;
+ struct sigaction sa;
+ size_t i;
+
+ for (i = 0; i < __arraycount(sig); i++) {
+
+ (void)memset(&sa, 0, sizeof(struct sigaction));
+
+ fail = true;
+
+ tv.tv_sec = 0;
+ tv.tv_nsec = 2;
+
+ sa.sa_flags = 0;
+ sa.sa_handler = handler_err;
+
+ ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
+ ATF_REQUIRE(sigaction(sig[i], &sa, 0) == 0);
+
+ ATF_REQUIRE(raise(sig[i]) == 0);
+ ATF_REQUIRE(nanosleep(&tv, &tr) == 0);
+
+ if (fail != false)
+ atf_tc_fail("raise(3) did not raise a signal");
+ }
+}
+
+ATF_TC(raise_stress);
+ATF_TC_HEAD(raise_stress, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic stress test with raise(3)");
+}
+
+ATF_TC_BODY(raise_stress, tc)
+{
+ static const int maxiter = 1000 * 10;
+ struct sigaction sa;
+ int i;
+
+ sa.sa_flags = 0;
+ sa.sa_handler = handler_stress;
+
+ ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
+ ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0);
+
+ for (count = i = 0; i < maxiter; i++)
+ (void)raise(SIGUSR1);
+
+ if (count != maxiter)
+ atf_tc_fail("not all signals were catched");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, raise_err);
+ ATF_TP_ADD_TC(tp, raise_ret);
+ ATF_TP_ADD_TC(tp, raise_sig);
+ ATF_TP_ADD_TC(tp, raise_stress);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_randomid.c b/contrib/netbsd-tests/lib/libc/gen/t_randomid.c
new file mode 100644
index 0000000..8377806
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_randomid.c
@@ -0,0 +1,93 @@
+/* $NetBSD: t_randomid.c,v 1.3 2011/07/07 09:49:59 jruoho Exp $ */
+
+/*-
+ * 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.h>
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <inttypes.h>
+#include <randomid.h>
+#include <stdio.h>
+#include <string.h>
+
+#define PERIOD 30000
+
+uint64_t last[65536];
+
+ATF_TC(randomid_basic);
+ATF_TC_HEAD(randomid_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Check randomid(3)");
+}
+
+ATF_TC_BODY(randomid_basic, tc)
+{
+ static randomid_t ctx = NULL;
+ uint64_t lowest, n, diff;
+ uint16_t id;
+
+ memset(last, 0, sizeof(last));
+ ctx = randomid_new(16, (long)3600);
+
+ lowest = UINT64_MAX;
+
+ for (n = 0; n < 1000000; n++) {
+ id = randomid(ctx);
+
+ if (last[id] > 0) {
+ diff = n - last[id];
+
+ if (diff <= lowest) {
+ if (lowest != UINT64_MAX)
+ printf("id %5d: last call at %9"PRIu64
+ ", current call %9"PRIu64
+ " (diff %5"PRIu64"), "
+ "lowest %"PRIu64"\n",
+ id, last[id], n, diff, lowest);
+
+ ATF_REQUIRE_MSG(diff >= PERIOD,
+ "diff (%"PRIu64") less than minimum "
+ "period (%d)", diff, PERIOD);
+
+ lowest = diff;
+ }
+ }
+
+ last[id] = n;
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, randomid_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_realpath.c b/contrib/netbsd-tests/lib/libc/gen/t_realpath.c
new file mode 100644
index 0000000..d4998c7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_realpath.c
@@ -0,0 +1,152 @@
+/* $NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_realpath.c,v 1.2 2012/03/27 07:54:58 njoly Exp $");
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static const struct {
+ const char *path;
+ const char *result;
+} paths[] = {
+
+ { "/", "/" },
+ { "///////", "/" },
+ { "", NULL },
+ { " ", NULL },
+ { "/ ", NULL },
+ { " /", NULL },
+ { "/etc///", "/etc" },
+ { "///////etc", "/etc" },
+ { "/a/b/c/d/e", NULL },
+ { " /usr/bin ", NULL },
+ { "\\//////usr//bin", NULL },
+ { "//usr//bin//", "/usr/bin" },
+ { "//////usr//bin//", "/usr/bin" },
+ { "/usr/bin//////////", "/usr/bin" },
+};
+
+ATF_TC(realpath_basic);
+ATF_TC_HEAD(realpath_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of realpath(3)");
+}
+
+ATF_TC_BODY(realpath_basic, tc)
+{
+ char buf[MAXPATHLEN];
+ char *ptr;
+ size_t i;
+
+ for (i = 0; i < __arraycount(paths); i++) {
+
+ (void)memset(buf, '\0', sizeof(buf));
+
+ ptr = realpath(paths[i].path, buf);
+
+ if (ptr == NULL && paths[i].result == NULL)
+ continue;
+
+ if (ptr == NULL && paths[i].result != NULL)
+ atf_tc_fail("realpath failed for '%s'", paths[i].path);
+
+ if (strcmp(paths[i].result, buf) != 0)
+ atf_tc_fail("expected '%s', got '%s'",
+ paths[i].result, buf);
+ }
+}
+
+ATF_TC(realpath_huge);
+ATF_TC_HEAD(realpath_huge, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test huge path with realpath(3)");
+}
+
+ATF_TC_BODY(realpath_huge, tc)
+{
+ char result[MAXPATHLEN] = { 0 };
+ char buffer[MAXPATHLEN] = { 0 };
+
+ (void)memset(buffer, '/', sizeof(buffer) - 1);
+
+ ATF_CHECK(realpath(buffer, result) != NULL);
+ ATF_CHECK(strlen(result) == 1);
+ ATF_CHECK(result[0] == '/');
+}
+
+ATF_TC(realpath_symlink);
+ATF_TC_HEAD(realpath_symlink, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test symbolic link with realpath(3)");
+}
+
+ATF_TC_BODY(realpath_symlink, tc)
+{
+ char path[MAXPATHLEN] = { 0 };
+ char slnk[MAXPATHLEN] = { 0 };
+ char resb[MAXPATHLEN] = { 0 };
+ int fd;
+
+ (void)getcwd(path, sizeof(path));
+ (void)getcwd(slnk, sizeof(slnk));
+
+ (void)strlcat(path, "/realpath", sizeof(path));
+ (void)strlcat(slnk, "/symbolic", sizeof(slnk));
+
+ fd = open(path, O_RDONLY | O_CREAT, 0600);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(symlink(path, slnk) == 0);
+ ATF_REQUIRE(close(fd) == 0);
+
+ ATF_REQUIRE(realpath(slnk, resb) != NULL);
+ ATF_REQUIRE(strcmp(resb, path) == 0);
+
+ ATF_REQUIRE(unlink(path) == 0);
+ ATF_REQUIRE(unlink(slnk) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, realpath_basic);
+ ATF_TP_ADD_TC(tp, realpath_huge);
+ ATF_TP_ADD_TC(tp, realpath_symlink);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c
new file mode 100644
index 0000000..f51eb2a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c
@@ -0,0 +1,148 @@
+/* $NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $");
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+static char domain[MAXHOSTNAMELEN];
+
+static const char domains[][MAXHOSTNAMELEN] = {
+ "1234567890",
+ "abcdefghijklmnopqrst",
+ "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8",
+ "--------------------------------------------------------------------"
+};
+
+ATF_TC_WITH_CLEANUP(setdomainname_basic);
+ATF_TC_HEAD(setdomainname_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of setdomainname(3)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(setdomainname_basic, tc)
+{
+ char name[MAXHOSTNAMELEN];
+ size_t i;
+
+ for (i = 0; i < __arraycount(domains); i++) {
+
+ (void)memset(name, 0, sizeof(name));
+
+#ifdef __FreeBSD__
+ /*
+ * Sanity checks to ensure that the wrong invariant isn't being
+ * tested for per PR # 181127
+ */
+ ATF_REQUIRE_EQ(sizeof(domains[i]), MAXHOSTNAMELEN);
+ ATF_REQUIRE_EQ(sizeof(name), MAXHOSTNAMELEN);
+
+ ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i]) - 1) == 0);
+ ATF_REQUIRE(getdomainname(name, sizeof(name) - 1) == 0);
+#else
+ ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i])) == 0);
+ ATF_REQUIRE(getdomainname(name, sizeof(name)) == 0);
+#endif
+ ATF_REQUIRE(strcmp(domains[i], name) == 0);
+ }
+
+ (void)setdomainname(domain, sizeof(domain));
+}
+
+ATF_TC_CLEANUP(setdomainname_basic, tc)
+{
+ (void)setdomainname(domain, sizeof(domain));
+}
+
+ATF_TC_WITH_CLEANUP(setdomainname_limit);
+ATF_TC_HEAD(setdomainname_limit, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Too long domain name errors out?");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(setdomainname_limit, tc)
+{
+ char name[MAXHOSTNAMELEN + 1];
+
+ (void)memset(name, 0, sizeof(name));
+
+#ifdef __FreeBSD__
+ ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN - 1 ) == 0);
+ ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN) == -1);
+#endif
+ ATF_REQUIRE(setdomainname(name, sizeof(name)) == -1);
+}
+
+ATF_TC_CLEANUP(setdomainname_limit, tc)
+{
+ (void)setdomainname(domain, sizeof(domain));
+}
+
+ATF_TC_WITH_CLEANUP(setdomainname_perm);
+ATF_TC_HEAD(setdomainname_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Can normal user set the domain name?");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(setdomainname_perm, tc)
+{
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EPERM, setdomainname(domain, sizeof(domain)) == -1);
+}
+
+ATF_TC_CLEANUP(setdomainname_perm, tc)
+{
+ (void)setdomainname(domain, sizeof(domain));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ (void)memset(domain, 0, sizeof(domain));
+
+ ATF_REQUIRE(getdomainname(domain, sizeof(domain)) == 0);
+
+ ATF_TP_ADD_TC(tp, setdomainname_basic);
+ ATF_TP_ADD_TC(tp, setdomainname_limit);
+ ATF_TP_ADD_TC(tp, setdomainname_perm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c
new file mode 100644
index 0000000..1972f7d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c
@@ -0,0 +1,150 @@
+/* $NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $");
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+static char host[MAXHOSTNAMELEN];
+
+static const char hosts[][MAXHOSTNAMELEN] = {
+ "1234567890",
+ "abcdefghijklmnopqrst",
+ "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8",
+ "--------------------------------------------------------------------"
+};
+
+ATF_TC_WITH_CLEANUP(sethostname_basic);
+ATF_TC_HEAD(sethostname_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of sethostname(3)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(sethostname_basic, tc)
+{
+ char name[MAXHOSTNAMELEN];
+ size_t i;
+
+ atf_tc_skip("screws up the test host's hostname on FreeBSD");
+
+ for (i = 0; i < __arraycount(hosts); i++) {
+
+ (void)memset(name, 0, sizeof(name));
+
+#ifdef __FreeBSD__
+ /*
+ * Sanity checks to ensure that the wrong invariant isn't being
+ * tested for per PR # 181127
+ */
+ ATF_REQUIRE_EQ(sizeof(hosts[i]), MAXHOSTNAMELEN);
+ ATF_REQUIRE_EQ(sizeof(name), MAXHOSTNAMELEN);
+
+ ATF_REQUIRE(sethostname(hosts[i], sizeof(hosts[i]) - 1) == 0);
+ ATF_REQUIRE(gethostname(name, sizeof(name) - 1) == 0);
+#else
+ ATF_REQUIRE(sethostname(hosts[i], sizeof(hosts[i])) == 0);
+ ATF_REQUIRE(gethostname(name, sizeof(name)) == 0);
+#endif
+ ATF_REQUIRE(strcmp(hosts[i], name) == 0);
+ }
+
+ (void)sethostname(host, sizeof(host));
+}
+
+ATF_TC_CLEANUP(sethostname_basic, tc)
+{
+ (void)sethostname(host, sizeof(host));
+}
+
+ATF_TC_WITH_CLEANUP(sethostname_limit);
+ATF_TC_HEAD(sethostname_limit, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Too long host name errors out?");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(sethostname_limit, tc)
+{
+ char name[MAXHOSTNAMELEN + 1];
+
+ (void)memset(name, 0, sizeof(name));
+
+ ATF_REQUIRE(sethostname(name, sizeof(name)) == -1);
+}
+
+ATF_TC_CLEANUP(sethostname_limit, tc)
+{
+#ifdef __FreeBSD__
+ ATF_REQUIRE(sethostname(host, MAXHOSTNAMELEN - 1 ) == 0);
+ ATF_REQUIRE(sethostname(host, MAXHOSTNAMELEN) == -1);
+#endif
+ (void)sethostname(host, sizeof(host));
+}
+
+ATF_TC_WITH_CLEANUP(sethostname_perm);
+ATF_TC_HEAD(sethostname_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Can normal user set the host name?");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(sethostname_perm, tc)
+{
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EPERM, sethostname(host, sizeof(host)) == -1);
+}
+
+ATF_TC_CLEANUP(sethostname_perm, tc)
+{
+ (void)sethostname(host, sizeof(host));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ (void)memset(host, 0, sizeof(host));
+
+ ATF_REQUIRE(gethostname(host, sizeof(host)) == 0);
+
+ ATF_TP_ADD_TC(tp, sethostname_basic);
+ ATF_TP_ADD_TC(tp, sethostname_limit);
+ ATF_TP_ADD_TC(tp, sethostname_perm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c
new file mode 100644
index 0000000..9c9a3c7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c
@@ -0,0 +1,505 @@
+/* $NetBSD: t_siginfo.c,v 1.24 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * 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.h>
+
+#ifdef __NetBSD__
+#include <sys/inttypes.h>
+#endif
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/ucontext.h>
+#include <sys/wait.h>
+
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <setjmp.h>
+#include <float.h>
+
+#ifdef HAVE_FENV
+#include <fenv.h>
+#elif defined(_FLOAT_IEEE754)
+#include <ieeefp.h>
+#endif
+
+#include "isqemu.h"
+
+/* for sigbus */
+volatile char *addr;
+
+/* for sigchild */
+pid_t child;
+int code;
+int status;
+
+/* for sigfpe */
+sig_atomic_t fltdiv_signalled = 0;
+sig_atomic_t intdiv_signalled = 0;
+
+static void
+sig_debug(int signo, siginfo_t *info, ucontext_t *ctx)
+{
+ unsigned int i;
+
+ printf("%d %p %p\n", signo, info, ctx);
+ if (info != NULL) {
+ printf("si_signo=%d\n", info->si_signo);
+ printf("si_errno=%d\n", info->si_errno);
+ printf("si_code=%d\n", info->si_code);
+ printf("si_value.sival_int=%d\n", info->si_value.sival_int);
+ }
+ if (ctx != NULL) {
+ printf("uc_flags 0x%x\n", ctx->uc_flags);
+ printf("uc_link %p\n", ctx->uc_link);
+ for (i = 0; i < __arraycount(ctx->uc_sigmask.__bits); i++)
+ printf("uc_sigmask[%d] 0x%x\n", i,
+ ctx->uc_sigmask.__bits[i]);
+ printf("uc_stack %p %lu 0x%x\n", ctx->uc_stack.ss_sp,
+ (unsigned long)ctx->uc_stack.ss_size,
+ ctx->uc_stack.ss_flags);
+#ifdef __NetBSD__
+ for (i = 0; i < __arraycount(ctx->uc_mcontext.__gregs); i++)
+ printf("uc_mcontext.greg[%d] 0x%lx\n", i,
+ (long)ctx->uc_mcontext.__gregs[i]);
+#endif
+ }
+}
+
+static void
+sigalrm_action(int signo, siginfo_t *info, void *ptr)
+{
+
+ sig_debug(signo, info, (ucontext_t *)ptr);
+
+ ATF_REQUIRE_EQ(info->si_signo, SIGALRM);
+ ATF_REQUIRE_EQ(info->si_code, SI_TIMER);
+ ATF_REQUIRE_EQ(info->si_value.sival_int, ITIMER_REAL);
+
+ atf_tc_pass();
+ /* NOTREACHED */
+}
+
+ATF_TC(sigalarm);
+
+ATF_TC_HEAD(sigalarm, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGALRM handler");
+}
+
+ATF_TC_BODY(sigalarm, tc)
+{
+ struct sigaction sa;
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = sigalrm_action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGALRM, &sa, NULL);
+ for (;;) {
+ alarm(1);
+ sleep(1);
+ }
+ atf_tc_fail("SIGALRM handler wasn't called");
+}
+
+static void
+sigchild_action(int signo, siginfo_t *info, void *ptr)
+{
+ if (info != NULL) {
+ printf("info=%p\n", info);
+ printf("ptr=%p\n", ptr);
+ printf("si_signo=%d\n", info->si_signo);
+ printf("si_errno=%d\n", info->si_errno);
+ printf("si_code=%d\n", info->si_code);
+ printf("si_uid=%d\n", info->si_uid);
+ printf("si_pid=%d\n", info->si_pid);
+ printf("si_status=%d\n", info->si_status);
+#ifdef __NetBSD__
+ printf("si_utime=%lu\n", (unsigned long int)info->si_utime);
+ printf("si_stime=%lu\n", (unsigned long int)info->si_stime);
+#endif
+ }
+ ATF_REQUIRE_EQ(info->si_code, code);
+ ATF_REQUIRE_EQ(info->si_signo, SIGCHLD);
+ ATF_REQUIRE_EQ(info->si_uid, getuid());
+ ATF_REQUIRE_EQ(info->si_pid, child);
+ if (WIFEXITED(info->si_status))
+ ATF_REQUIRE_EQ(WEXITSTATUS(info->si_status), status);
+ else if (WIFSTOPPED(info->si_status))
+ ATF_REQUIRE_EQ(WSTOPSIG(info->si_status), status);
+ else if (WIFSIGNALED(info->si_status))
+ ATF_REQUIRE_EQ(WTERMSIG(info->si_status), status);
+}
+
+static void
+setchildhandler(void (*action)(int, siginfo_t *, void *))
+{
+ struct sigaction sa;
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGCHLD, &sa, NULL);
+}
+
+static void
+sigchild_setup(void)
+{
+ sigset_t set;
+ struct rlimit rlim;
+
+ (void)getrlimit(RLIMIT_CORE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max;
+ (void)setrlimit(RLIMIT_CORE, &rlim);
+
+ setchildhandler(sigchild_action);
+ sigemptyset(&set);
+ sigaddset(&set, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &set, NULL);
+}
+
+ATF_TC(sigchild_normal);
+ATF_TC_HEAD(sigchild_normal, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGCHLD handler "
+ "when child exits normally");
+}
+
+ATF_TC_BODY(sigchild_normal, tc)
+{
+ sigset_t set;
+
+ sigchild_setup();
+
+ status = 25;
+ code = CLD_EXITED;
+
+ switch ((child = fork())) {
+ case 0:
+ sleep(1);
+ exit(status);
+ case -1:
+ atf_tc_fail("fork failed");
+ default:
+ sigemptyset(&set);
+ sigsuspend(&set);
+ }
+}
+
+ATF_TC(sigchild_dump);
+ATF_TC_HEAD(sigchild_dump, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGCHLD handler "
+ "when child segfaults");
+}
+
+ATF_TC_BODY(sigchild_dump, tc)
+{
+ sigset_t set;
+
+ sigchild_setup();
+
+ status = SIGSEGV;
+ code = CLD_DUMPED;
+
+ switch ((child = fork())) {
+ case 0:
+ sleep(1);
+ *(volatile long *)0 = 0;
+ atf_tc_fail("Child did not segfault");
+ /* NOTREACHED */
+ case -1:
+ atf_tc_fail("fork failed");
+ default:
+ sigemptyset(&set);
+ sigsuspend(&set);
+ }
+}
+
+ATF_TC(sigchild_kill);
+ATF_TC_HEAD(sigchild_kill, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGCHLD handler "
+ "when child is killed");
+}
+
+ATF_TC_BODY(sigchild_kill, tc)
+{
+ sigset_t set;
+
+ sigchild_setup();
+
+ status = SIGPIPE;
+ code = CLD_KILLED;
+
+ switch ((child = fork())) {
+ case 0:
+ sigemptyset(&set);
+ sigsuspend(&set);
+ break;
+ case -1:
+ atf_tc_fail("fork failed");
+ default:
+ kill(child, SIGPIPE);
+ sigemptyset(&set);
+ sigsuspend(&set);
+ }
+}
+
+static sigjmp_buf sigfpe_flt_env;
+static void
+sigfpe_flt_action(int signo, siginfo_t *info, void *ptr)
+{
+
+ sig_debug(signo, info, (ucontext_t *)ptr);
+
+ if (fltdiv_signalled++ != 0)
+ atf_tc_fail("FPE handler called more than once");
+
+ ATF_REQUIRE_EQ(info->si_signo, SIGFPE);
+ ATF_REQUIRE_EQ(info->si_code, FPE_FLTDIV);
+ ATF_REQUIRE_EQ(info->si_errno, 0);
+
+ siglongjmp(sigfpe_flt_env, 1);
+}
+
+ATF_TC(sigfpe_flt);
+ATF_TC_HEAD(sigfpe_flt, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGFPE handler "
+ "for floating div-by-zero");
+}
+
+ATF_TC_BODY(sigfpe_flt, tc)
+{
+ struct sigaction sa;
+ double d = strtod("0", NULL);
+
+ if (isQEMU())
+ atf_tc_skip("Test does not run correctly under QEMU");
+#if defined(__powerpc__)
+ atf_tc_skip("Test not valid on powerpc");
+#endif
+ if (sigsetjmp(sigfpe_flt_env, 0) == 0) {
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = sigfpe_flt_action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGFPE, &sa, NULL);
+#ifdef HAVE_FENV
+ feenableexcept(FE_ALL_EXCEPT);
+#elif defined(_FLOAT_IEEE754)
+ fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP);
+#endif
+ printf("%g\n", 1 / d);
+ }
+ if (fltdiv_signalled == 0)
+ atf_tc_fail("FPE signal handler was not invoked");
+}
+
+static sigjmp_buf sigfpe_int_env;
+static void
+sigfpe_int_action(int signo, siginfo_t *info, void *ptr)
+{
+
+ sig_debug(signo, info, (ucontext_t *)ptr);
+
+ if (intdiv_signalled++ != 0)
+ atf_tc_fail("INTDIV handler called more than once");
+
+ ATF_REQUIRE_EQ(info->si_signo, SIGFPE);
+ ATF_REQUIRE_EQ(info->si_code, FPE_INTDIV);
+ atf_tc_expect_pass();
+ ATF_REQUIRE_EQ(info->si_errno, 0);
+
+ siglongjmp(sigfpe_int_env, 1);
+}
+
+ATF_TC(sigfpe_int);
+ATF_TC_HEAD(sigfpe_int, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGFPE handler "
+ "for integer div-by-zero (PR port-i386/43655)");
+}
+
+ATF_TC_BODY(sigfpe_int, tc)
+{
+ struct sigaction sa;
+ long l = strtol("0", NULL, 10);
+
+#if defined(__powerpc__)
+ atf_tc_skip("Test not valid on powerpc");
+#endif
+ if (sigsetjmp(sigfpe_int_env, 0) == 0) {
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = sigfpe_int_action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGFPE, &sa, NULL);
+#ifdef HAVE_FENV
+ feenableexcept(FE_ALL_EXCEPT);
+#elif defined(_FLOAT_IEEE754)
+ fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP);
+#endif
+ printf("%ld\n", 1 / l);
+ }
+ if (intdiv_signalled == 0)
+ atf_tc_fail("FPE signal handler was not invoked");
+}
+
+static void
+sigsegv_action(int signo, siginfo_t *info, void *ptr)
+{
+
+ sig_debug(signo, info, (ucontext_t *)ptr);
+
+ ATF_REQUIRE_EQ(info->si_signo, SIGSEGV);
+ ATF_REQUIRE_EQ(info->si_errno, 0);
+ ATF_REQUIRE_EQ(info->si_code, SEGV_MAPERR);
+ ATF_REQUIRE_EQ(info->si_addr, (void *)0);
+
+ atf_tc_pass();
+ /* NOTREACHED */
+}
+
+ATF_TC(sigsegv);
+ATF_TC_HEAD(sigsegv, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGSEGV handler");
+}
+
+ATF_TC_BODY(sigsegv, tc)
+{
+ struct sigaction sa;
+
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = sigsegv_action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGSEGV, &sa, NULL);
+
+ *(volatile long *)0 = 0;
+ atf_tc_fail("Test did not fault as expected");
+}
+
+static void
+sigbus_action(int signo, siginfo_t *info, void *ptr)
+{
+
+ printf("si_addr = %p\n", info->si_addr);
+ sig_debug(signo, info, (ucontext_t *)ptr);
+
+ ATF_REQUIRE_EQ(info->si_signo, SIGBUS);
+ ATF_REQUIRE_EQ(info->si_errno, 0);
+ ATF_REQUIRE_EQ(info->si_code, BUS_ADRALN);
+
+#if defined(__i386__) || defined(__x86_64__)
+ atf_tc_expect_fail("x86 architecture does not correctly "
+ "report the address where the unaligned access occured");
+#endif
+ ATF_REQUIRE_EQ(info->si_addr, (volatile void *)addr);
+
+ atf_tc_pass();
+ /* NOTREACHED */
+}
+
+ATF_TC(sigbus_adraln);
+ATF_TC_HEAD(sigbus_adraln, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGBUS handler "
+ "for invalid address alignment");
+}
+
+ATF_TC_BODY(sigbus_adraln, tc)
+{
+ struct sigaction sa;
+
+#if defined(__alpha__)
+ int rv, val;
+ size_t len = sizeof(val);
+ rv = sysctlbyname("machdep.unaligned_sigbus", &val, &len, NULL, 0);
+ ATF_REQUIRE(rv == 0);
+ if (val == 0)
+ atf_tc_skip("SIGBUS signal not enabled for unaligned accesses");
+#endif
+
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = sigbus_action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGBUS, &sa, NULL);
+
+ /* Enable alignment checks for x86. 0x40000 is PSL_AC. */
+#if defined(__i386__)
+ __asm__("pushf; orl $0x40000, (%esp); popf");
+#elif defined(__amd64__)
+ __asm__("pushf; orl $0x40000, (%rsp); popf");
+#endif
+
+ addr = calloc(2, sizeof(int));
+ ATF_REQUIRE(addr != NULL);
+
+ if (isQEMU())
+ atf_tc_expect_fail("QEMU fails to trap unaligned accesses");
+
+ /* Force an unaligned access */
+ addr++;
+ printf("now trying to access unaligned address %p\n", addr);
+ ATF_REQUIRE_EQ(*(volatile int *)addr, 0);
+
+ atf_tc_fail("Test did not fault as expected");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sigalarm);
+ ATF_TP_ADD_TC(tp, sigchild_normal);
+ ATF_TP_ADD_TC(tp, sigchild_dump);
+ ATF_TP_ADD_TC(tp, sigchild_kill);
+ ATF_TP_ADD_TC(tp, sigfpe_flt);
+ ATF_TP_ADD_TC(tp, sigfpe_int);
+ ATF_TP_ADD_TC(tp, sigsegv);
+ ATF_TP_ADD_TC(tp, sigbus_adraln);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sleep.c b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c
new file mode 100644
index 0000000..f722ec9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c
@@ -0,0 +1,350 @@
+/* $NetBSD: t_sleep.c,v 1.8 2014/07/15 14:56:34 gson Exp $ */
+
+/*-
+ * Copyright (c) 2006 Frank Kardel
+ * 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 <errno.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/cdefs.h>
+#include <sys/event.h>
+#include <sys/signal.h>
+
+#include "isqemu.h"
+
+#define BILLION 1000000000LL /* nano-seconds per second */
+#define MILLION 1000000LL /* nano-seconds per milli-second */
+
+#define ALARM 6 /* SIGALRM after this many seconds */
+#define MAXSLEEP 22 /* Maximum delay in seconds */
+#define KEVNT_TIMEOUT 10300 /* measured in milli-seconds */
+#define FUZZ (40 * MILLION) /* scheduling fuzz accepted - 40 ms */
+
+#ifdef __FreeBSD__
+#include <sys/time.h>
+#include <inttypes.h>
+#endif
+
+/*
+ * Timer notes
+ *
+ * Most tests use FUZZ as their initial delay value, but 'sleep'
+ * starts at 1sec (since it cannot handle sub-second intervals).
+ * Subsequent passes double the previous interval, up to MAXSLEEP.
+ *
+ * The current values result in 5 passes for the 'sleep' test (at 1,
+ * 2, 4, 8, and 16 seconds) and 10 passes for the other tests (at
+ * 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, and 20.48
+ * seconds).
+ *
+ * The ALARM is only set if the current pass's delay is longer, and
+ * only if the ALARM has not already been triggered.
+ *
+ * The 'kevent' test needs the ALARM to be set on a different pass
+ * from when the KEVNT_TIMEOUT fires. So set ALARM to fire on the
+ * penultimate pass, and the KEVNT_TIMEOUT on the final pass. We
+ * set KEVNT_TIMEOUT just barely long enough to put it into the
+ * last test pass, and set MAXSLEEP a couple seconds longer than
+ * necessary, in order to avoid a QEMU bug which nearly doubles
+ * some timers.
+ */
+
+static volatile int sig;
+
+int sleeptest(int (*)(struct timespec *, struct timespec *), bool, bool);
+int do_nanosleep(struct timespec *, struct timespec *);
+int do_select(struct timespec *, struct timespec *);
+#ifdef __NetBSD__
+int do_poll(struct timespec *, struct timespec *);
+#endif
+int do_sleep(struct timespec *, struct timespec *);
+int do_kevent(struct timespec *, struct timespec *);
+void sigalrm(int);
+
+void
+sigalrm(int s)
+{
+
+ sig++;
+}
+
+int
+do_nanosleep(struct timespec *delay, struct timespec *remain)
+{
+ int ret;
+
+ if (nanosleep(delay, remain) == -1)
+ ret = (errno == EINTR ? 0 : errno);
+ else
+ ret = 0;
+ return ret;
+}
+
+int
+do_select(struct timespec *delay, struct timespec *remain)
+{
+ int ret;
+ struct timeval tv;
+
+ TIMESPEC_TO_TIMEVAL(&tv, delay);
+ if (select(0, NULL, NULL, NULL, &tv) == -1)
+ ret = (errno == EINTR ? 0 : errno);
+ else
+ ret = 0;
+ return ret;
+}
+
+#ifdef __NetBSD__
+int
+do_poll(struct timespec *delay, struct timespec *remain)
+{
+ int ret;
+ struct timeval tv;
+
+ TIMESPEC_TO_TIMEVAL(&tv, delay);
+ if (pollts(NULL, 0, delay, NULL) == -1)
+ ret = (errno == EINTR ? 0 : errno);
+ else
+ ret = 0;
+ return ret;
+}
+#endif
+
+int
+do_sleep(struct timespec *delay, struct timespec *remain)
+{
+ struct timeval tv;
+
+ TIMESPEC_TO_TIMEVAL(&tv, delay);
+ remain->tv_sec = sleep(delay->tv_sec);
+ remain->tv_nsec = 0;
+
+ return 0;
+}
+
+int
+do_kevent(struct timespec *delay, struct timespec *remain)
+{
+ struct kevent ktimer;
+ struct kevent kresult;
+ int rtc, kq, kerrno;
+ int tmo;
+
+ ATF_REQUIRE_MSG((kq = kqueue()) != -1, "kqueue: %s", strerror(errno));
+
+ tmo = KEVNT_TIMEOUT;
+
+ /*
+ * If we expect the KEVNT_TIMEOUT to fire, and we're running
+ * under QEMU, make sure the delay is long enough to account
+ * for the effects of PR kern/43997 !
+ */
+ if (isQEMU() &&
+ tmo/1000 < delay->tv_sec && tmo/500 > delay->tv_sec)
+ delay->tv_sec = MAXSLEEP;
+
+ EV_SET(&ktimer, 1, EVFILT_TIMER, EV_ADD, 0, tmo, 0);
+
+ rtc = kevent(kq, &ktimer, 1, &kresult, 1, delay);
+ kerrno = errno;
+
+ (void)close(kq);
+
+ if (rtc == -1) {
+ ATF_REQUIRE_MSG(kerrno == EINTR, "kevent: %s", strerror(errno));
+ return 0;
+ }
+
+ if (delay->tv_sec * BILLION + delay->tv_nsec > tmo * MILLION)
+ ATF_REQUIRE_MSG(rtc > 0,
+ "kevent: KEVNT_TIMEOUT did not cause EVFILT_TIMER event");
+
+ return 0;
+}
+
+ATF_TC(nanosleep);
+ATF_TC_HEAD(nanosleep, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test nanosleep(2) timing");
+ atf_tc_set_md_var(tc, "timeout", "65");
+}
+
+ATF_TC_BODY(nanosleep, tc)
+{
+
+ sleeptest(do_nanosleep, true, false);
+}
+
+ATF_TC(select);
+ATF_TC_HEAD(select, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test select(2) timing");
+ atf_tc_set_md_var(tc, "timeout", "65");
+}
+
+ATF_TC_BODY(select, tc)
+{
+
+ sleeptest(do_select, true, true);
+}
+
+#ifdef __NetBSD__
+ATF_TC(poll);
+ATF_TC_HEAD(poll, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test poll(2) timing");
+ atf_tc_set_md_var(tc, "timeout", "65");
+}
+
+ATF_TC_BODY(poll, tc)
+{
+
+ sleeptest(do_poll, true, true);
+}
+#endif
+
+ATF_TC(sleep);
+ATF_TC_HEAD(sleep, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sleep(3) timing");
+ atf_tc_set_md_var(tc, "timeout", "65");
+}
+
+ATF_TC_BODY(sleep, tc)
+{
+
+ sleeptest(do_sleep, false, false);
+}
+
+ATF_TC(kevent);
+ATF_TC_HEAD(kevent, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test kevent(2) timing");
+ atf_tc_set_md_var(tc, "timeout", "65");
+}
+
+ATF_TC_BODY(kevent, tc)
+{
+
+ sleeptest(do_kevent, true, true);
+}
+
+int
+sleeptest(int (*test)(struct timespec *, struct timespec *),
+ bool subsec, bool sim_remain)
+{
+ struct timespec tsa, tsb, tslp, tremain;
+ int64_t delta1, delta2, delta3, round;
+
+ sig = 0;
+ signal(SIGALRM, sigalrm);
+
+ if (subsec) {
+ round = 1;
+ delta3 = FUZZ;
+ } else {
+ round = 1000000000;
+ delta3 = round;
+ }
+
+ tslp.tv_sec = delta3 / 1000000000;
+ tslp.tv_nsec = delta3 % 1000000000;
+
+ while (tslp.tv_sec <= MAXSLEEP) {
+ /*
+ * disturb sleep by signal on purpose
+ */
+ if (tslp.tv_sec > ALARM && sig == 0)
+ alarm(ALARM);
+
+ clock_gettime(CLOCK_REALTIME, &tsa);
+ (*test)(&tslp, &tremain);
+ clock_gettime(CLOCK_REALTIME, &tsb);
+
+ if (sim_remain) {
+ timespecsub(&tsb, &tsa, &tremain);
+ timespecsub(&tslp, &tremain, &tremain);
+ }
+
+ delta1 = (int64_t)tsb.tv_sec - (int64_t)tsa.tv_sec;
+ delta1 *= BILLION;
+ delta1 += (int64_t)tsb.tv_nsec - (int64_t)tsa.tv_nsec;
+
+ delta2 = (int64_t)tremain.tv_sec * BILLION;
+ delta2 += (int64_t)tremain.tv_nsec;
+
+ delta3 = (int64_t)tslp.tv_sec * BILLION;
+ delta3 += (int64_t)tslp.tv_nsec - delta1 - delta2;
+
+ delta3 /= round;
+ delta3 *= round;
+
+ if (delta3 > FUZZ || delta3 < -FUZZ) {
+ if (!sim_remain)
+ atf_tc_expect_fail("Long reschedule latency "
+ "due to PR kern/43997");
+
+ atf_tc_fail("Reschedule latency %"PRId64" exceeds "
+ "allowable fuzz %lld", delta3, FUZZ);
+ }
+ delta3 = (int64_t)tslp.tv_sec * 2 * BILLION;
+ delta3 += (int64_t)tslp.tv_nsec * 2;
+
+ delta3 /= round;
+ delta3 *= round;
+ if (delta3 < FUZZ)
+ break;
+ tslp.tv_sec = delta3 / BILLION;
+ tslp.tv_nsec = delta3 % BILLION;
+ }
+ ATF_REQUIRE_MSG(sig == 1, "Alarm did not fire!");
+
+ atf_tc_pass();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, nanosleep);
+ ATF_TP_ADD_TC(tp, select);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, poll);
+#endif
+ ATF_TP_ADD_TC(tp, sleep);
+ ATF_TP_ADD_TC(tp, kevent);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_syslog.c b/contrib/netbsd-tests/lib/libc/gen/t_syslog.c
new file mode 100644
index 0000000..c9417c0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_syslog.c
@@ -0,0 +1,56 @@
+/* $NetBSD: t_syslog.c,v 1.2 2012/03/18 07:00:51 jruoho Exp $ */
+
+/*-
+ * 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 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 HOLDERS 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 <atf-c.h>
+#include <syslog.h>
+
+ATF_TC(syslog_pthread);
+ATF_TC_HEAD(syslog_pthread, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test that syslog(3) "
+ "works when linked to pthread(3) (PR lib/44248)");
+ atf_tc_set_md_var(tc, "timeout", "2");
+}
+
+ATF_TC_BODY(syslog_pthread, tc)
+{
+ syslog(LOG_DEBUG, "from tests/lib/libc/gen/t_syslog");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, syslog_pthread);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_time.c b/contrib/netbsd-tests/lib/libc/gen/t_time.c
new file mode 100644
index 0000000..790f3ca
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_time.c
@@ -0,0 +1,117 @@
+/* $NetBSD: t_time.c,v 1.2 2011/11/11 05:03:38 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_time.c,v 1.2 2011/11/11 05:03:38 jruoho Exp $");
+
+#ifdef __FreeBSD__
+#include <sys/time.h>
+#endif
+#include <atf-c.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+ATF_TC(time_copy);
+ATF_TC_HEAD(time_copy, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test the return values of time(3)");
+}
+
+ATF_TC_BODY(time_copy, tc)
+{
+ time_t t1, t2 = 0;
+
+ t1 = time(&t2);
+
+ if (t1 != t2)
+ atf_tc_fail("incorrect return values from time(3)");
+}
+
+ATF_TC(time_mono);
+ATF_TC_HEAD(time_mono, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test monotonicity of time(3)");
+}
+
+ATF_TC_BODY(time_mono, tc)
+{
+ const size_t maxiter = 10;
+ time_t t1, t2;
+ size_t i;
+
+ for (i = 0; i < maxiter; i++) {
+
+ t1 = time(NULL);
+ (void)sleep(1);
+ t2 = time(NULL);
+
+ (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n",
+ (int64_t)t1, (int64_t)t2);
+
+ if (t1 >= t2)
+ atf_tc_fail("time(3) is not monotonic");
+ }
+}
+
+ATF_TC(time_timeofday);
+ATF_TC_HEAD(time_timeofday, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test time(3) vs. gettimeofday(2)");
+}
+
+ATF_TC_BODY(time_timeofday, tc)
+{
+ struct timeval tv = { 0, 0 };
+ time_t t;
+
+ t = time(NULL);
+ ATF_REQUIRE(gettimeofday(&tv, NULL) == 0);
+
+ (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n",
+ (int64_t)t, (int64_t)tv.tv_sec);
+
+ if (t != tv.tv_sec)
+ atf_tc_fail("time(3) and gettimeofday(2) differ");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, time_copy);
+ ATF_TP_ADD_TC(tp, time_mono);
+ ATF_TP_ADD_TC(tp, time_timeofday);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c
new file mode 100644
index 0000000..bb9d264
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c
@@ -0,0 +1,191 @@
+/* $NetBSD: t_ttyname.c,v 1.3 2011/05/01 18:14:01 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_ttyname.c,v 1.3 2011/05/01 18:14:01 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static long ttymax = 0;
+
+ATF_TC(ttyname_err);
+ATF_TC_HEAD(ttyname_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors in ttyname(3)");
+}
+
+ATF_TC_BODY(ttyname_err, tc)
+{
+ int fd;
+
+ fd = open("XXX", O_RDONLY);
+
+ if (fd < 0) {
+
+ errno = 0;
+
+ ATF_REQUIRE(isatty(fd) != -1);
+ ATF_REQUIRE(errno == EBADF);
+
+ errno = 0;
+
+ ATF_REQUIRE(ttyname(fd) == NULL);
+ ATF_REQUIRE(errno == EBADF);
+ }
+
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd >= 0) {
+
+ errno = 0;
+
+ ATF_REQUIRE(isatty(fd) != -1);
+ ATF_REQUIRE(errno == ENOTTY);
+
+ errno = 0;
+
+ ATF_REQUIRE(ttyname(fd) == NULL);
+ ATF_REQUIRE(errno == ENOTTY);
+ }
+}
+
+ATF_TC(ttyname_r_err);
+ATF_TC_HEAD(ttyname_r_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors in ttyname_r(3)");
+}
+
+ATF_TC_BODY(ttyname_r_err, tc)
+{
+ char sbuf[0];
+ char *buf;
+ int fd;
+ int rv;
+
+ buf = malloc(ttymax + 1);
+
+ if (buf == NULL)
+ return;
+
+ (void)memset(buf, '\0', ttymax + 1);
+
+ if (isatty(STDIN_FILENO) != 0) {
+
+ rv = ttyname_r(STDIN_FILENO, sbuf, sizeof(sbuf));
+ ATF_REQUIRE(rv == ERANGE);
+ }
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("FreeBSD returns ENOTTY instead of EBADF; see bin/191936");
+#endif
+ rv = ttyname_r(-1, buf, ttymax);
+ ATF_REQUIRE(rv == EBADF);
+
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd >= 0) {
+ rv = ttyname_r(fd, buf, ttymax);
+ ATF_REQUIRE(rv == ENOTTY);
+ ATF_REQUIRE(close(fd) == 0);
+ }
+
+ free(buf);
+}
+
+ATF_TC(ttyname_r_stdin);
+ATF_TC_HEAD(ttyname_r_stdin, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ttyname_r(3) with stdin(3)");
+}
+
+ATF_TC_BODY(ttyname_r_stdin, tc)
+{
+ const char *str;
+ char *buf;
+ int rv;
+
+ if (isatty(STDIN_FILENO) == 0)
+ return;
+
+ buf = malloc(ttymax + 1);
+
+ if (buf == NULL)
+ return;
+
+ (void)memset(buf, '\0', ttymax + 1);
+
+ str = ttyname(STDIN_FILENO);
+ rv = ttyname_r(STDIN_FILENO, buf, ttymax);
+
+ ATF_REQUIRE(rv == 0);
+ ATF_REQUIRE(str != NULL);
+
+ if (strcmp(str, buf) != 0)
+ atf_tc_fail("ttyname(3) and ttyname_r(3) conflict");
+
+ free(buf);
+}
+
+ATF_TC(ttyname_stdin);
+ATF_TC_HEAD(ttyname_stdin, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ttyname(3) with stdin(3)");
+}
+
+ATF_TC_BODY(ttyname_stdin, tc)
+{
+
+ if (isatty(STDIN_FILENO) != 0)
+ ATF_REQUIRE(ttyname(STDIN_FILENO) != NULL);
+
+ (void)close(STDIN_FILENO);
+
+ ATF_REQUIRE(isatty(STDIN_FILENO) != 1);
+ ATF_REQUIRE(ttyname(STDIN_FILENO) == NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ttymax = sysconf(_SC_TTY_NAME_MAX);
+ ATF_REQUIRE(ttymax >= 0);
+
+ ATF_TP_ADD_TC(tp, ttyname_err);
+ ATF_TP_ADD_TC(tp, ttyname_r_err);
+ ATF_TP_ADD_TC(tp, ttyname_r_stdin);
+ ATF_TP_ADD_TC(tp, ttyname_stdin);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_vis.c b/contrib/netbsd-tests/lib/libc/gen/t_vis.c
new file mode 100644
index 0000000..525bafa
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_vis.c
@@ -0,0 +1,155 @@
+/* $NetBSD: t_vis.c,v 1.7 2014/09/08 19:01:03 christos Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Christos Zoulas.
+ *
+ * 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 <string.h>
+#include <stdlib.h>
+#include <err.h>
+#include <vis.h>
+
+static int styles[] = {
+ VIS_OCTAL,
+ VIS_CSTYLE,
+ VIS_SP,
+ VIS_TAB,
+ VIS_NL,
+ VIS_WHITE,
+ VIS_SAFE,
+#if 0 /* Not reversible */
+ VIS_NOSLASH,
+#endif
+ VIS_HTTP1808,
+ VIS_MIMESTYLE,
+#if 0 /* Not supported by vis(3) */
+ VIS_HTTP1866,
+#endif
+};
+
+#define SIZE 256
+
+ATF_TC(strvis_basic);
+ATF_TC_HEAD(strvis_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test strvis(3)");
+}
+
+ATF_TC_BODY(strvis_basic, tc)
+{
+ char *srcbuf, *dstbuf, *visbuf;
+ unsigned int i, j;
+
+ ATF_REQUIRE((dstbuf = malloc(SIZE)) != NULL);
+ ATF_REQUIRE((srcbuf = malloc(SIZE)) != NULL);
+ ATF_REQUIRE((visbuf = malloc(SIZE * 4 + 1)) != NULL);
+
+ for (i = 0; i < SIZE; i++)
+ srcbuf[i] = (char)i;
+
+ for (i = 0; i < __arraycount(styles); i++) {
+ ATF_REQUIRE(strsvisx(visbuf, srcbuf, SIZE, styles[i], "") > 0);
+ memset(dstbuf, 0, SIZE);
+ ATF_REQUIRE(strunvisx(dstbuf, visbuf,
+ styles[i] & (VIS_HTTP1808|VIS_MIMESTYLE)) > 0);
+ for (j = 0; j < SIZE; j++)
+ if (dstbuf[j] != (char)j)
+ atf_tc_fail_nonfatal("Failed for style %x, "
+ "char %d [%d]", styles[i], j, dstbuf[j]);
+ }
+ free(dstbuf);
+ free(srcbuf);
+ free(visbuf);
+}
+
+ATF_TC(strvis_null);
+ATF_TC_HEAD(strvis_null, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strvis(3) NULL");
+}
+
+ATF_TC_BODY(strvis_null, tc)
+{
+ char dst[] = "fail";
+ strvis(dst, NULL, VIS_SAFE);
+ ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a');
+}
+
+ATF_TC(strvis_empty);
+ATF_TC_HEAD(strvis_empty, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strvis(3) empty");
+}
+
+ATF_TC_BODY(strvis_empty, tc)
+{
+ char dst[] = "fail";
+ strvis(dst, "", VIS_SAFE);
+ ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a');
+}
+
+ATF_TC(strunvis_hex);
+ATF_TC_HEAD(strunvis_hex, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strunvis(3) \\xXX");
+}
+
+ATF_TC_BODY(strunvis_hex, tc)
+{
+ static const struct {
+ const char *e;
+ const char *d;
+ int error;
+ } ed[] = {
+ { "\\xff", "\xff", 1 },
+ { "\\x1", "\x1", 1 },
+ { "\\x1\\x02", "\x1\x2", 2 },
+ { "\\x1x", "\x1x", 2 },
+ { "\\xx", "", -1 },
+ };
+ char uv[10];
+
+ for (size_t i = 0; i < __arraycount(ed); i++) {
+ ATF_REQUIRE(strunvis(uv, ed[i].e) == ed[i].error);
+ if (ed[i].error > 0)
+ ATF_REQUIRE(memcmp(ed[i].d, uv, ed[i].error) == 0);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strvis_basic);
+ ATF_TP_ADD_TC(tp, strvis_null);
+ ATF_TP_ADD_TC(tp, strvis_empty);
+ ATF_TP_ADD_TC(tp, strunvis_hex);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/hash/data/md5test-in b/contrib/netbsd-tests/lib/libc/hash/data/md5test-in
new file mode 100644
index 0000000..763e4f9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/data/md5test-in
@@ -0,0 +1,7 @@
+
+a
+abc
+message digest
+abcdefghijklmnopqrstuvwxyz
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
diff --git a/contrib/netbsd-tests/lib/libc/hash/data/md5test-out b/contrib/netbsd-tests/lib/libc/hash/data/md5test-out
new file mode 100644
index 0000000..bb86bb6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/data/md5test-out
@@ -0,0 +1,7 @@
+d41d8cd98f00b204e9800998ecf8427e
+0cc175b9c0f1b6a831c399e269772661
+900150983cd24fb0d6963f7d28e17f72
+f96b697d7cb7938d525a2f31aaf161d0
+c3fcd3d76192e4007dfb496cca67e13b
+d174ab98d277d9f5a5611c2c9f419d9f
+57edf4a22be3c955ac49da2e2107b67a
diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in
new file mode 100644
index 0000000..632d133
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-in
@@ -0,0 +1,2 @@
+abc
+abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq
diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out
new file mode 100644
index 0000000..c23a058
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test-out
@@ -0,0 +1,2 @@
+a9993e364706816aba3e25717850c26c9cd0d89d
+84983e441c3bd26ebaae4aa1f95129e5e54670f1
diff --git a/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out b/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out
new file mode 100644
index 0000000..a483a0e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out
@@ -0,0 +1 @@
+34aa973cd4c4daa4f61eeb2bdbad27316534016f
diff --git a/contrib/netbsd-tests/lib/libc/hash/h_hash.c b/contrib/netbsd-tests/lib/libc/hash/h_hash.c
new file mode 100644
index 0000000..6e20a48
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/h_hash.c
@@ -0,0 +1,187 @@
+/* $NetBSD: h_hash.c,v 1.1 2011/01/02 22:03:25 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2000 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.
+ */
+
+/*
+ * Combined MD5/SHA1 time and regression test.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <md5.h>
+#ifdef __NetBSD__
+#include <sha1.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <sha.h>
+#endif
+
+int mflag, rflag, sflag, tflag;
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr,
+ "Usage:\t%s -r[ms] < test-file\n"
+ "\t%s -t[ms]\n",
+ getprogname(), getprogname());
+ exit(1);
+ /* NOTREACHED */
+}
+
+static void
+hexdump (unsigned char *buf, int len)
+{
+ int i;
+ for (i=0; i<len; i++) {
+ printf("%02x", buf[i]);
+ }
+ printf("\n");
+}
+
+
+static void
+timetest(void)
+{
+ printf("sorry, not yet\n");
+}
+
+#define CHOMP(buf, len, last) \
+ if ((len > 0) && \
+ (buf[len-1] == '\n')) { \
+ buf[len-1] = '\0'; \
+ len--; \
+ last = 1; \
+ }
+
+static void
+regress(void)
+{
+ unsigned char buf[1024];
+ unsigned char out[20];
+ int len, outlen, last;
+
+ while (fgets((char *)buf, sizeof(buf), stdin) != NULL) {
+ last = 0;
+
+ len = strlen((char *)buf);
+ CHOMP(buf, len, last);
+ if (mflag) {
+ MD5_CTX ctx;
+
+ MD5Init(&ctx);
+ MD5Update(&ctx, buf, len);
+ while (!last &&
+ fgets((char *)buf, sizeof(buf), stdin) != NULL) {
+ len = strlen((char *)buf);
+ CHOMP(buf, len, last);
+ MD5Update(&ctx, buf, len);
+ }
+ MD5Final(out, &ctx);
+ outlen = 16;
+ } else {
+#ifdef __FreeBSD__
+ SHA_CTX ctx;
+
+ SHA1_Init(&ctx);
+ SHA1_Update(&ctx, buf, len);
+#else
+ SHA1_CTX ctx;
+
+ SHA1Init(&ctx);
+ SHA1Update(&ctx, buf, len);
+#endif
+ while (!last &&
+ fgets((char *)buf, sizeof(buf), stdin) != NULL) {
+ len = strlen((char *)buf);
+ CHOMP(buf, len, last);
+#ifdef __FreeBSD__
+ SHA1_Update(&ctx, buf, len);
+#else
+ SHA1Update(&ctx, buf, len);
+#endif
+ }
+#ifdef __FreeBSD__
+ SHA1_Final(out, &ctx);
+#else
+ SHA1Final(out, &ctx);
+#endif
+ outlen = 20;
+ }
+ hexdump(out, outlen);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int ch;
+
+ while ((ch = getopt(argc, argv, "mrst")) != -1)
+ switch (ch) {
+ case 'm':
+ mflag = 1;
+ break;
+ case 'r':
+ rflag = 1;
+ break;
+ case 's':
+ sflag = 1;
+ break;
+ case 't':
+ tflag = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
+
+ if (!(mflag || sflag))
+ mflag = 1;
+
+ if ((mflag ^ sflag) != 1)
+ usage();
+
+ if ((tflag ^ rflag) != 1)
+ usage();
+
+ if (tflag)
+ timetest();
+
+ if (rflag)
+ regress();
+
+ exit(0);
+
+}
diff --git a/contrib/netbsd-tests/lib/libc/hash/t_hash.sh b/contrib/netbsd-tests/lib/libc/hash/t_hash.sh
new file mode 100755
index 0000000..719f19d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/t_hash.sh
@@ -0,0 +1,67 @@
+# $NetBSD: t_hash.sh,v 1.1 2011/01/02 22:03:25 pgoyette Exp $
+#
+# 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.
+#
+
+prog()
+{
+ echo "$(atf_get_srcdir)/h_hash"
+}
+
+datadir()
+{
+ echo "$(atf_get_srcdir)/data"
+}
+
+atf_test_case md5
+md5_head()
+{
+ atf_set "descr" "Checks MD5 functions"
+}
+md5_body()
+{
+ atf_check -o file:"$(datadir)/md5test-out" -x \
+ "$(prog) -r < $(datadir)/md5test-in"
+}
+
+atf_test_case sha1
+sha1_head()
+{
+ atf_set "descr" "Checks SHA1 functions"
+}
+sha1_body()
+{
+ atf_check -o file:"$(datadir)/sha1test-out" -x \
+ "$(prog) -rs < $(datadir)/sha1test-in"
+
+ atf_check -o file:"$(datadir)/sha1test2-out" -x \
+ "jot -s '' -b 'a' -n 1000000 | $(prog) -rs"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case md5
+ atf_add_test_case sha1
+}
diff --git a/contrib/netbsd-tests/lib/libc/hash/t_sha2.c b/contrib/netbsd-tests/lib/libc/hash/t_sha2.c
new file mode 100644
index 0000000..ce2c80d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/t_sha2.c
@@ -0,0 +1,257 @@
+/* $NetBSD: t_sha2.c,v 1.3 2012/09/26 22:23:30 joerg Exp $ */
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_sha2.c,v 1.3 2012/09/26 22:23:30 joerg Exp $");
+
+#include <atf-c.h>
+#include <sys/types.h>
+#ifdef __NetBSD__
+#include <sha2.h>
+#endif
+#include <string.h>
+
+#ifdef __FreeBSD__
+#include <openssl/sha.h>
+typedef SHA512_CTX SHA384_CTX;
+/* From /usr/src/crypto/openssh/openbsd-compat/sha2.h */
+#define SHA256_DIGEST_LENGTH 32
+#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
+#define SHA384_DIGEST_LENGTH 48
+#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
+#define SHA512_DIGEST_LENGTH 64
+#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
+#endif
+
+ATF_TC(t_sha256);
+ATF_TC(t_sha384);
+ATF_TC(t_sha512);
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_sha256);
+ ATF_TP_ADD_TC(tp, t_sha384);
+ ATF_TP_ADD_TC(tp, t_sha512);
+
+ return atf_no_error();
+}
+
+struct testvector {
+ const char *vector;
+ const char *hash;
+};
+
+static const struct testvector test256[] = {
+ { "hello, world", "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b" },
+ { "", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" },
+ { "a", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" },
+ { "ab", "fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603" },
+ { "abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" },
+ { "abcd", "88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589" },
+ { "abcde", "36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c" },
+ { "abcdef", "bef57ec7f53a6d40beb640a780a639c83bc29ac8a9816f1fc6c5c6dcd93c4721" },
+ { "abcdefg", "7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a" },
+ { "abcdefgh", "9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab" },
+ { "abcdefghi", "19cc02f26df43cc571bc9ed7b0c4d29224a3ec229529221725ef76d021c8326f" },
+ { "abcdefghij", "72399361da6a7754fec986dca5b7cbaf1c810a28ded4abaf56b2106d06cb78b0" },
+ { "abcdefghijk", "ca2f2069ea0c6e4658222e06f8dd639659cbb5e67cbbba6734bc334a3799bc68" },
+ { "abcdefghijkl", "d682ed4ca4d989c134ec94f1551e1ec580dd6d5a6ecde9f3d35e6e4a717fbde4" },
+ { "abcdefghijklm", "ff10304f1af23606ede1e2d8abcdc94c229047a61458d809d8bbd53ede1f6598" },
+ { "abcdefghijklmn", "0653c7e992d7aad40cb2635738b870e4c154afb346340d02c797d490dd52d5f9" },
+ { "abcdefghijklmno", "41c7760c50efde99bf574ed8fffc7a6dd3405d546d3da929b214c8945acf8a97" },
+ { "abcdefghijklmnop", "f39dac6cbaba535e2c207cd0cd8f154974223c848f727f98b3564cea569b41cf" },
+ { "abcdefghijklmnopq", "918a954ac4dfb54ac39f068d9868227f69ab39bc362e2c9b0083bf6a109d6ad7" },
+ { "abcdefghijklmnopqr", "2d1222692afaf56e95a8ab00879ed023a00db3e26fa14236e542748579285efa" },
+ { "abcdefghijklmnopqrs", "e250f886728b77ba63722c7e65fc73e203101a84281b32332fd67cc6a1ae3e22" },
+ { "abcdefghijklmnopqrst", "dd65eea0329dcb94b17187af9dff28c31a1d78026737a16af75979a1fa4618e5" },
+ { "abcdefghijklmnopqrstu", "25f62a5a3d414ec6e20907df7f367f2b72625aade552db64c07933f6044fc49a" },
+ { "abcdefghijklmnopqrstuv", "f69f9b70d1c9a5442258ca76f8b0a7a45fcb4e31c36141b6357ec591328b0624" },
+ { "abcdefghijklmnopqrstuvw", "7f07818e14d08944ce145629ca54332f5cfad148c590efbcb5c377f4d336e5f4" },
+ { "abcdefghijklmnopqrstuvwq", "063132d7fbec0acb79b2f228777eec8885e7f09bc1896b3ce5aa1843e83de048" },
+};
+
+static const struct testvector test384[] = {
+ { "hello, world", "1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e" },
+ { "", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" },
+ { "a", "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31" },
+ { "ab", "c7be03ba5bcaa384727076db0018e99248e1a6e8bd1b9ef58a9ec9dd4eeebb3f48b836201221175befa74ddc3d35afdd" },
+ { "abc", "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" },
+ { "abcd", "1165b3406ff0b52a3d24721f785462ca2276c9f454a116c2b2ba20171a7905ea5a026682eb659c4d5f115c363aa3c79b" },
+ { "abcde", "4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0" },
+ { "abcdef", "c6a4c65b227e7387b9c3e839d44869c4cfca3ef583dea64117859b808c1e3d8ae689e1e314eeef52a6ffe22681aa11f5" },
+ { "abcdefg", "9f11fc131123f844c1226f429b6a0a6af0525d9f40f056c7fc16cdf1b06bda08e302554417a59fa7dcf6247421959d22" },
+ { "abcdefgh", "9000cd7cada59d1d2eb82912f7f24e5e69cc5517f68283b005fa27c285b61e05edf1ad1a8a9bded6fd29eb87d75ad806" },
+ { "abcdefghi", "ef54915b60cf062b8dd0c29ae3cad69abe6310de63ac081f46ef019c5c90897caefd79b796cfa81139788a260ded52df" },
+ { "abcdefghij", "a12070030a02d86b0ddacd0d3a5b598344513d0a051e7355053e556a0055489c1555399b03342845c4adde2dc44ff66c" },
+ { "abcdefghijk", "2440d0e751fe5b8b1aba067e20be00b9deecc5e218b0b4b37202de824bcd04294d67c8d0b73e393afa844fa9ca25fa51" },
+ { "abcdefghijkl", "103ca96c06a1ce798f08f8eff0dfb0ccdb567d48b285b23d0cd773454667a3c2fa5f1b58d9cdf2329bd9979730bfaaff" },
+ { "abcdefghijklm", "89a7179df195462f047393c36e4843183eb38404bdfbacfd0b0f9c2556632a2799f19c3ecf48bdb7c9bdf95d3f6c3704" },
+ { "abcdefghijklmn", "3bc463b0a5614d39fd207cbfd108534bce68d5438235c6c577b34b70fe219954adceaf8808d1fad4a44fc9c420ea8ff1" },
+ { "abcdefghijklmno", "5149860ee76dd6666308189e60090d615e36ce0c0ef753a610cca0524a022900489d70167a47cc74c4dd9f9f340066af" },
+ { "abcdefghijklmnop", "96d3c1b54b1938600abe5b57232e185df1c5856f74656b8f9837c5317cf5b22ac38226fafc8c946b9d20aca1b0c53a98" },
+ { "abcdefghijklmnopq", "dae0d8c29d8f1137df3afb8f502dc474d3bbb56de0c10fc219547826f23f38f37ec29e4ed203908e6e7955c83a138129" },
+ { "abcdefghijklmnopqr", "5cfa62716d985d3b1efab0ed3460e7b7f6af9439ae8ee5c58b20e68607eeec3e8c6df8481f5f36e726eaa56512acea6e" },
+ { "abcdefghijklmnopqrs", "c5d404fc93b0e59ecb5f40446da201876faf18a0af46e577ae2f7a4fe56dc4c419afff7edec90ff3de160d0c5e7a5ec1" },
+ { "abcdefghijklmnopqrst", "bc1511cd8b813544cb60b13d1ceb63e81f46aa3ca114a23fc5c3aba54f9965cdf9afa68e2dc2a680934e429dff5aa7f2" },
+ { "abcdefghijklmnopqrstu", "8f18622d37e0aceabba191e3836b30e8970aca202ce6e811f586ec5f950edb7bf799cc88a18468a3effb063397242d95" },
+ { "abcdefghijklmnopqrstuv", "c8a4f46e609626543ce6c1362721fcbe95c8e7405aaee61da4f2da1740f0351172c98a66530f8607bf8609e387ff8456" },
+ { "abcdefghijklmnopqrstuvw", "2daff33b3bd67de61550070696b431d54b1397b40d053912b07a94260812185907726e3efbe9ae9fc078659cd2ce36db" },
+ { "abcdefghijklmnopqrstuvwq", "87dc70a2eaa0dd0b687f91f26383866161026e41bb310a9e32b7a17c99284db85b9743476a30caeedf3fbb3c8072bc5e" },
+};
+
+static const struct testvector test512[] = {
+ { "hello, world", "8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9" },
+ { "", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" },
+ { "a", "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75" },
+ { "ab", "2d408a0717ec188158278a796c689044361dc6fdde28d6f04973b80896e1823975cdbf12eb63f9e0591328ee235d80e9b5bf1aa6a44f4617ff3caf6400eb172d" },
+ { "abc", "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" },
+ { "abcd", "d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f" },
+ { "abcde", "878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1" },
+ { "abcdef", "e32ef19623e8ed9d267f657a81944b3d07adbb768518068e88435745564e8d4150a0a703be2a7d88b61e3d390c2bb97e2d4c311fdc69d6b1267f05f59aa920e7" },
+ { "abcdefg", "d716a4188569b68ab1b6dfac178e570114cdf0ea3a1cc0e31486c3e41241bc6a76424e8c37ab26f096fc85ef9886c8cb634187f4fddff645fb099f1ff54c6b8c" },
+ { "abcdefgh", "a3a8c81bc97c2560010d7389bc88aac974a104e0e2381220c6e084c4dccd1d2d17d4f86db31c2a851dc80e6681d74733c55dcd03dd96f6062cdda12a291ae6ce" },
+ { "abcdefghi", "f22d51d25292ca1d0f68f69aedc7897019308cc9db46efb75a03dd494fc7f126c010e8ade6a00a0c1a5f1b75d81e0ed5a93ce98dc9b833db7839247b1d9c24fe" },
+ { "abcdefghij", "ef6b97321f34b1fea2169a7db9e1960b471aa13302a988087357c520be957ca119c3ba68e6b4982c019ec89de3865ccf6a3cda1fe11e59f98d99f1502c8b9745" },
+ { "abcdefghijk", "2798fd001ee8800e3da09ee99ae9600de2d0ccf464ab782c92fcc06ce3847cef0743365f1d49c2c8b4426db1635433f937d508672a9d0cb673b84f368eca1b23" },
+ { "abcdefghijkl", "17807c728ee3ba35e7cf7af823116d26e41e5d4d6c2ff1f3720d3d96aacb6f69de642e63d5b73fc396c12be38b2bd5d884257c32c8f6d0854ae6b540f86dda2e" },
+ { "abcdefghijklm", "e11a66f7b9a2acda5663e9434377137d73ea560a32782230412642a463c8558123bfb7c0dbf17851e9aa58cc9587c3b4f5e3f7f38dcb6f890702e5bed4d5b54a" },
+ { "abcdefghijklmn", "8334134081070bf7fcc8bf1c242d24bb3182a5119e5fb19d8bbf6b9d0cdb7fed5336e83415fce93094c0e55123cf69e14d7ae41b22289232699824e31125b6d9" },
+ { "abcdefghijklmno", "db723f341a042d8de1aa813efd5e02fc1745ccbe259486257514804e2ec4bcebb2a46f1e4ad442154943f9e97e1bc47c3ae0eddab7de0c01a9c51f15342a5b19" },
+ { "abcdefghijklmnop", "d0cadd6834fa0c157b36cca30ee8b0b1435d841aa5b5ac850c11ae80a1440f51743e98fb1f1e7376c70f2f65404f088c28bcb4a511df2e64111f8f7424364b60" },
+ { "abcdefghijklmnopq", "6196942a8495b721f82bbc385c74c1f10eeadf35db8adc9cf1a05ddeed19351228279644cd5d686ee48a31631ebb64747a2b68b733dd6015e3d27750878fa875" },
+ { "abcdefghijklmnopqr", "fb3bd1fc157ea6f7a6728986a59b271b766fb723f6b7cf2b4194437435f2c497f33b6a56ae7eb3830fa9e04d5ebb4cb5e3f4d4bd812c498bdf0167e125de3fba" },
+ { "abcdefghijklmnopqrs", "836f9ecf2aa02f522a94f1370af45a9fd538ac3c70e3b709d614b2f8981881d6b0070fc6387b74ee371fc2549309f82926e78084b401deb61a106c399089bee8" },
+ { "abcdefghijklmnopqrst", "8cd9c137651425fb32d193d99b281735ec68eb5fd296f16459d1b33eac7badcfce0dca22eadaa5f209fa4ac3bbecd41342bac8b8a5dc3626e7f22cdc96e17cb4" },
+ { "abcdefghijklmnopqrstu", "7079853a3e36241a8d83639f168ef38e883d7f72851a84ef3ed4d91c6a3896cf542b8b4518c2816fb19d4692a4b9aae65cb857e3642ce0a3936e20363bcbd4ca" },
+ { "abcdefghijklmnopqrstuv", "a4e8a90b7058fb078e6cdcfd0c6a33c366437eb9084eac657830356804c9f9b53f121496d8e972d8707a4cf02615e6f58ed1a770c28ac79ffd845401fe18a928" },
+ { "abcdefghijklmnopqrstuvw", "d91b1fd7c7785975493826719f333d090b214ff42351c84d8f8b2538509a28d2d59a36d0ac798d99d3908083b072a4be606ae391def5daa74156350fec71dd24" },
+ { "abcdefghijklmnopqrstuvwq", "404eb5652173323320cac6bf8d9714aef0747693a8ab4570700c6262268d367f30e31c44fa66860568ff058fe39c9aa8dac76bc78566c691a884cb9052c4aa0a" },
+};
+
+static void
+digest2string(const uint8_t *digest, char *string, size_t len)
+{
+ while (len--) {
+ if (*digest / 16 < 10)
+ *string++ = '0' + *digest / 16;
+ else
+ *string++ = 'a' + *digest / 16 - 10;
+ if (*digest % 16 < 10)
+ *string++ = '0' + *digest % 16;
+ else
+ *string++ = 'a' + *digest % 16 - 10;
+ ++digest;
+ }
+ *string = '\0';
+}
+
+ATF_TC_HEAD(t_sha256, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test SHA256 functions for consistent results");
+}
+
+ATF_TC_BODY(t_sha256, tc)
+{
+ size_t i, j, len;
+ SHA256_CTX ctx;
+ unsigned char buf[256];
+ unsigned char digest[8 + SHA256_DIGEST_LENGTH];
+ char output[SHA256_DIGEST_STRING_LENGTH];
+
+ for (i = 0; i < sizeof(test256) / sizeof(test256[0]); ++i) {
+ len = strlen(test256[i].vector);
+ for (j = 0; j < 8; ++j) {
+ SHA256_Init(&ctx);
+ memcpy(buf + j, test256[i].vector, len);
+ SHA256_Update(&ctx, buf + j, len);
+ SHA256_Final(digest + j, &ctx);
+ digest2string(digest + j, output, SHA256_DIGEST_LENGTH);
+ ATF_CHECK_STREQ(test256[i].hash, output);
+ }
+ }
+}
+
+ATF_TC_HEAD(t_sha384, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test SHA384 functions for consistent results");
+}
+
+ATF_TC_BODY(t_sha384, tc)
+{
+ size_t i, j, len;
+ SHA384_CTX ctx;
+ unsigned char buf[384];
+ unsigned char digest[8 + SHA384_DIGEST_LENGTH];
+ char output[SHA384_DIGEST_STRING_LENGTH];
+
+ for (i = 0; i < sizeof(test384) / sizeof(test384[0]); ++i) {
+ len = strlen(test384[i].vector);
+ for (j = 0; j < 8; ++j) {
+ SHA384_Init(&ctx);
+ memcpy(buf + j, test384[i].vector, len);
+ SHA384_Update(&ctx, buf + j, len);
+ SHA384_Final(digest + j, &ctx);
+ digest2string(digest + j, output, SHA384_DIGEST_LENGTH);
+ ATF_CHECK_STREQ(test384[i].hash, output);
+ }
+ }
+}
+
+ATF_TC_HEAD(t_sha512, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test SHA512 functions for consistent results");
+}
+
+ATF_TC_BODY(t_sha512, tc)
+{
+ size_t i, j, len;
+ SHA512_CTX ctx;
+ unsigned char buf[512];
+ unsigned char digest[8 + SHA512_DIGEST_LENGTH];
+ char output[SHA512_DIGEST_STRING_LENGTH];
+
+ for (i = 0; i < sizeof(test512) / sizeof(test512[0]); ++i) {
+ len = strlen(test512[i].vector);
+ for (j = 0; j < 8; ++j) {
+ SHA512_Init(&ctx);
+ memcpy(buf + j, test512[i].vector, len);
+ SHA512_Update(&ctx, buf + j, len);
+ SHA512_Final(digest + j, &ctx);
+ digest2string(digest + j, output, SHA512_DIGEST_LENGTH);
+ ATF_CHECK_STREQ(test512[i].hash, output);
+ }
+ }
+}
diff --git a/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c b/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c
new file mode 100644
index 0000000..a6a6c62
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c
@@ -0,0 +1,174 @@
+/* $NetBSD: t_inet_network.c,v 1.3 2011/07/15 11:27:23 jruoho Exp $ */
+
+/*
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Brian Ginsbach.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_inet_network.c,v 1.3 2011/07/15 11:27:23 jruoho Exp $");
+
+#include <arpa/inet.h>
+
+#include <atf-c.h>
+#include <stdio.h>
+#include <string.h>
+
+#define H_REQUIRE(input, expected) \
+ ATF_REQUIRE_EQ_MSG(inet_network(input), (in_addr_t) expected, \
+ "inet_network(%s) returned: 0x%08X, expected: %s", #input, \
+ inet_network(input), #expected)
+
+ATF_TC(inet_addr_basic);
+ATF_TC_HEAD(inet_addr_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks inet_addr(3)");
+}
+
+ATF_TC_BODY(inet_addr_basic, tc)
+{
+ static const char *addrs[] = {
+ "127.0.0.1", "99.99.99.99", "0.0.0.0", "255.255.255.255" };
+
+ struct in_addr ia;
+ const char *ian;
+ in_addr_t addr;
+ size_t i;
+
+ for (i = 0; i < __arraycount(addrs); i++) {
+
+ (void)fprintf(stderr, "checking %s\n", addrs[i]);;
+
+ addr = inet_addr(addrs[i]);
+ ia.s_addr = addr;
+ ian = inet_ntoa(ia);
+
+ ATF_REQUIRE(ian != NULL);
+ ATF_CHECK(strcmp(ian, addrs[i]) == 0);
+ }
+}
+
+ATF_TC(inet_addr_err);
+ATF_TC_HEAD(inet_addr_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Invalid addresses with inet_addr(3)");
+}
+
+ATF_TC_BODY(inet_addr_err, tc)
+{
+ static const char *addrs[] = {
+ ". . . .", "1.2.3.", "0.0.0.256", "255.255.255.256",
+ "................................................",
+ "a.b.c.d", "0x0.0x1.0x2.0x3", "-1.-1.-1.-1", "", " "};
+
+ struct in_addr ia;
+ const char *ian;
+ in_addr_t addr;
+ size_t i;
+
+ for (i = 0; i < __arraycount(addrs); i++) {
+
+ (void)fprintf(stderr, "checking %s\n", addrs[i]);;
+
+ addr = inet_addr(addrs[i]);
+ ia.s_addr = addr;
+ ian = inet_ntoa(ia);
+
+ ATF_REQUIRE(ian != NULL);
+ ATF_CHECK(strcmp(ian, addrs[i]) != 0);
+ }
+}
+
+ATF_TC(inet_network_basic);
+ATF_TC_HEAD(inet_network_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks inet_network(3)");
+}
+
+ATF_TC_BODY(inet_network_basic, tc)
+{
+
+ H_REQUIRE("0x12", 0x00000012);
+ H_REQUIRE("127.1", 0x00007f01);
+ H_REQUIRE("127.1.2.3", 0x7f010203);
+ H_REQUIRE("0X12", 0x00000012);
+ H_REQUIRE("0", 0x0);
+ H_REQUIRE("01.02.07.077", 0x0102073f);
+ H_REQUIRE("0x1.23.045.0", 0x01172500);
+ H_REQUIRE("0x12.0x34", 0x00001234);
+
+ /* This is valid (because of the trailing space after the digit). */
+ H_REQUIRE("1 bar", 0x00000001);
+}
+
+ATF_TC(inet_network_err);
+ATF_TC_HEAD(inet_network_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Invalid addresses w/ inet_network(3)");
+}
+
+ATF_TC_BODY(inet_network_err, tc)
+{
+ /* Malformed requests. */
+ H_REQUIRE("4.2.3.1.", 0xffffffff);
+ H_REQUIRE("0x123456", 0xffffffff);
+ H_REQUIRE("0x12.0x345", 0xffffffff);
+ H_REQUIRE("1.2.3.4.5", 0xffffffff);
+ H_REQUIRE("1..3.4", 0xffffffff);
+ H_REQUIRE(".", 0xffffffff);
+ H_REQUIRE("1.", 0xffffffff);
+ H_REQUIRE(".1", 0xffffffff);
+#if defined(__FreeBSD__) || defined(__APPLE__)
+ H_REQUIRE("0x", 0x0);
+#else
+ H_REQUIRE("0x", 0xffffffff);
+#endif
+ H_REQUIRE("", 0xffffffff);
+ H_REQUIRE(" ", 0xffffffff);
+ H_REQUIRE("bar", 0xffffffff);
+ H_REQUIRE("1.2bar", 0xffffffff);
+ H_REQUIRE("1.", 0xffffffff);
+ H_REQUIRE("\xc3\x8a\xc3\x83\xc3\x95\xc3\x8b\xc3\x85\xc3\x8e",
+ 0xffffffff);
+ H_REQUIRE("255.255.255.255", 0xffffffff);
+ H_REQUIRE("x", 0xffffffff);
+ H_REQUIRE("078", 0xffffffff);
+ H_REQUIRE("127.0xfff", 0xffffffff);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, inet_addr_basic);
+ ATF_TP_ADD_TC(tp, inet_addr_err);
+ ATF_TP_ADD_TC(tp, inet_network_basic);
+ ATF_TP_ADD_TC(tp, inet_network_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_io.c b/contrib/netbsd-tests/lib/libc/locale/t_io.c
new file mode 100644
index 0000000..86029e9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_io.c
@@ -0,0 +1,193 @@
+/* $NetBSD: t_io.c,v 1.4 2014/01/21 00:32:16 yamt Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_io.c,v 1.4 2014/01/21 00:32:16 yamt Exp $");
+
+#include <sys/param.h>
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+
+ATF_TC(bad_big5_wprintf);
+ATF_TC_HEAD(bad_big5_wprintf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar wprintf");
+}
+
+ATF_TC_BODY(bad_big5_wprintf, tc)
+{
+#ifdef __FreeBSD__
+ atf_tc_skip("does not fail as expected (may be implementation "
+ "specific issue with the test)");
+#endif
+
+ /* XXX implementation detail knowledge (wchar_t encoding) */
+ wchar_t ibuf[] = { 0xcf10, 0 };
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+
+ ATF_REQUIRE_ERRNO(EILSEQ, wprintf(L"%ls\n", ibuf) < 0);
+ ATF_REQUIRE(ferror(stdout));
+}
+
+ATF_TC(bad_big5_swprintf);
+ATF_TC_HEAD(bad_big5_swprintf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar swprintf");
+}
+
+ATF_TC_BODY(bad_big5_swprintf, tc)
+{
+#ifdef __FreeBSD__
+ atf_tc_skip("does not fail as expected (may be implementation "
+ "specific issue with the test)");
+#endif
+
+ /* XXX implementation detail knowledge (wchar_t encoding) */
+ wchar_t ibuf[] = { 0xcf10, 0 };
+ wchar_t obuf[20];
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+
+ ATF_REQUIRE_ERRNO(EILSEQ,
+ swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf) < 0);
+}
+
+ATF_TC(good_big5_wprintf);
+ATF_TC_HEAD(good_big5_wprintf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test good big5 wchar wprintf");
+}
+
+ATF_TC_BODY(good_big5_wprintf, tc)
+{
+ /* XXX implementation detail knowledge (wchar_t encoding) */
+ wchar_t ibuf[] = { 0xcf40, 0 };
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+ ATF_REQUIRE_EQ(wprintf(L"%ls\n", ibuf), 2);
+}
+
+ATF_TC(good_big5_swprintf);
+ATF_TC_HEAD(good_big5_swprintf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test good big5 wchar swprintf");
+}
+
+ATF_TC_BODY(good_big5_swprintf, tc)
+{
+ /* XXX implementation detail knowledge (wchar_t encoding) */
+ wchar_t ibuf[] = { 0xcf40, 0 };
+ wchar_t obuf[20];
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+ ATF_REQUIRE_EQ(swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf), 2);
+}
+
+struct ibuf {
+ off_t off;
+ size_t buflen;
+ const char *buf;
+};
+
+static int
+readfn(void *vp, char *buf, int len)
+{
+ struct ibuf *ib = vp;
+ size_t todo = MIN((size_t)len, ib->buflen - ib->off);
+
+ memcpy(buf, ib->buf + ib->off, todo);
+ ib->off += todo;
+ return todo;
+}
+
+ATF_TC(good_big5_getwc);
+ATF_TC_HEAD(good_big5_getwc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test good big5 wchar getwc");
+}
+
+ATF_TC_BODY(good_big5_getwc, tc)
+{
+ const char buf[] = { 0xcf, 0x40 };
+ struct ibuf ib = {
+ .buf = buf,
+ .buflen = sizeof(buf),
+ };
+ FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL);
+
+ ATF_REQUIRE(fp != NULL);
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+ /* XXX implementation detail knowledge (wchar_t encoding) */
+ ATF_REQUIRE_EQ(getwc(fp), 0xcf40);
+ fclose(fp);
+}
+
+ATF_TC(bad_big5_getwc);
+ATF_TC_HEAD(bad_big5_getwc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar getwc");
+}
+
+ATF_TC_BODY(bad_big5_getwc, tc)
+{
+ const char buf[] = { 0xcf, 0x20 };
+ struct ibuf ib = {
+ .buf = buf,
+ .buflen = sizeof(buf),
+ };
+ FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL);
+
+ ATF_REQUIRE(fp != NULL);
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("does not return WEOF as expected");
+#endif
+ ATF_REQUIRE_EQ(getwc(fp), WEOF);
+ fclose(fp);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, bad_big5_wprintf);
+ ATF_TP_ADD_TC(tp, bad_big5_swprintf);
+ ATF_TP_ADD_TC(tp, good_big5_wprintf);
+ ATF_TP_ADD_TC(tp, good_big5_swprintf);
+ ATF_TP_ADD_TC(tp, good_big5_getwc);
+ ATF_TP_ADD_TC(tp, bad_big5_getwc);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c
new file mode 100644
index 0000000..8b3876f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c
@@ -0,0 +1,277 @@
+/* $NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by YAMAMOTO Takashi
+ *
+ * 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 (c)2003 Citrus Project,
+ * 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 AUTHOR 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 AUTHOR 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $");
+
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vis.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+#define SIZE 256
+
+static struct test {
+ const char *locale;
+ const char *data;
+ const wchar_t wchars[64];
+ const wchar_t widths[64];
+ size_t length;
+} tests[] = {
+{
+ "C",
+ "ABCD01234_\\",
+ { 0x41, 0x42, 0x43, 0x44, 0x30, 0x31, 0x32, 0x33, 0x34, 0x5F, 0x5C },
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ 11
+}, {
+ "en_US.UTF-8",
+ "[\001\177][\302\200\337\277][\340\240\200\357\277\277][\360\220\200"
+ "\200\367\277\277\277][\370\210\200\200\200\373\277\277\277\277][\374"
+ "\204\200\200\200\200\375\277\277\277\277\277]",
+ { 0x5b, 0x01, 0x7f, 0x5d, 0x5b, 0x80, 0x7ff, 0x5d, 0x5b, 0x800, 0xffff,
+ 0x5d, 0x5b, 0x10000, 0x1fffff, 0x5d, 0x5b, 0x200000, 0x3ffffff, 0x5d,
+ 0x5b, 0x4000000, 0x7fffffff, 0x5d },
+ { 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 3, 1, 1, 4, 4, 1, 1, 5, 5, 1, 1, 6, 6, 1 },
+ 24
+}, {
+ "ja_JP.ISO2022-JP2",
+ "\033$BF|K\1348l\033(BA\033$B$\"\033(BB\033$B$$\033(B",
+ { 0x4200467c, 0x42004b5c, 0x4200386c, 0x41, 0x42002422, 0x42, 0x42002424 },
+ { 5, 2, 2, 4, 5, 4, 5 },
+ 7
+}, {
+ "ja_JP.SJIS",
+ "\223\372\226{\214\352A\202\240B\202\242",
+ { 0x93fa, 0x967b, 0x8cea, 0x41, 0x82a0, 0x42, 0x82a2 },
+ { 2, 2, 2, 1, 2, 1, 2 },
+ 7
+}, {
+ "ja_JP.eucJP",
+ "\306\374\313\334\270\354A\244\242B\244\244",
+ { 0xc6fc, 0xcbdc, 0xb8ec, 0x41, 0xa4a2, 0x42, 0xa4a4 },
+ { 2, 2, 2, 1, 2, 1, 2 },
+ 7
+}, {
+ NULL,
+ NULL,
+ { },
+ { },
+ 0
+}
+};
+
+static void
+h_ctype2(const struct test *t, bool use_mbstate)
+{
+ mbstate_t *stp;
+ mbstate_t st;
+ char buf[SIZE];
+ char *str;
+ size_t n;
+
+ ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
+#ifdef __NetBSD__
+ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
+#else
+ if (setlocale(LC_CTYPE, t->locale) == NULL) {
+ fprintf(stderr, "Locale %s not found.\n", t->locale);
+ return;
+ }
+#endif
+
+ (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Checking string: \"%s\"\n", buf);
+
+ ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL);
+ (void)printf("Using locale: %s\n", str);
+
+ (void)printf("Using mbstate: %s\n", use_mbstate ? "yes" : "no");
+
+ (void)memset(&st, 0, sizeof(st));
+// mbrtowc(0, 0, 0, &st); /* XXX for ISO2022-JP */
+ stp = use_mbstate ? &st : 0;
+
+ for (n = 9; n > 0; n--) {
+ const char *src = t->data;
+ wchar_t dst;
+ size_t nchar = 0;
+ int width = 0;
+
+ ATF_REQUIRE(mbsinit(stp) != 0);
+
+ for (;;) {
+ size_t rv = mbrtowc(&dst, src, n, stp);
+
+ if (rv == 0)
+ break;
+
+ if (rv == (size_t)-2) {
+ src += n;
+ width += n;
+
+ continue;
+ }
+ if (rv == (size_t)-1) {
+ ATF_REQUIRE_EQ(errno, EILSEQ);
+ atf_tc_fail("Invalid sequence");
+ /* NOTREACHED */
+ }
+
+ width += rv;
+ src += rv;
+
+ if (dst != t->wchars[nchar] ||
+ width != t->widths[nchar]) {
+ (void)printf("At position %zd:\n", nchar);
+ (void)printf(" expected: 0x%04X (%u)\n",
+ t->wchars[nchar], t->widths[nchar]);
+ (void)printf(" got : 0x%04X (%u)\n",
+ dst, width);
+ atf_tc_fail("Test failed");
+ }
+
+ nchar++;
+ width = 0;
+ }
+
+ ATF_REQUIRE_EQ_MSG(dst, 0, "Incorrect terminating character: "
+ "0x%04X (expected: 0x00)", dst);
+
+ ATF_REQUIRE_EQ_MSG(nchar, t->length, "Incorrect length: "
+ "%zd (expected: %zd)", nchar, t->length);
+ }
+
+ {
+ wchar_t wbuf[SIZE];
+ size_t rv;
+ char const *src = t->data;
+ int i;
+
+ (void)memset(wbuf, 0xFF, sizeof(wbuf));
+
+ rv = mbsrtowcs(wbuf, &src, SIZE, stp);
+
+ ATF_REQUIRE_EQ_MSG(rv, t->length, "Incorrect length: %zd "
+ "(expected: %zd)", rv, t->length);
+ ATF_REQUIRE_EQ(src, NULL);
+
+ for (i = 0; wbuf[i] != 0; ++i) {
+ if (wbuf[i] == t->wchars[i])
+ continue;
+
+ (void)printf("At position %d:\n", i);
+ (void)printf(" expected: 0x%04X\n", t->wchars[i]);
+ (void)printf(" got : 0x%04X\n", wbuf[i]);
+ atf_tc_fail("Test failed");
+ }
+
+ ATF_REQUIRE_EQ_MSG((size_t)i, t->length, "Incorrect length: "
+ "%d (expected: %zd)", i, t->length);
+ }
+
+ (void)printf("Ok.\n");
+}
+
+ATF_TC(mbrtowc_internal);
+ATF_TC_HEAD(mbrtowc_internal, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks mbrtowc(3) and mbsrtowcs(3) (using internal "
+ "state) with different locales");
+}
+ATF_TC_BODY(mbrtowc_internal, tc)
+{
+ struct test *t;
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("ja_* locale fails");
+#endif
+ for (t = &tests[0]; t->data != NULL; ++t)
+ h_ctype2(t, false);
+}
+
+ATF_TC(mbrtowc_object);
+ATF_TC_HEAD(mbrtowc_object, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks mbrtowc(3) and mbsrtowcs(3) (using state "
+ "object) with different locales");
+}
+ATF_TC_BODY(mbrtowc_object, tc)
+{
+ struct test *t;
+
+ for (t = &tests[0]; t->data != NULL; ++t)
+ h_ctype2(t, true);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mbrtowc_internal);
+ ATF_TP_ADD_TC(tp, mbrtowc_object);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c b/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c
new file mode 100644
index 0000000..446d7ef
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c
@@ -0,0 +1,98 @@
+/* $NetBSD: t_mbsnrtowcs.c,v 1.2 2014/05/06 00:41:26 yamt Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_mbsnrtowcs.c,v 1.2 2014/05/06 00:41:26 yamt Exp $");
+
+#include <locale.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+static const struct test {
+ const char *locale;
+ const char *data;
+ size_t limit;
+ const wchar_t output1[64];
+ size_t output1_len;
+ const wchar_t output2[64];
+ size_t output2_len;
+} tests[] = {
+ { "C", "ABCD0123", 4, { 0x41, 0x42, 0x43, 0x44 }, 4,
+ { 0x30, 0x31, 0x32, 0x33, 0x0 }, 5 },
+ { "en_US.UTF-8", "ABCD0123", 4, { 0x41, 0x42, 0x43, 0x44 }, 4,
+ { 0x30, 0x31, 0x32, 0x33, 0x0 }, 5 },
+ { "en_US.UTF-8", "ABC\303\2440123", 4, { 0x41, 0x42, 0x43, }, 3,
+ { 0xe4, 0x30, 0x31, 0x32, 0x33, 0x0 }, 6 },
+};
+
+ATF_TC(mbsnrtowcs);
+ATF_TC_HEAD(mbsnrtowcs, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks mbsnrtowc(3) with different locales");
+}
+ATF_TC_BODY(mbsnrtowcs, tc)
+{
+ size_t i;
+ const struct test *t;
+ mbstate_t state;
+ wchar_t buf[64];
+ const char *src;
+ size_t len;
+
+ for (i = 0; i < __arraycount(tests); ++i) {
+ t = &tests[i];
+ ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
+ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
+ memset(&state, 0, sizeof(state));
+ src = t->data;
+ len = mbsnrtowcs(buf, &src, t->limit,
+ __arraycount(buf), &state);
+ ATF_REQUIRE_EQ(src, t->data + t->limit);
+ ATF_REQUIRE_EQ(len, t->output1_len);
+ ATF_REQUIRE(wmemcmp(t->output1, buf, len) == 0);
+ len = mbsnrtowcs(buf, &src, strlen(src) + 1,
+ __arraycount(buf), &state);
+ ATF_REQUIRE_EQ(len, strlen(t->data) - t->limit);
+ ATF_REQUIRE(wmemcmp(t->output2, buf, len + 1) == 0);
+ ATF_REQUIRE_EQ(src, NULL);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mbsnrtowcs);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c
new file mode 100644
index 0000000..f8c06d3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c
@@ -0,0 +1,209 @@
+/* $NetBSD: t_mbstowcs.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 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 (c)2003 Citrus Project,
+ * 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 AUTHOR 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 AUTHOR 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_mbstowcs.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $");
+
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vis.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+#define REQUIRE_ERRNO(x, v) \
+ ATF_REQUIRE_MSG((x) != (v), "%s: %s", #x, strerror(errno))
+
+#define SIZE 256
+
+static struct test {
+ const char *locale;
+ const char *data;
+ wchar_t wchars[64];
+ int widths[64];
+ int width;
+} tests[] = {
+{
+ "en_US.UTF-8",
+ "[\001\177][\302\200\337\277][\340\240\200\357\277\277][\360\220\200"
+ "\200\367\277\277\277][\370\210\200\200\200\373\277\277\277\277][\374"
+ "\204\200\200\200\200\375\277\277\277\277\277]",
+ {
+ 0x5B, 0x01, 0x7F, 0x5D, 0x5B, 0x80, 0x07FF, 0x5D, 0x5B, 0x0800,
+ 0xFFFF, 0x5D, 0x5B, 0x10000, 0x1FFFFF, 0x5D, 0x5B, 0x200000,
+ 0x3FFFFFF, 0x5D, 0x5B, 0x4000000, 0x7FFFFFFF, 0x5D, 0x0A
+ },
+ { 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1,
+ 1, 1, -1, -1, 1, 1, -1, -1, 1, -1
+ },
+ -1
+}, {
+ "ja_JP.ISO2022-JP",
+ "\033$B#J#I#S$G$9!#\033(Baaaa\033$B$\"$$$&$($*\033(B",
+ {
+ 0x4200234A, 0x42002349, 0x42002353, 0x42002447, 0x42002439,
+ 0x42002123, 0x61, 0x61, 0x61, 0x61, 0x42002422, 0x42002424,
+ 0x42002426, 0x42002428, 0x4200242A, 0x0A
+ },
+ { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 },
+ 26
+}, {
+ "ja_JP.SJIS",
+ "\202r\202i\202h\202r\202\305\202\267\201Baaaa\202\240\202\242"
+ "\202\244\202\246\202\250",
+ {
+ 0x8272, 0x8269, 0x8268, 0x8272, 0x82C5, 0x82B7, 0x8142, 0x61,
+ 0x61, 0x61, 0x61, 0x82A0, 0x82A2, 0x82A4, 0x82A6, 0x82A8, 0x0A
+ },
+ { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 },
+ 28
+}, {
+ "ja_JP.eucJP",
+ "\243\305\243\325\243\303\244\307\244\271\241\243aaaa\244\242\244"
+ "\244\244\246\244\250\244\252",
+ {
+ 0xA3C5, 0xA3D5, 0xA3C3, 0xA4C7, 0xA4B9, 0xA1A3, 0x61, 0x61, 0x61,
+ 0x61, 0xA4A2, 0xA4A4, 0xA4A6, 0xA4A8, 0xA4AA, 0x0A
+ },
+ { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 },
+ 26
+}, {
+ NULL,
+ NULL,
+ {},
+ {},
+ 0
+}
+};
+
+ATF_TC(mbstowcs_basic);
+ATF_TC_HEAD(mbstowcs_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks wide character functions with different locales");
+}
+ATF_TC_BODY(mbstowcs_basic, tc)
+{
+ struct test *t;
+
+ for (t = &tests[0]; t->data != NULL; ++t) {
+ wchar_t wbuf[SIZE];
+ char buf[SIZE];
+ char visbuf[SIZE];
+ char *str;
+ int i;
+
+ ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
+#ifdef __NetBSD__
+ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
+#else
+ if (setlocale(LC_CTYPE, t->locale) == NULL) {
+ fprintf(stderr, "Locale %s not found.\n", t->locale);
+ continue;
+ }
+#endif
+
+ (void)strvis(visbuf, t->data, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Checking string: \"%s\"\n", visbuf);
+
+ ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL);
+ (void)printf("Using locale: %s\n", str);
+
+ REQUIRE_ERRNO((ssize_t)mbstowcs(wbuf, t->data, SIZE-1), -1);
+ REQUIRE_ERRNO((ssize_t)wcstombs(buf, wbuf, SIZE-1), -1);
+
+ if (strcmp(buf, t->data) != 0) {
+ (void)strvis(visbuf, buf, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Conversion to wcs and back failed: "
+ "\"%s\"\n", visbuf);
+ atf_tc_fail("Test failed");
+ }
+
+ /* The output here is implementation-dependent. */
+
+ for (i = 0; wbuf[i] != 0; ++i) {
+ if (wbuf[i] == t->wchars[i] &&
+ wcwidth(wbuf[i]) == t->widths[i])
+ continue;
+
+ (void)printf("At position %d:\n", i);
+ (void)printf(" expected: 0x%04X (%d)\n",
+ t->wchars[i], t->widths[i]);
+ (void)printf(" got : 0x%04X (%d)\n", wbuf[i],
+ wcwidth(wbuf[i]));
+ atf_tc_fail("Test failed");
+ }
+
+ if (wcswidth(wbuf, SIZE-1) != t->width) {
+ (void)printf("Incorrect wcswidth:\n");
+ (void)printf(" expected: %d\n", t->width);
+ (void)printf(" got : %d\n", wcswidth(wbuf, SIZE-1));
+ atf_tc_fail("Test failed");
+ }
+
+ (void)printf("Ok.\n");
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, mbstowcs_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c
new file mode 100644
index 0000000..7816260
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c
@@ -0,0 +1,157 @@
+/* $NetBSD: t_mbtowc.c,v 1.1 2011/04/09 17:45:25 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2011 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 (c)2007 Citrus Project,
+ * 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 AUTHOR 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 AUTHOR 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_mbtowc.c,v 1.1 2011/04/09 17:45:25 pgoyette Exp $");
+
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vis.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+static void
+h_mbtowc(const char *locale, const char *illegal, const char *legal)
+{
+ char buf[64];
+ size_t stateful, ret;
+ char *str;
+
+ ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
+#ifdef __NetBSD__
+ ATF_REQUIRE(setlocale(LC_CTYPE, locale) != NULL);
+#else
+ if (setlocale(LC_CTYPE, locale) == NULL) {
+ fprintf(stderr, "Locale %s not found.\n", locale);
+ return;
+ }
+#endif
+
+ ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL);
+ (void)printf("Using locale: %s\n", str);
+
+ stateful = wctomb(NULL, L'\0');
+ (void)printf("Locale is state-%sdependent\n",
+ stateful ? "in" : "");
+
+ /* initialize internal state */
+ ret = mbtowc(NULL, NULL, 0);
+ ATF_REQUIRE(stateful ? ret : !ret);
+
+ (void)strvis(buf, illegal, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Checking illegal sequence: \"%s\"\n", buf);
+
+ ret = mbtowc(NULL, illegal, strlen(illegal));
+ (void)printf("mbtowc() returned: %zd\n", ret);
+ ATF_REQUIRE_EQ(ret, (size_t)-1);
+ (void)printf("errno: %s\n", strerror(errno));
+ ATF_REQUIRE_EQ(errno, EILSEQ);
+
+ /* if this is stateless encoding, this re-initialization is not required. */
+ if (stateful) {
+ /* re-initialize internal state */
+ ret = mbtowc(NULL, NULL, 0);
+ ATF_REQUIRE(stateful ? ret : !ret);
+ }
+
+ /* valid multibyte sequence case */
+ (void)strvis(buf, legal, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Checking legal sequence: \"%s\"\n", buf);
+
+ errno = 0;
+ ret = mbtowc(NULL, legal, strlen(legal));
+ (void)printf("mbtowc() returned: %zd\n", ret);
+ ATF_REQUIRE(ret != (size_t)-1);
+ (void)printf("errno: %s\n", strerror(errno));
+ ATF_REQUIRE_EQ(errno, 0);
+
+ (void)printf("Ok.\n");
+}
+
+ATF_TC(mbtowc);
+ATF_TC_HEAD(mbtowc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks mbtowc(3)");
+}
+ATF_TC_BODY(mbtowc, tc)
+{
+ h_mbtowc("en_US.UTF-8", "\240", "\302\240");
+ h_mbtowc("ja_JP.ISO2022-JP", "\033$B", "\033$B$\"\033(B");
+ h_mbtowc("ja_JP.SJIS", "\202", "\202\240");
+ h_mbtowc("ja_JP.eucJP", "\244", "\244\242");
+#ifndef __FreeBSD__
+ /* Moved last as it fails */
+ h_mbtowc("zh_CN.GB18030", "\241", "\241\241");
+#endif
+ h_mbtowc("zh_TW.Big5", "\241", "\241@");
+ h_mbtowc("zh_TW.eucTW", "\241", "\241\241");
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("zh_CN.GB18030");
+ h_mbtowc("zh_CN.GB18030", "\241", "\241\241");
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, mbtowc);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c b/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c
new file mode 100644
index 0000000..10756b5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c
@@ -0,0 +1,58 @@
+/* $NetBSD: t_wcscspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_wcscspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $");
+
+#include <atf-c.h>
+#include <wchar.h>
+
+ATF_TC(wcscspn);
+ATF_TC_HEAD(wcscspn, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test wcscspn(3)");
+}
+
+ATF_TC_BODY(wcscspn, tc)
+{
+ ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L""), 16);
+ ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"a"), 0);
+ ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"b"), 1);
+ ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"cd"), 2);
+ ATF_CHECK_EQ(wcscspn(L"abcdefghijklmnop", L"qrstuvwxyz"), 16);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, wcscspn);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c b/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c
new file mode 100644
index 0000000..57c1ac5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c
@@ -0,0 +1,62 @@
+/* $NetBSD: t_wcspbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_wcspbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $");
+
+#include <atf-c.h>
+#include <wchar.h>
+
+ATF_TC(wcspbrk);
+ATF_TC_HEAD(wcspbrk, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test wcspbrk(3)");
+}
+
+ATF_TC_BODY(wcspbrk, tc)
+{
+ static const wchar_t s[] = L"abcdefghijklmnop";
+
+ ATF_CHECK_EQ(wcspbrk(s, L""), NULL);
+ ATF_CHECK_EQ(wcspbrk(s, L"qrst"), NULL);
+ ATF_CHECK_EQ(wcspbrk(s, L"a"), s);
+ ATF_CHECK_EQ(wcspbrk(s, L"b"), s + 1);
+ ATF_CHECK_EQ(wcspbrk(s, L"ab"), s);
+ ATF_CHECK_EQ(wcspbrk(s, L"cdef"), s + 2);
+ ATF_CHECK_EQ(wcspbrk(s, L"fedc"), s + 2);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, wcspbrk);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c b/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c
new file mode 100644
index 0000000..2083650
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c
@@ -0,0 +1,60 @@
+/* $NetBSD: t_wcsspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_wcsspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $");
+
+#include <atf-c.h>
+#include <wchar.h>
+
+ATF_TC(wcsspn);
+ATF_TC_HEAD(wcsspn, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test wcsspn(3)");
+}
+
+ATF_TC_BODY(wcsspn, tc)
+{
+ ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L""), 0);
+ ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"a"), 1);
+ ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"b"), 0);
+ ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"ab"), 2);
+ ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abc"), 3);
+ ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abce"), 3);
+ ATF_CHECK_EQ(wcsspn(L"abcdefghijklmnop", L"abcdefghijklmnop"), 16);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, wcsspn);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c
new file mode 100644
index 0000000..8d1ef33
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c
@@ -0,0 +1,460 @@
+/* $NetBSD: t_wcstod.c,v 1.3 2011/10/01 17:56:11 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 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 (c)2005 Citrus Project,
+ * 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 AUTHOR 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 AUTHOR 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_wcstod.c,v 1.3 2011/10/01 17:56:11 christos Exp $");
+
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+#ifdef __FreeBSD__
+#include <stdio.h>
+#endif
+
+#define ALT_HUGE_VAL -1
+#define ALT_MINUS_HUGE_VAL -2
+#define ALT_NAN -3
+
+#if !defined(__vax__)
+static struct test {
+ const wchar_t *wcs;
+ size_t len;
+ double val;
+ int err;
+} tests[] = {
+{ L"IN", 0, 0, 0 },
+{ L"+IN", 0, 0, 0 },
+{ L"-IN", 0, 0, 0 },
+{ L"INX", 0, 0, 0 },
+{ L"+INX", 0, 0, 0 },
+{ L"-INX", 0, 0, 0 },
+{ L"INF", 3, ALT_HUGE_VAL, 0 },
+{ L"+INF", 4, ALT_HUGE_VAL, 0 },
+{ L"-INF", 4, ALT_MINUS_HUGE_VAL, 0 },
+{ L"INFX", 3, ALT_HUGE_VAL, 0 },
+{ L"+INFX", 4, ALT_HUGE_VAL, 0 },
+{ L"-INFX", 4, ALT_MINUS_HUGE_VAL, 0 },
+{ L" IN", 0, 0, 0 },
+{ L" +IN", 0, 0, 0 },
+{ L" -IN", 0, 0, 0 },
+{ L" INX", 0, 0, 0 },
+{ L" +INX", 0, 0, 0 },
+{ L" -INX", 0, 0, 0 },
+{ L"+ INF", 0, 0, 0 },
+{ L"- INF", 0, 0, 0 },
+{ L" INF", 8, ALT_HUGE_VAL, 0 },
+{ L" +INF", 9, ALT_HUGE_VAL, 0 },
+{ L" -INF", 9, ALT_MINUS_HUGE_VAL, 0 },
+{ L" INFX", 8, ALT_HUGE_VAL, 0 },
+{ L" +INFX", 9, ALT_HUGE_VAL, 0 },
+{ L" -INFX", 9, ALT_MINUS_HUGE_VAL, 0 },
+{ L" INFINIT", 8, ALT_HUGE_VAL, 0 },
+{ L" +INFINIT", 9, ALT_HUGE_VAL, 0 },
+{ L" -INFINIT", 9, ALT_MINUS_HUGE_VAL, 0 },
+{ L" INFINITY", 13, ALT_HUGE_VAL, 0 },
+{ L" +INFINITY", 14, ALT_HUGE_VAL, 0 },
+{ L" -INFINITY", 14, ALT_MINUS_HUGE_VAL, 0 },
+{ L" INFINITYX", 13, ALT_HUGE_VAL, 0 },
+{ L" +INFINITYX", 14, ALT_HUGE_VAL, 0 },
+{ L" -INFINITYX", 14, ALT_MINUS_HUGE_VAL, 0 },
+
+/* NAN */
+{ L"NA", 0, 0, 0 },
+{ L"+NA", 0, 0, 0 },
+{ L"-NA", 0, 0, 0 },
+{ L"NAX", 0, 0, 0 },
+{ L"+NAX", 0, 0, 0 },
+{ L"-NAX", 0, 0, 0 },
+{ L"NAN", 3, ALT_NAN, 0 },
+{ L"+NAN", 4, ALT_NAN, 0 },
+{ L"-NAN", 4, ALT_NAN, 0 },
+{ L"NANX", 3, ALT_NAN, 0 },
+{ L"+NANX", 4, ALT_NAN, 0 },
+{ L"-NANX", 4, ALT_NAN, 0 },
+{ L" NA", 0, 0, 0 },
+{ L" +NA", 0, 0, 0 },
+{ L" -NA", 0, 0, 0 },
+{ L" NAX", 0, 0, 0 },
+{ L" +NAX", 0, 0, 0 },
+{ L" -NAX", 0, 0, 0 },
+{ L"+ NAN", 0, 0, 0 },
+{ L"- NAN", 0, 0, 0 },
+{ L" NAN", 8, ALT_NAN, 0 },
+{ L" +NAN", 9, ALT_NAN, 0 },
+{ L" -NAN", 9, ALT_NAN, 0 },
+{ L" NANX", 8, ALT_NAN, 0 },
+{ L" +NANX", 9, ALT_NAN, 0 },
+{ L" -NANX", 9, ALT_NAN, 0 },
+
+{ L"0", 1, 0, 0 },
+{ L"+0", 2, 0, 0 },
+{ L"-0", 2, 0, 0 },
+{ L" 0", 11, 0, 0 },
+{ L" +0", 12, 0, 0 },
+{ L" -0", 12, 0, 0 },
+{ L"+ 0", 0, 0, 0 },
+{ L"- 0", 0, 0, 0 },
+
+{ L".", 0, 0, 0 },
+{ L".0", 2, 0, 0 },
+{ L".00", 3, 0, 0 },
+{ L".000", 4, 0, 0 },
+
+{ L"0.", 2, 0, 0 },
+{ L"+0.", 3, 0, 0 },
+{ L"-0.", 3, 0, 0 },
+{ L" 0.", 12, 0, 0 },
+{ L" +0.", 13, 0, 0 },
+{ L" -0.", 13, 0, 0 },
+
+{ L"0.0", 3, 0, 0 },
+{ L"+0.0", 4, 0, 0 },
+{ L"-0.0", 4, 0, 0 },
+{ L" 0.0", 13, 0, 0 },
+{ L" +0.0", 14, 0, 0 },
+{ L" -0.0", 14, 0, 0 },
+
+{ L"000", 3, 0, 0 },
+{ L"+000", 4, 0, 0 },
+{ L"-000", 4, 0, 0 },
+{ L" 000", 13, 0, 0 },
+{ L" +000", 14, 0, 0 },
+{ L" -000", 14, 0, 0 },
+
+{ L"000.", 4, 0, 0 },
+{ L"+000.", 5, 0, 0 },
+{ L"-000.", 5, 0, 0 },
+{ L" 000.", 14, 0, 0 },
+{ L" +000.", 15, 0, 0 },
+{ L" -000.", 15, 0, 0 },
+
+{ L"000.0", 5, 0, 0 },
+{ L"+000.0", 6, 0, 0 },
+{ L"-000.0", 6, 0, 0 },
+{ L" 000.0", 15, 0, 0 },
+{ L" +000.0", 16, 0, 0 },
+{ L" -000.0", 16, 0, 0 },
+
+
+{ L"0.0.", 3, 0, 0 },
+{ L"+0.0.", 4, 0, 0 },
+{ L"-0.0.", 4, 0, 0 },
+{ L" 0.0.", 13, 0, 0 },
+{ L" +0.0.", 14, 0, 0 },
+{ L" -0.0.", 14, 0, 0 },
+
+{ L"0.0.0", 3, 0, 0 },
+{ L"+0.0.0", 4, 0, 0 },
+{ L"-0.0.0", 4, 0, 0 },
+{ L" 0.0.0", 13, 0, 0 },
+{ L" +0.0.0", 14, 0, 0 },
+{ L" -0.0.0", 14, 0, 0 },
+
+/* XXX: FIXME */
+#if defined(__linux__)
+{ L"0X", 2, 0, 0 },
+{ L"+0X", 3, 0, 0 },
+{ L"-0X", 3, 0, 0 },
+#else
+{ L"0X", 1, 0, 0 },
+{ L"+0X", 2, 0, 0 },
+{ L"-0X", 2, 0, 0 },
+#endif
+
+/* XXX: SunOS 5.8's wcstod(3) doesn't accept hex */
+#if !defined(__SunOS__)
+#if defined(__linux__)
+{ L"0X.", 3, 0, 0 },
+{ L"+0X.", 4, 0, 0 },
+{ L"-0X.", 4, 0, 0 },
+{ L" 0X.", 13, 0, 0 },
+{ L" +0X.", 14, 0, 0 },
+{ L" -0X.", 14, 0, 0 },
+#else
+{ L"0X.", 1, 0, 0 },
+{ L"+0X.", 2, 0, 0 },
+{ L"-0X.", 2, 0, 0 },
+{ L" 0X.", 11, 0, 0 },
+{ L" +0X.", 12, 0, 0 },
+{ L" -0X.", 12, 0, 0 },
+#endif
+/* XXX: FIXME */
+#if defined(__NetBSD__) || defined(__linux__) || defined(__FreeBSD__)
+{ L"0X.0", 4, 0, 0 },
+{ L"+0X.0", 5, 0, 0 },
+{ L"-0X.0", 5, 0, 0 },
+{ L" 0X.0", 14, 0, 0 },
+{ L" +0X.0", 15, 0, 0 },
+{ L" -0X.0", 15, 0, 0 },
+
+{ L"0X.0P", 4, 0, 0 },
+{ L"+0X.0P", 5, 0, 0 },
+{ L"-0X.0P", 5, 0, 0 },
+{ L" 0X.0P", 14, 0, 0 },
+{ L" +0X.0P", 15, 0, 0 },
+{ L" -0X.0P", 15, 0, 0 },
+#else
+{ L"0X.0", 1, 0, 0 },
+{ L"+0X.0", 2, 0, 0 },
+{ L"-0X.0", 2, 0, 0 },
+{ L" 0X.0", 11, 0, 0 },
+{ L" +0X.0", 12, 0, 0 },
+{ L" -0X.0", 12, 0, 0 },
+
+{ L"0X.0P", 1, 0, 0 },
+{ L"+0X.0P", 2, 0, 0 },
+{ L"-0X.0P", 2, 0, 0 },
+{ L" 0X.0P", 11, 0, 0 },
+{ L" +0X.0P", 12, 0, 0 },
+{ L" -0X.0P", 12, 0, 0 },
+#endif
+
+{ L"0X0", 3, 0, 0 },
+{ L"+0X0", 4, 0, 0 },
+{ L"-0X0", 4, 0, 0 },
+{ L" 0X0", 13, 0, 0 },
+{ L" +0X0", 14, 0, 0 },
+{ L" -0X0", 14, 0, 0 },
+
+{ L"00X0.0", 2, 0, 0 },
+{ L"+00X0.0", 3, 0, 0 },
+{ L"-00X0.0", 3, 0, 0 },
+{ L" 00X0.0", 12, 0, 0 },
+{ L" +00X0.0", 13, 0, 0 },
+{ L" -00X0.0", 13, 0, 0 },
+
+{ L"0X0P", 3, 0, 0 },
+{ L"+0X0P", 4, 0, 0 },
+{ L"-0X0P", 4, 0, 0 },
+{ L" 0X0P", 13, 0, 0 },
+{ L" +0X0P", 14, 0, 0 },
+{ L" -0X0P", 14, 0, 0 },
+
+{ L"0X0.", 4, 0, 0 },
+{ L"+0X0.", 5, 0, 0 },
+{ L"-0X0.", 5, 0, 0 },
+{ L" 0X0.", 14, 0, 0 },
+{ L" +0X0.", 15, 0, 0 },
+{ L" -0X0.", 15, 0, 0 },
+
+{ L"0X0.0", 5, 0, 0 },
+{ L"+0X0.0", 6, 0, 0 },
+{ L"-0X0.0", 6, 0, 0 },
+{ L" 0X0.0", 15, 0, 0 },
+{ L" +0X0.0", 16, 0, 0 },
+{ L" -0X0.0", 16, 0, 0 },
+
+{ L"0X0.P", 4, 0, 0 },
+{ L"+0X0.P", 5, 0, 0 },
+{ L"-0X0.P", 5, 0, 0 },
+{ L" 0X0.P", 14, 0, 0 },
+{ L" +0X0.P", 15, 0, 0 },
+{ L" -0X0.P", 15, 0, 0 },
+
+{ L"0X0.P", 4, 0, 0 },
+{ L"+0X0.P", 5, 0, 0 },
+{ L"-0X0.P", 5, 0, 0 },
+{ L" 0X0.P", 14, 0, 0 },
+{ L" +0X0.P", 15, 0, 0 },
+{ L" -0X0.P", 15, 0, 0 },
+
+#endif
+{ L"0.12345678", 10, 0.12345678, 0 },
+{ L"+0.12345678", 11, +0.12345678, 0 },
+{ L"-0.12345678", 11, -0.12345678, 0 },
+{ L" 0.12345678", 15, 0.12345678, 0 },
+{ L" +0.12345678", 16, +0.12345678, 0 },
+{ L" -0.12345678", 16, -0.12345678, 0 },
+
+{ L"0.12345E67", 10, 0.12345E67, 0 },
+{ L"+0.12345E67", 11, +0.12345E67, 0 },
+{ L"-0.12345E67", 11, -0.12345E67, 0 },
+{ L" 0.12345E67", 15, 0.12345E67, 0 },
+{ L" +0.12345E67", 16, +0.12345E67, 0 },
+{ L" -0.12345E67", 16, -0.12345E67, 0 },
+
+{ L"0.12345E+6", 10, 0.12345E+6, 0 },
+{ L"+0.12345E+6", 11, +0.12345E+6, 0 },
+{ L"-0.12345E+6", 11, -0.12345E+6, 0 },
+{ L" 0.12345E+6", 15, 0.12345E+6, 0 },
+{ L" +0.12345E+6", 16, +0.12345E+6, 0 },
+{ L" -0.12345E+6", 16, -0.12345E+6, 0 },
+
+{ L"0.98765E-4", 10, 0.98765E-4, 0 },
+{ L"+0.98765E-4", 11, +0.98765E-4, 0 },
+{ L"-0.98765E-4", 11, -0.98765E-4, 0 },
+{ L" 0.98765E-4", 15, 0.98765E-4, 0 },
+{ L" +0.98765E-4", 16, +0.98765E-4, 0 },
+{ L" -0.98765E-4", 16, -0.98765E-4, 0 },
+
+{ L"12345678E9", 10, 12345678E9, 0 },
+{ L"+12345678E9", 11, +12345678E9, 0 },
+{ L"-12345678E9", 11, -12345678E9, 0 },
+{ L" 12345678E9", 15, 12345678E9, 0 },
+{ L" +12345678E9", 16, +12345678E9, 0 },
+{ L" -12345678E9", 16, -12345678E9, 0 },
+
+/* XXX: SunOS 5.8's wcstod(3) doesn't accept hex */
+#if !defined(__SunOS__)
+{ L"0x1P+2", 6, 4, 0 },
+{ L"+0x1P+2", 7, +4, 0 },
+{ L"-0x1P+2", 7, -4, 0 },
+{ L" 0x1P+2", 11, 4, 0 },
+{ L" +0x1P+2", 12, +4, 0 },
+{ L" -0x1P+2", 12, -4, 0 },
+
+{ L"0x1.0P+2", 8, 4, 0 },
+{ L"+0x1.0P+2", 9, +4, 0 },
+{ L"-0x1.0P+2", 9, -4, 0 },
+{ L" 0x1.0P+2", 13, 4, 0 },
+{ L" +0x1.0P+2", 14, +4, 0 },
+{ L" -0x1.0P+2", 14, -4, 0 },
+
+{ L"0x1P-2", 6, 0.25, 0 },
+{ L"+0x1P-2", 7, +0.25, 0 },
+{ L"-0x1P-2", 7, -0.25, 0 },
+{ L" 0x1P-2", 11, 0.25, 0 },
+{ L" +0x1P-2", 12, +0.25, 0 },
+{ L" -0x1P-2", 12, -0.25, 0 },
+
+{ L"0x1.0P-2", 8, 0.25, 0 },
+{ L"+0x1.0P-2", 9, +0.25, 0 },
+{ L"-0x1.0P-2", 9, -0.25, 0 },
+{ L" 0x1.0P-2", 13, 0.25, 0 },
+{ L" +0x1.0P-2", 14, +0.25, 0 },
+{ L" -0x1.0P-2", 14, -0.25, 0 },
+#endif
+
+{ NULL, 0, 0, 0 }
+};
+#endif /* !defined(__vax__) */
+
+ATF_TC(wcstod);
+ATF_TC_HEAD(wcstod, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks wcstod(3)");
+}
+ATF_TC_BODY(wcstod, tc)
+{
+#if defined(__vax__)
+#else
+ struct test *t;
+#endif
+
+#if !defined(__vax__)
+ for (t = &tests[0]; t->wcs != NULL; ++t) {
+ double d;
+ size_t n;
+ wchar_t *tail;
+ char *buf;
+
+ /* we do not supported %ls nor %S yet. */
+ n = wcstombs(NULL, t->wcs, 0);
+ ATF_REQUIRE((buf = (void *)malloc(n + 1)) != NULL);
+ (void)wcstombs(buf, t->wcs, n + 1);
+ (void)printf("Checking wcstod(\"%s\", &tail):\n", buf);
+ free(buf);
+
+ errno = 0;
+ d = wcstod(t->wcs, &tail);
+ (void)printf("[errno]\n");
+ (void)printf(" got : %s\n", strerror(errno));
+ (void)printf(" expected: %s\n", strerror(t->err));
+ ATF_REQUIRE_EQ(errno, t->err);
+
+ n = (size_t)(tail - t->wcs);
+ (void)printf("[endptr - nptr]\n");
+ (void)printf(" got : %zd\n", n);
+ (void)printf(" expected: %zd\n", t->len);
+ ATF_REQUIRE_EQ(n, t->len);
+
+ (void)printf("[result]\n");
+ (void)printf(" real: %F\n", d);
+ if (t->val == ALT_HUGE_VAL) {
+ (void)printf(" expected: %F\n", HUGE_VAL);
+ ATF_REQUIRE(isinf(d));
+ ATF_REQUIRE_EQ(d, HUGE_VAL);
+ } else if (t->val == ALT_MINUS_HUGE_VAL) {
+ (void)printf(" expected: %F\n", -HUGE_VAL);
+ ATF_REQUIRE(isinf(d));
+ ATF_REQUIRE_EQ(d, -HUGE_VAL);
+ } else if (t->val == ALT_NAN) {
+ (void)printf(" expected: %F\n", NAN);
+ ATF_REQUIRE(isnan(d));
+ } else {
+ (void)printf(" expected: %F\n", t->val);
+ ATF_REQUIRE_EQ(d, t->val);
+ }
+
+ (void)printf("\n");
+ }
+#else /* !defined(__vax__) */
+ atf_tc_skip("Test is unavailable on vax.");
+#endif /* !defined(__vax__) */
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, wcstod);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c
new file mode 100644
index 0000000..3405e97
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c
@@ -0,0 +1,212 @@
+/* $NetBSD: t_wctomb.c,v 1.3 2013/03/25 15:31:03 gson Exp $ */
+
+/*-
+ * Copyright (c) 2011 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 (c)2004 Citrus Project,
+ * 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 AUTHOR 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 AUTHOR 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_wctomb.c,v 1.3 2013/03/25 15:31:03 gson Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <vis.h>
+#include <wchar.h>
+#include <string.h>
+#include <limits.h>
+
+#include <atf-c.h>
+
+#define TC_WCTOMB 0
+#define TC_WCRTOMB 1
+#define TC_WCRTOMB_ST 2
+
+static struct test {
+ const char *locale;
+ const char *data;
+ size_t wclen;
+ size_t mblen[16];
+} tests[] = {
+{
+ "ja_JP.ISO2022-JP",
+ "\x1b$B" /* JIS X 0208-1983 */
+ "\x46\x7c\x4b\x5c\x38\x6c" /* "nihongo" */
+ "\x1b(B" /* ISO 646 */
+ "ABC"
+ "\x1b(I" /* JIS X 0201 katakana */
+ "\xb1\xb2\xb3" /* "aiu" */
+ "\x1b(B", /* ISO 646 */
+ 3 + 3 + 3,
+ { 3+2, 2, 2, 3+1, 1, 1, 3+1, 1, 1, 3+1 }
+}, {
+ "C",
+ "ABC",
+ 3,
+ { 1, 1, 1, 1 }
+}, { NULL, NULL, 0, { } }
+};
+
+static void
+h_wctomb(const struct test *t, char tc)
+{
+ wchar_t wcs[16 + 2];
+ char buf[128];
+ char cs[MB_LEN_MAX];
+ const char *pcs;
+ char *str;
+ mbstate_t st;
+ mbstate_t *stp = NULL;
+ size_t sz, ret, i;
+
+ ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
+#ifdef __NetBSD__
+ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
+#else
+ if (setlocale(LC_CTYPE, t->locale) == NULL) {
+ fprintf(stderr, "Locale %s not found.\n", t->locale);
+ return;
+ }
+#endif
+
+ (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Checking sequence: \"%s\"\n", buf);
+
+ ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL);
+ (void)printf("Using locale: %s\n", str);
+
+ if (tc == TC_WCRTOMB_ST) {
+ (void)memset(&st, 0, sizeof(st));
+ stp = &st;
+ }
+
+ wcs[t->wclen] = L'X'; /* poison */
+ pcs = t->data;
+ sz = mbsrtowcs(wcs, &pcs, t->wclen + 2, NULL);
+ ATF_REQUIRE_EQ_MSG(sz, t->wclen, "mbsrtowcs() returned: "
+ "%zu, expected: %zu", sz, t->wclen);
+ ATF_REQUIRE_EQ(wcs[t->wclen], 0);
+
+ for (i = 0; i < t->wclen + 1; i++) {
+ if (tc == TC_WCTOMB)
+ ret = wctomb(cs, wcs[i]);
+ else
+ ret = wcrtomb(cs, wcs[i], stp);
+
+ if (ret == t->mblen[i])
+ continue;
+
+ (void)printf("At position %zd:\n", i);
+ (void)printf(" expected: %zd\n", t->mblen[i]);
+ (void)printf(" got : %zd\n", ret);
+ atf_tc_fail("Test failed");
+ /* NOTREACHED */
+ }
+
+ (void)printf("Ok.\n");
+}
+
+ATF_TC(wctomb);
+ATF_TC_HEAD(wctomb, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks wctomb(3)");
+}
+ATF_TC_BODY(wctomb, tc)
+{
+ struct test *t;
+
+ (void)printf("Checking wctomb()\n");
+
+ for (t = &tests[0]; t->data != NULL; ++t)
+ h_wctomb(t, TC_WCTOMB);
+}
+
+ATF_TC(wcrtomb_state);
+ATF_TC_HEAD(wcrtomb_state, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks wcrtomb(3) (using state object)");
+}
+ATF_TC_BODY(wcrtomb_state, tc)
+{
+ struct test *t;
+
+ (void)printf("Checking wcrtomb() (with state object)\n");
+
+ for (t = &tests[0]; t->data != NULL; ++t)
+ h_wctomb(t, TC_WCRTOMB_ST);
+}
+
+ATF_TC(wcrtomb);
+ATF_TC_HEAD(wcrtomb, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks wcrtomb(3) (using internal state)");
+}
+ATF_TC_BODY(wcrtomb, tc)
+{
+ struct test *t;
+
+ (void)printf("Checking wcrtomb() (using internal state)\n");
+
+ for (t = &tests[0]; t->data != NULL; ++t)
+ h_wctomb(t, TC_WCRTOMB);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, wctomb);
+ ATF_TP_ADD_TC(tp, wcrtomb);
+ ATF_TP_ADD_TC(tp, wcrtomb_state);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/gen_ether_subr b/contrib/netbsd-tests/lib/libc/net/gen_ether_subr
new file mode 100755
index 0000000..9f9b63c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/gen_ether_subr
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+awk '
+BEGIN {
+ print
+ print "#include <ctype.h>"
+ print "#include <sys/types.h>"
+ print "#include <errno.h>"
+ print
+ print "#define ETHER_ADDR_LEN 6"
+ print
+ print "int ether_aton_r(u_char *dest, size_t len, const char *str);"
+ print
+}
+/^ether_aton_r/ {
+ print prevline
+ out = 1
+}
+{
+ if (out) print
+ else prevline = $0
+}
+/^}$/ {
+ if (out) exit(0)
+}' $1 >$2
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README
new file mode 100644
index 0000000..e856fe7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/README
@@ -0,0 +1,7 @@
+This test may fail if
+
+ - your /etc/services file is not in sync with what this test expects
+ - your /etc/hosts file or DNS have unusual entries for "localhost"
+ (a duplicate "localhost 127.0.0.1" line in /etc/hosts for example)
+
+On kernels without IPv6 support some of the tests are skipped.
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp
new file mode 100644
index 0000000..d2945f2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp
@@ -0,0 +1,36 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp
new file mode 100644
index 0000000..0238f83
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp
@@ -0,0 +1,42 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv http
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv tftp
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv tftp
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv echo
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv echo
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c
new file mode 100644
index 0000000..939fcdb
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c
@@ -0,0 +1,186 @@
+/* $NetBSD: h_gai.c,v 1.1 2011/01/12 02:58:40 pgoyette Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, and 2002 WIDE Project.
+ * 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.
+ * 3. Neither the name of the project 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 PROJECT 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 PROJECT 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 <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+struct addrinfo ai;
+
+char host[NI_MAXHOST];
+char serv[NI_MAXSERV];
+int vflag = 0;
+
+static void usage(void);
+static void print1(const char *, const struct addrinfo *, char *, char *);
+int main(int, char *[]);
+
+static void
+usage()
+{
+ fprintf(stderr, "usage: test [-f family] [-s socktype] [-p proto] [-DPRSv46] host serv\n");
+}
+
+static void
+print1(const char *title, const struct addrinfo *res, char *h, char *s)
+{
+ const char *start, *end;
+ int error;
+ const int niflag = NI_NUMERICHOST;
+
+ if (res->ai_addr) {
+ error = getnameinfo(res->ai_addr, res->ai_addr->sa_len,
+ host, sizeof(host), serv, sizeof(serv),
+ niflag);
+ h = host;
+ s = serv;
+ } else
+ error = 0;
+
+ if (vflag) {
+ start = "\t";
+ end = "\n";
+ } else {
+ start = " ";
+ end = "";
+ }
+ printf("%s%s", title, end);
+ printf("%sflags 0x%x%s", start, res->ai_flags, end);
+ printf("%sfamily %d%s", start, res->ai_family, end);
+ printf("%ssocktype %d%s", start, res->ai_socktype, end);
+ printf("%sprotocol %d%s", start, res->ai_protocol, end);
+ printf("%saddrlen %d%s", start, res->ai_addrlen, end);
+ if (error)
+ printf("%serror %d%s", start, error, end);
+ else {
+ printf("%shost %s%s", start, h, end);
+ printf("%sserv %s%s", start, s, end);
+ }
+#if 0
+ if (res->ai_canonname)
+ printf("%scname \"%s\"%s", start, res->ai_canonname, end);
+#endif
+ if (!vflag)
+ printf("\n");
+
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct addrinfo *res;
+ int error, i;
+ char *p, *q;
+ extern int optind;
+ extern char *optarg;
+ int c;
+ char nbuf[10];
+
+ memset(&ai, 0, sizeof(ai));
+ ai.ai_family = PF_UNSPEC;
+ ai.ai_flags |= AI_CANONNAME;
+ while ((c = getopt(argc, argv, "Df:p:PRs:Sv46")) != -1) {
+ switch (c) {
+ case 'D':
+ ai.ai_socktype = SOCK_DGRAM;
+ break;
+ case 'f':
+ ai.ai_family = atoi(optarg);
+ break;
+ case 'p':
+ ai.ai_protocol = atoi(optarg);
+ break;
+ case 'P':
+ ai.ai_flags |= AI_PASSIVE;
+ break;
+ case 'R':
+ ai.ai_socktype = SOCK_RAW;
+ break;
+ case 's':
+ ai.ai_socktype = atoi(optarg);
+ break;
+ case 'S':
+ ai.ai_socktype = SOCK_STREAM;
+ break;
+ case 'v':
+ vflag++;
+ break;
+ case '4':
+ ai.ai_family = PF_INET;
+ break;
+ case '6':
+ ai.ai_family = PF_INET6;
+ break;
+ default:
+ usage();
+ exit(1);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 2){
+ usage();
+ exit(1);
+ }
+
+ p = *argv[0] ? argv[0] : NULL;
+ q = *argv[1] ? argv[1] : NULL;
+
+ strncpy(nbuf, "(empty)", sizeof(nbuf));
+ print1("arg:", &ai, p ? p : nbuf , q ? q : nbuf);
+
+ error = getaddrinfo(p, q, &ai, &res);
+ if (error) {
+ printf("%s\n", gai_strerror(error));
+ exit(1);
+ }
+
+ i = 1;
+ do {
+ snprintf(nbuf, sizeof(nbuf), "ai%d:", i);
+ print1(nbuf, res, NULL, NULL);
+
+ i++;
+ } while ((res = res->ai_next) != NULL);
+ printf("\n");
+
+ exit(0);
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp
new file mode 100644
index 0000000..21059c7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp
@@ -0,0 +1,38 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo
+ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp
+ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai2: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp
new file mode 100644
index 0000000..7d30fea
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp
@@ -0,0 +1,56 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv echo
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv echo
+ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv echo
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv echo
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv tftp
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv tftp
+ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv tftp
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv tftp
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai3: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv http
+ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv http
+ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv http
+ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv echo
+ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv echo
+ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv echo
+ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv echo
+ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv echo
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv tftp
+ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv tftp
+ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv tftp
+ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv tftp
+ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv tftp
+
+arg: flags 0x3 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x3 family 24 socktype 2 protocol 17 addrlen 28 host :: serv http
+ai2: flags 0x3 family 24 socktype 1 protocol 6 addrlen 28 host :: serv http
+ai3: flags 0x3 family 2 socktype 2 protocol 17 addrlen 16 host 0.0.0.0 serv http
+ai4: flags 0x3 family 2 socktype 1 protocol 6 addrlen 16 host 0.0.0.0 serv http
+
+arg: flags 0x2 family 0 socktype 1 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 0 socktype 2 protocol 0 addrlen 0 host (empty) serv 80
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp
new file mode 100644
index 0000000..9de5c56
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp
@@ -0,0 +1,14 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty)
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty)
+hostname nor servname provided, or not known
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp
new file mode 100644
index 0000000..1df5663
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp
@@ -0,0 +1,16 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host 127.0.0.1 serv (empty)
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv 0
+ai3: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv 0
+ai4: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host (empty) serv (empty)
+hostname nor servname provided, or not known
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp
new file mode 100644
index 0000000..d06d163
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp
@@ -0,0 +1,4 @@
+arg: flags 0x2 family 0 socktype 0 protocol 0 addrlen 0 host fe80::1%lo0 serv http
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host fe80::1%lo0 serv http
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host fe80::1%lo0 serv http
+
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp
new file mode 100644
index 0000000..bc850e0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp
@@ -0,0 +1,13 @@
+arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80
+servname not supported for ai_socktype
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www
+servname not supported for ai_socktype
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0
+
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp
new file mode 100644
index 0000000..a4f2fb8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp
@@ -0,0 +1,15 @@
+arg: flags 0x2 family 0 socktype 3 protocol 0 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 24 socktype 3 protocol 0 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 2 socktype 3 protocol 0 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv (empty)
+ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0
+ai2: flags 0x2 family 2 socktype 3 protocol 59 addrlen 16 host 127.0.0.1 serv 0
+
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv 80
+servname not supported for ai_socktype
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host localhost serv www
+servname not supported for ai_socktype
+arg: flags 0x2 family 0 socktype 3 protocol 59 addrlen 0 host ::1 serv (empty)
+ai1: flags 0x2 family 24 socktype 3 protocol 59 addrlen 28 host ::1 serv 0
+
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp
new file mode 100644
index 0000000..1c0ce43
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp
@@ -0,0 +1,6 @@
+arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 24 socktype 0 protocol 0 addrlen 0 host localhost serv http
+No address associated with hostname
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp
new file mode 100644
index 0000000..e24036e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp
@@ -0,0 +1,8 @@
+arg: flags 0x2 family 2 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 2 socktype 2 protocol 17 addrlen 16 host 127.0.0.1 serv http
+ai2: flags 0x2 family 2 socktype 1 protocol 6 addrlen 16 host 127.0.0.1 serv http
+
+arg: flags 0x2 family 24 socktype 0 protocol 0 addrlen 0 host localhost serv http
+ai1: flags 0x2 family 24 socktype 2 protocol 17 addrlen 28 host ::1 serv http
+ai2: flags 0x2 family 24 socktype 1 protocol 6 addrlen 28 host ::1 serv http
+
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh
new file mode 100755
index 0000000..94a3c0b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh
@@ -0,0 +1,198 @@
+# $NetBSD: t_getaddrinfo.sh,v 1.2 2011/06/15 07:54:32 jmmv Exp $
+
+#
+# Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, and 2002 WIDE Project.
+# 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.
+# 3. Neither the name of the project 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 PROJECT 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 PROJECT 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_output()
+{
+ if [ "$2" = "none" ] ; then
+ exp="${1}.exp"
+ elif [ "$2" = "hosts" ] ; then
+ # Determine if localhost has an IPv6 address or not
+ lcl=$( cat /etc/hosts | \
+ sed -e 's/#.*$//' -e 's/[ ][ ]*/ /g' | \
+ awk '/ localhost($| )/ {printf "%s ", $1}' )
+ if [ "${lcl%*::*}" = "${lcl}" ] ; then
+ exp="${1}_v4.exp"
+ else
+ exp="${1}_v4v6.exp"
+ fi
+ elif [ "$2" = "ifconfig" ] ; then
+ lcl=$( ifconfig lo0 | grep inet6 )
+ if [ -n "${lcl}" ] ; then
+ exp="${1}_v4v6.exp"
+ else
+ exp="${1}_v4.exp"
+ fi
+ else
+ atf_fail "Invalid family_match_type $2 requested."
+ fi
+
+ cmp -s $(atf_get_srcdir)/data/${exp} out && return
+ diff -u $(atf_get_srcdir)/data/${exp} out && \
+ atf_fail "Actual output does not match expected output"
+}
+
+atf_test_case basic
+basic_head()
+{
+ atf_set "descr" "Testing basic ones"
+}
+basic_body()
+{
+ TEST=$(atf_get_srcdir)/h_gai
+
+ ( $TEST ::1 http
+ $TEST 127.0.0.1 http
+ $TEST localhost http
+ $TEST ::1 tftp
+ $TEST 127.0.0.1 tftp
+ $TEST localhost tftp
+ $TEST ::1 echo
+ $TEST 127.0.0.1 echo
+ $TEST localhost echo ) > out 2>&1
+
+ check_output basics hosts
+}
+
+atf_test_case specific
+specific_head()
+{
+ atf_set "descr" "Testing specific address family"
+}
+specific_body()
+{
+ TEST=$(atf_get_srcdir)/h_gai
+
+ ( $TEST -4 localhost http
+ $TEST -6 localhost http ) > out 2>&1
+
+ check_output spec_fam hosts
+}
+
+atf_test_case empty_hostname
+empty_hostname_head()
+{
+ atf_set "descr" "Testing empty hostname"
+}
+empty_hostname_body()
+{
+ TEST=$(atf_get_srcdir)/h_gai
+
+ ( $TEST '' http
+ $TEST '' echo
+ $TEST '' tftp
+ $TEST '' 80
+ $TEST -P '' http
+ $TEST -P '' echo
+ $TEST -P '' tftp
+ $TEST -P '' 80
+ $TEST -S '' 80
+ $TEST -D '' 80 ) > out 2>&1
+
+ check_output no_host ifconfig
+}
+
+atf_test_case empty_servname
+empty_servname_head()
+{
+ atf_set "descr" "Testing empty service name"
+}
+empty_servname_body()
+{
+ TEST=$(atf_get_srcdir)/h_gai
+
+ ( $TEST ::1 ''
+ $TEST 127.0.0.1 ''
+ $TEST localhost ''
+ $TEST '' '' ) > out 2>&1
+
+ check_output no_serv hosts
+}
+
+atf_test_case sock_raw
+sock_raw_head()
+{
+ atf_set "descr" "Testing raw socket"
+}
+sock_raw_body()
+{
+ TEST=$(atf_get_srcdir)/h_gai
+
+ ( $TEST -R -p 0 localhost ''
+ $TEST -R -p 59 localhost ''
+ $TEST -R -p 59 localhost 80
+ $TEST -R -p 59 localhost www
+ $TEST -R -p 59 ::1 '' ) > out 2>&1
+
+ check_output sock_raw hosts
+}
+
+atf_test_case unsupported_family
+unsupported_family_head()
+{
+ atf_set "descr" "Testing unsupported family"
+}
+unsupported_family_body()
+{
+ TEST=$(atf_get_srcdir)/h_gai
+
+ ( $TEST -f 99 localhost '' ) > out 2>&1
+
+ check_output unsup_fam none
+}
+
+atf_test_case scopeaddr
+scopeaddr_head()
+{
+ atf_set "descr" "Testing scoped address format"
+}
+scopeaddr_body()
+{
+ TEST=$(atf_get_srcdir)/h_gai
+
+ ( $TEST fe80::1%lo0 http
+# IF=`ifconfig -a | grep -v '^ ' | \
+# sed -e 's/:.*//' | head -1 | awk '{print $1}'`
+# $TEST fe80::1%$IF http
+ ) > out 2>&1
+
+ check_output scoped none
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case basic
+ atf_add_test_case specific
+ atf_add_test_case empty_hostname
+ atf_add_test_case empty_servname
+ atf_add_test_case sock_raw
+ atf_add_test_case unsupported_family
+ atf_add_test_case scopeaddr
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp
new file mode 100644
index 0000000..b6133c0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp
@@ -0,0 +1,2 @@
+arg: flags 0x2 family 99 socktype 0 protocol 0 addrlen 0 host localhost serv (empty)
+ai_family not supported
diff --git a/contrib/netbsd-tests/lib/libc/net/h_dns_server.c b/contrib/netbsd-tests/lib/libc/net/h_dns_server.c
new file mode 100644
index 0000000..a8f0caa
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/h_dns_server.c
@@ -0,0 +1,415 @@
+/* $NetBSD: h_dns_server.c,v 1.4 2014/03/29 16:10:54 gson Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andreas Gustafsson.
+ *
+ * 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.
+ */
+
+/*
+ * A minimal DNS server capable of providing canned answers to the
+ * specific queries issued by t_hostent.sh and nothing more.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: h_dns_server.c,v 1.4 2014/03/29 16:10:54 gson Exp $");
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#ifdef __NetBSD__
+#include <netinet6/in6.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <paths.h>
+#endif
+
+union sockaddr_either {
+ struct sockaddr s;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+};
+
+#ifdef DEBUG
+#define DPRINTF(...) fprintf(stderr, __VA_ARGS__)
+#else
+#define DPRINTF(...)
+#endif
+
+/* A DNS question and its corresponding answer */
+
+struct dns_data {
+ size_t qname_size;
+ const char *qname; /* Wire-encode question name */
+ int qtype;
+ size_t answer_size;
+ const char *answer; /* One wire-encoded answer RDATA */
+};
+
+/* Convert C string constant to length + data pair */
+#define STR_DATA(s) sizeof(s) - 1, s
+
+/* Canned DNS queestion-answer pairs */
+struct dns_data data[] = {
+ /* Forward mappings */
+ /* localhost IN A -> 127.0.0.1 */
+ { STR_DATA("\011localhost\000"), 1,
+ STR_DATA("\177\000\000\001") },
+ /* localhost IN AAAA -> ::1 */
+ { STR_DATA("\011localhost\000"), 28,
+ STR_DATA("\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001") },
+ /* sixthavenue.astron.com IN A -> 38.117.134.16 */
+ { STR_DATA("\013sixthavenue\006astron\003com\000"), 1,
+ STR_DATA("\046\165\206\020") },
+ /* sixthavenue.astron.com IN AAAA -> 2620:106:3003:1f00:3e4a:92ff:fef4:e180 */
+ { STR_DATA("\013sixthavenue\006astron\003com\000"), 28,
+ STR_DATA("\x26\x20\x01\x06\x30\x03\x1f\x00\x3e\x4a\x92\xff\xfe\xf4\xe1\x80") },
+ /* Reverse mappings */
+ { STR_DATA("\0011\0010\0010\003127\007in-addr\004arpa\000"), 12,
+ STR_DATA("\011localhost\000") },
+ { STR_DATA("\0011\0010\0010\0010\0010\0010\0010\0010"
+ "\0010\0010\0010\0010\0010\0010\0010\0010"
+ "\0010\0010\0010\0010\0010\0010\0010\0010"
+ "\0010\0010\0010\0010\0010\0010\0010\0010"
+ "\003ip6\004arpa\000"), 12,
+ STR_DATA("\011localhost\000") },
+ { STR_DATA("\00216\003134\003117\00238"
+ "\007in-addr\004arpa\000"), 12,
+ STR_DATA("\013sixthavenue\006astron\003com\000") },
+ { STR_DATA("\0010\0018\0011\001e\0014\001f\001e\001f"
+ "\001f\001f\0012\0019\001a\0014\001e\0013"
+ "\0010\0010\001f\0011\0013\0010\0010\0013"
+ "\0016\0010\0011\0010\0010\0012\0016\0012"
+ "\003ip6\004arpa\000"), 12,
+ STR_DATA("\013sixthavenue\006astron\003com\000") },
+ /* End marker */
+ { STR_DATA(""), 0, STR_DATA("") }
+};
+
+/*
+ * Compare two DNS names for equality. If equal, return their
+ * length, and if not, return zero. Does not handle compression.
+ */
+static int
+name_eq(const unsigned char *a, const unsigned char *b) {
+ const unsigned char *a_save = a;
+ for (;;) {
+ int i;
+ int lena = *a++;
+ int lenb = *b++;
+ if (lena != lenb)
+ return 0;
+ if (lena == 0)
+ return a - a_save;
+ for (i = 0; i < lena; i++)
+ if (tolower(a[i]) != tolower(b[i]))
+ return 0;
+ a += lena;
+ b += lena;
+ }
+}
+
+#ifdef DEBUG
+static char *
+name2str(const void *v, char *buf, size_t buflen) {
+ const unsigned char *a = v;
+ char *b = buf;
+ char *eb = buf + buflen;
+
+#define ADDC(c) do { \
+ if (b < eb) \
+ *b++ = c; \
+ else \
+ return NULL; \
+ } while (/*CONSTCOND*/0)
+ for (int did = 0;; did++) {
+ int lena = *a++;
+ if (lena == 0) {
+ ADDC('\0');
+ return buf;
+ }
+ if (did)
+ ADDC('.');
+ for (int i = 0; i < lena; i++)
+ ADDC(a[i]);
+ a += lena;
+ }
+}
+#endif
+
+#ifdef __FreeBSD__
+/* XXX the daemon2_* functions should be in a library */
+
+int __daemon2_detach_pipe[2];
+
+static int
+daemon2_fork(void)
+{
+ int r;
+ int fd;
+ int i;
+
+ /*
+ * Set up the pipe, making sure the write end does not
+ * get allocated one of the file descriptors that will
+ * be closed in daemon2_detach().
+ */
+ for (i = 0; i < 3; i++) {
+ r = pipe(__daemon2_detach_pipe);
+ if (r < 0)
+ return -1;
+ if (__daemon2_detach_pipe[1] <= STDERR_FILENO &&
+ (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+ (void)dup2(fd, __daemon2_detach_pipe[0]);
+ (void)dup2(fd, __daemon2_detach_pipe[1]);
+ if (fd > STDERR_FILENO)
+ (void)close(fd);
+ continue;
+ }
+ break;
+ }
+
+ r = fork();
+ if (r < 0) {
+ return -1;
+ } else if (r == 0) {
+ /* child */
+ close(__daemon2_detach_pipe[0]);
+ return 0;
+ }
+ /* Parent */
+
+ (void) close(__daemon2_detach_pipe[1]);
+
+ for (;;) {
+ char dummy;
+ r = read(__daemon2_detach_pipe[0], &dummy, 1);
+ if (r < 0) {
+ if (errno == EINTR)
+ continue;
+ _exit(1);
+ } else if (r == 0) {
+ _exit(1);
+ } else { /* r > 0 */
+ _exit(0);
+ }
+ }
+}
+
+static int
+daemon2_detach(int nochdir, int noclose)
+{
+ int r;
+ int fd;
+
+ if (setsid() == -1)
+ return -1;
+
+ if (!nochdir)
+ (void)chdir("/");
+
+ if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+ (void)dup2(fd, STDIN_FILENO);
+ (void)dup2(fd, STDOUT_FILENO);
+ (void)dup2(fd, STDERR_FILENO);
+ if (fd > STDERR_FILENO)
+ (void)close(fd);
+ }
+
+ while (1) {
+ r = write(__daemon2_detach_pipe[1], "", 1);
+ if (r < 0) {
+ if (errno == EINTR)
+ continue;
+ /* May get "broken pipe" here if parent is killed */
+ return -1;
+ } else if (r == 0) {
+ /* Should not happen */
+ return -1;
+ } else {
+ break;
+ }
+ }
+
+ (void) close(__daemon2_detach_pipe[1]);
+
+ return 0;
+}
+#endif
+
+int main(int argc, char **argv) {
+ int s, r, protocol;
+ union sockaddr_either saddr;
+ struct dns_data *dp;
+ unsigned char *p;
+ char pidfile_name[40];
+ FILE *f;
+ int one = 1;
+#ifdef DEBUG
+ char buf1[1024], buf2[1024];
+#endif
+
+#ifdef __FreeBSD__
+ daemon2_fork();
+#endif
+ if (argc < 2 || ((protocol = argv[1][0]) != '4' && protocol != '6'))
+ errx(1, "usage: dns_server 4 | 6");
+ s = socket(protocol == '4' ? PF_INET : PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (s < 0)
+ err(1, "socket");
+ if (protocol == '4') {
+ memset(&saddr.sin, 0, sizeof(saddr.sin));
+ saddr.sin.sin_family = AF_INET;
+ saddr.sin.sin_len = sizeof(saddr.sin);
+ saddr.sin.sin_port = htons(53);
+ saddr.sin.sin_addr.s_addr = INADDR_ANY;
+ } else {
+ static struct in6_addr loopback = IN6ADDR_LOOPBACK_INIT;
+ memset(&saddr.sin6, 0, sizeof(saddr.sin6));
+ saddr.sin6.sin6_family = AF_INET6;
+ saddr.sin6.sin6_len = sizeof(saddr.sin6);
+ saddr.sin6.sin6_port = htons(53);
+ saddr.sin6.sin6_addr = loopback;
+ }
+
+ r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
+ if (r < 0)
+ err(1, "setsockopt");
+
+ r = bind(s,
+ (struct sockaddr *) &saddr,
+ protocol == '4' ? sizeof(struct sockaddr_in) :
+ sizeof(struct sockaddr_in6));
+ if (r < 0)
+ err(1, "bind");
+
+ snprintf(pidfile_name, sizeof pidfile_name,
+ "dns_server_%c.pid", protocol);
+ f = fopen(pidfile_name, "w");
+ fprintf(f, "%d", getpid());
+ fclose(f);
+#ifdef __FreeBSD__
+#ifdef DEBUG
+ daemon2_detach(0, 1);
+#else
+ daemon2_detach(0, 0);
+#endif
+#else
+#ifdef DEBUG
+ daemon(0, 1);
+#else
+ daemon(0, 0);
+#endif
+#endif
+
+ for (;;) {
+ unsigned char buf[512];
+ union sockaddr_either from;
+ ssize_t nrecv, nsent;
+ socklen_t fromlen =
+ protocol == '4' ? sizeof(struct sockaddr_in) :
+ sizeof(struct sockaddr_in6);
+ memset(buf, 0, sizeof buf);
+ nrecv = recvfrom(s, buf, sizeof buf, 0, &from.s, &fromlen);
+ if (nrecv < 0)
+ err(1, "recvfrom");
+ if (nrecv < 12) {
+ DPRINTF("Too short %zd\n", nrecv);
+ continue;
+ }
+ if ((buf[2] & 0x80) != 0) {
+ DPRINTF("Not a query 0x%x\n", buf[2]);
+ continue;
+ }
+ if (!(buf[4] == 0 && buf[5] == 1)) {
+ DPRINTF("QCOUNT is not 1 0x%x 0x%x\n", buf[4], buf[5]);
+ continue; /* QDCOUNT is not 1 */
+ }
+
+ for (dp = data; dp->qname_size != 0; dp++) {
+ int qtype, qclass;
+ p = buf + 12; /* Point to QNAME */
+ int n = name_eq(p, (const unsigned char *) dp->qname);
+ if (n == 0) {
+ DPRINTF("no match name %s != %s\n",
+ name2str(p, buf1, sizeof(buf1)),
+ name2str(dp->qname, buf2, sizeof(buf2)));
+ continue; /* Name does not match */
+ }
+ DPRINTF("match name %s\n",
+ name2str(p, buf1, sizeof(buf1)));
+ p += n; /* Skip QNAME */
+ qtype = *p++ << 8;
+ qtype |= *p++;
+ if (qtype != dp->qtype) {
+ DPRINTF("no match name 0x%x != 0x%x\n",
+ qtype, dp->qtype);
+ continue;
+ }
+ DPRINTF("match type 0x%x\n", qtype);
+ qclass = *p++ << 8;
+ qclass |= *p++;
+ if (qclass != 1) { /* IN */
+ DPRINTF("no match class %d != 1\n", qclass);
+ continue;
+ }
+ DPRINTF("match class %d\n", qclass);
+ goto found;
+ }
+ continue;
+ found:
+ buf[2] |= 0x80; /* QR */
+ buf[3] |= 0x80; /* RA */
+ memset(buf + 6, 0, 6); /* Clear ANCOUNT, NSCOUNT, ARCOUNT */
+ buf[7] = 1; /* ANCOUNT */
+ memcpy(p, dp->qname, dp->qname_size);
+ p += dp->qname_size;
+ *p++ = dp->qtype >> 8;
+ *p++ = dp->qtype & 0xFF;
+ *p++ = 0;
+ *p++ = 1; /* IN */
+ memset(p, 0, 4); /* TTL = 0 */
+ p += 4;
+ *p++ = 0; /* RDLENGTH MSB */
+ *p++ = dp->answer_size; /* RDLENGTH LSB */
+ memcpy(p, dp->answer, dp->answer_size);
+ p += dp->answer_size;
+ nsent = sendto(s, buf, p - buf, 0, &from.s, fromlen);
+ DPRINTF("sent %zd\n", nsent);
+ if (nsent != p - buf)
+ warn("sendto");
+ }
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/h_hostent.c b/contrib/netbsd-tests/lib/libc/net/h_hostent.c
new file mode 100644
index 0000000..4a72923
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/h_hostent.c
@@ -0,0 +1,195 @@
+/* $NetBSD: h_hostent.c,v 1.2 2014/01/09 02:18:10 christos Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: h_hostent.c,v 1.2 2014/01/09 02:18:10 christos Exp $");
+
+#include <stdio.h>
+#include <string.h>
+#include <nsswitch.h>
+#include <netdb.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include "hostent.h"
+
+extern const char *__res_conf_name;
+
+static void
+phostent(const struct hostent *h)
+{
+ size_t i;
+ char buf[1024];
+ const int af = h->h_length == NS_INADDRSZ ? AF_INET : AF_INET6;
+
+ printf("name=%s, length=%d, addrtype=%d, aliases=[",
+ h->h_name, h->h_length, h->h_addrtype);
+
+ for (i = 0; h->h_aliases[i]; i++)
+ printf("%s%s", i == 0 ? "" : " ", h->h_aliases[i]);
+
+ printf("] addr_list=[");
+
+ for (i = 0; h->h_addr_list[i]; i++)
+ printf("%s%s", i == 0 ? "" : " ", inet_ntop(af,
+ h->h_addr_list[i], buf, (socklen_t)sizeof(buf)));
+
+ printf("]\n");
+}
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr, "Usage: %s [-f <hostsfile>] "
+ "[-t <any|dns|nis|files>] "
+ "[-46a] <name|address>\n", getprogname());
+ exit(EXIT_FAILURE);
+}
+
+static void
+getby(int (*f)(void *, void *, va_list), struct getnamaddr *info, ...)
+{
+ va_list ap;
+ int e;
+
+ va_start(ap, info);
+ e = (*f)(info, NULL, ap);
+ va_end(ap);
+ switch (e) {
+ case NS_SUCCESS:
+ phostent(info->hp);
+ break;
+ default:
+ printf("error %d\n", e);
+ break;
+ }
+}
+
+static void
+geta(struct hostent *hp) {
+ if (hp == NULL)
+ printf("error %d\n", h_errno);
+ else
+ phostent(hp);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int (*f)(void *, void *, va_list) = NULL;
+ const char *type = "any";
+ int c, af, e, byaddr, len;
+ struct hostent hent;
+ struct getnamaddr info;
+ char buf[4096];
+
+ af = AF_INET;
+ byaddr = 0;
+ len = 0;
+ info.hp = &hent;
+ info.buf = buf;
+ info.buflen = sizeof(buf);
+ info.he = &e;
+
+ while ((c = getopt(argc, argv, "46af:r:t:")) != -1) {
+ switch (c) {
+ case '4':
+ af = AF_INET;
+ break;
+ case '6':
+ af = AF_INET6;
+ break;
+ case 'a':
+ byaddr++;
+ break;
+ case 'f':
+ _hf_sethostsfile(optarg);
+ break;
+ case 'r':
+ __res_conf_name = optarg;
+ break;
+ case 't':
+ type = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1)
+ usage();
+
+ switch (*type) {
+ case 'a':
+ break;
+ case 'd':
+ f = byaddr ? _dns_gethtbyaddr : _dns_gethtbyname;
+ break;
+#ifdef YP
+ case 'n':
+ f = byaddr ? _yp_gethtbyaddr : _yp_gethtbyname;
+ break;
+#endif
+ case 'f':
+ f = byaddr ? _hf_gethtbyaddr : _hf_gethtbyname;
+ break;
+ default:
+ errx(EXIT_FAILURE, "Unknown db type `%s'", type);
+ }
+
+ if (byaddr) {
+ struct in6_addr addr;
+ af = strchr(*argv, ':') ? AF_INET6 : AF_INET;
+ len = af == AF_INET ? NS_INADDRSZ : NS_IN6ADDRSZ;
+ if (inet_pton(af, *argv, &addr) == -1)
+ err(EXIT_FAILURE, "Can't parse `%s'", *argv);
+ if (*type == 'a')
+ geta(gethostbyaddr((const char *)&addr, len, af));
+ else
+ getby(f, &info, &addr, len, af);
+ } else {
+ if (*type == 'a')
+ geta(gethostbyname2(*argv, af));
+ else
+ getby(f, &info, *argv, len, af);
+ }
+
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c b/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c
new file mode 100644
index 0000000..2f315d2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c
@@ -0,0 +1,107 @@
+/* $NetBSD: h_nsd_recurse.c,v 1.2 2011/01/13 02:24:51 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_nsd_recurse.c,v 1.2 2011/01/13 02:24:51 pgoyette Exp $");
+
+#define _REENTRANT
+
+#include <assert.h>
+#include <nsswitch.h>
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static const ns_src testsrc[] = {
+ { "test", NS_SUCCESS },
+ { NULL, 0 }
+};
+
+static int
+func3(void *rv, void *cb_data, va_list ap)
+{
+ (void)printf("func3: enter\n");
+ (void)printf("func3: exit\n");
+
+ return NS_SUCCESS;
+}
+
+static int
+func2(void *rv, void *cb_data, va_list ap)
+{
+ static const ns_dtab dtab[] = {
+ { "test", func3, NULL },
+ { NULL, NULL, NULL }
+ };
+ int r;
+
+ (void)printf("func2: enter\n");
+ r = nsdispatch(NULL, dtab, "test", "test", testsrc);
+ (void)printf("func2: exit\n");
+
+ return r;
+}
+
+static int
+func1(void)
+{
+ static const ns_dtab dtab[] = {
+ { "test", func2, NULL },
+ { NULL, NULL, NULL }
+ };
+ int r;
+
+ (void)printf("func1: enter\n");
+ r = nsdispatch(NULL, dtab, "test", "test", testsrc);
+ (void)printf("func1: exit\n");
+
+ return r;
+}
+
+static void *
+thrfunc(void *arg)
+{
+ pthread_exit(NULL);
+}
+
+int
+main(int argc, char *argv[])
+{
+ pthread_t thr;
+ void *threval;
+
+ assert(pthread_create(&thr, NULL, thrfunc, NULL) == 0);
+ assert(func1() == NS_SUCCESS);
+ assert(pthread_join(thr, &threval) == 0);
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/h_protoent.c b/contrib/netbsd-tests/lib/libc/net/h_protoent.c
new file mode 100644
index 0000000..f37a85c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/h_protoent.c
@@ -0,0 +1,97 @@
+/* $NetBSD: h_protoent.c,v 1.2 2011/04/07 18:14:09 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 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 <netdb.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+static void
+pserv(const struct protoent *prp)
+{
+ char **pp;
+
+ printf("name=%s, proto=%d, aliases=",
+ prp->p_name, prp->p_proto);
+ for (pp = prp->p_aliases; *pp; pp++)
+ printf("%s ", *pp);
+ printf("\n");
+}
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr, "Usage: %s\n"
+ "\t%s -p <proto>\n"
+ "\t%s -n <name>\n", getprogname(), getprogname(),
+ getprogname());
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct protoent *prp;
+ const char *proto = NULL, *name = NULL;
+ int c;
+
+ while ((c = getopt(argc, argv, "p:n:")) != -1) {
+ switch (c) {
+ case 'n':
+ name = optarg;
+ break;
+ case 'p':
+ proto = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (proto && name)
+ usage();
+ if (proto) {
+ if ((prp = getprotobynumber(atoi(proto))) != NULL)
+ pserv(prp);
+ return 0;
+ }
+ if (name) {
+ if ((prp = getprotobyname(name)) != NULL)
+ pserv(prp);
+ return 0;
+ }
+
+ setprotoent(0);
+ while ((prp = getprotoent()) != NULL)
+ pserv(prp);
+ endprotoent();
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/h_servent.c b/contrib/netbsd-tests/lib/libc/net/h_servent.c
new file mode 100644
index 0000000..6d7efd8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/h_servent.c
@@ -0,0 +1,100 @@
+/* $NetBSD: h_servent.c,v 1.2 2011/04/07 18:14:09 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 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 <netdb.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <stdio.h>
+
+static void
+pserv(const struct servent *svp)
+{
+ char **pp;
+
+ printf("name=%s, port=%d, proto=%s, aliases=",
+ svp->s_name, ntohs((uint16_t)svp->s_port), svp->s_proto);
+ for (pp = svp->s_aliases; *pp; pp++)
+ printf("%s ", *pp);
+ printf("\n");
+}
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr, "Usage: %s\n"
+ "\t%s -p <port> [-P <proto>]\n"
+ "\t%s -n <name> [-P <proto>]\n", getprogname(), getprogname(),
+ getprogname());
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct servent *svp;
+ const char *port = NULL, *proto = NULL, *name = NULL;
+ int c;
+
+ while ((c = getopt(argc, argv, "p:n:P:")) != -1) {
+ switch (c) {
+ case 'n':
+ name = optarg;
+ break;
+ case 'p':
+ port = optarg;
+ break;
+ case 'P':
+ proto = optarg;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (port && name)
+ usage();
+ if (port) {
+ if ((svp = getservbyport(htons(atoi(port)), proto)) != NULL)
+ pserv(svp);
+ return 0;
+ }
+ if (name) {
+ if ((svp = getservbyname(name, proto)) != NULL)
+ pserv(svp);
+ return 0;
+ }
+
+ setservent(0);
+ while ((svp = getservent()) != NULL)
+ pserv(svp);
+ endservent();
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/hosts b/contrib/netbsd-tests/lib/libc/net/hosts
new file mode 100644
index 0000000..87ccbe8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/hosts
@@ -0,0 +1,11 @@
+# $NetBSD: hosts,v 1.1 2013/08/16 15:29:45 christos Exp $
+#
+# Host Database
+# This file should contain the addresses and aliases
+# for local hosts that share this file.
+# It is used only for "ifconfig" and other operations
+# before the nameserver is started.
+#
+#
+::1 localhost localhost. localhost.localdomain.
+127.0.0.1 localhost localhost. localhost.localdomain.
diff --git a/contrib/netbsd-tests/lib/libc/net/resolv.conf b/contrib/netbsd-tests/lib/libc/net/resolv.conf
new file mode 100644
index 0000000..bbc8559
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/resolv.conf
@@ -0,0 +1 @@
+nameserver 127.0.0.1
diff --git a/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c
new file mode 100644
index 0000000..2a91060
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c
@@ -0,0 +1,137 @@
+/* $NetBSD: t_ether_aton.c,v 1.1 2011/11/01 22:36:53 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 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/cdefs.h>
+__RCSID("$NetBSD: t_ether_aton.c,v 1.1 2011/11/01 22:36:53 pgoyette Exp $");
+
+#include <atf-c.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <err.h>
+#include <string.h>
+#include <errno.h>
+
+#ifndef __NetBSD__
+#ifdef __linux__
+#include <netinet/ether.h>
+#endif
+#include <net/ethernet.h>
+#endif
+
+#ifdef __NetBSD__
+#define ETHER_ADDR_LEN 6
+
+int ether_aton_r(u_char *dest, size_t len, const char *str);
+#endif
+
+static const struct {
+ u_char res[ETHER_ADDR_LEN];
+ const char *str;
+ int error;
+} tests[] = {
+ { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab }, "01:23:45:67:89:ab", 0 },
+#ifdef __NetBSD__
+ { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "0:1:22-3:14:05", 0 },
+ { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "000122031405", 0 },
+ { { 0x0a, 0x0B, 0xcc, 0xdD, 0xEE, 0x0f }, "0a0BccdDEE0f", 0 },
+#endif
+#define ZERO { 0, 0, 0, 0, 0, 0 }
+ { ZERO, "0:1:2-3:04:05:06", ENAMETOOLONG },
+ { ZERO, "0:1:2-3:04:", ENOBUFS },
+ { ZERO, "0:1:2-3:04:x7", EINVAL },
+ { ZERO, "1:x-3:04:05:7", EINVAL },
+ { ZERO, NULL, 0 },
+};
+
+ATF_TC(tc_ether_aton);
+ATF_TC_HEAD(tc_ether_aton, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check that ether_aton(3) works");
+}
+
+ATF_TC_BODY(tc_ether_aton, tc)
+{
+#ifdef __NetBSD__
+ u_char dest[ETHER_ADDR_LEN];
+#else
+ struct ether_addr dest;
+#endif
+ size_t t;
+#ifdef __NetBSD__
+ int e, r;
+#else
+ int e;
+ struct ether_addr *r;
+#endif
+ const char *s;
+
+ for (t = 0; tests[t].str; t++) {
+ s = tests[t].str;
+ if ((e = tests[t].error) == 0) {
+#ifdef __NetBSD__
+ if (ether_aton_r(dest, sizeof(dest), s) != e)
+ atf_tc_fail("failed on `%s'", s);
+ if (memcmp(dest, tests[t].res, sizeof(dest)) != 0)
+ atf_tc_fail("unexpected result on `%s'", s);
+#else
+ if (ether_aton_r(s, &dest) == NULL && e == 0)
+ atf_tc_fail("failed on `%s'", s);
+ if (memcmp(&dest, tests[t].res, sizeof(dest)) != 0)
+ atf_tc_fail("unexpected result on `%s'", s);
+#endif
+ } else {
+#ifdef __NetBSD__
+ if ((r = ether_aton_r(dest, sizeof(dest), s)) != e)
+ atf_tc_fail("unexpectedly succeeded on `%s' "
+ "(%d != %d)", s, r, e);
+#else
+ if ((r = ether_aton_r(s, &dest)) != NULL && e != 0)
+ atf_tc_fail("unexpectedly succeeded on `%s' "
+ "(%p != %d)", s, r, e);
+#endif
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, tc_ether_aton);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c b/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c
new file mode 100644
index 0000000..1c1a0e0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c
@@ -0,0 +1,233 @@
+/* $NetBSD: t_getprotoent.c,v 1.2 2012/04/04 10:03:53 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_getprotoent.c,v 1.2 2012/04/04 10:03:53 joerg Exp $");
+
+#include <atf-c.h>
+#include <netdb.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+static const struct {
+ const char *name;
+ int number;
+} protos[] = {
+
+ { "icmp", 1 }, { "tcp", 6 }, { "udp", 17 }, { "gre", 47 },
+ { "esp", 50 }, { "ah", 51 }, { "sctp", 132}, { "ipv6-icmp", 58 }
+};
+
+ATF_TC(endprotoent_rewind);
+ATF_TC_HEAD(endprotoent_rewind, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check that endprotoent(3) rewinds");
+}
+
+ATF_TC_BODY(endprotoent_rewind, tc)
+{
+ struct protoent *p;
+ int i = 0;
+
+ setprotoent(0);
+
+ while ((p = getprotoent()) != NULL && i <= 10) {
+ ATF_REQUIRE(p->p_proto == i);
+ i++;
+ }
+
+ i = 0;
+ endprotoent();
+
+ while ((p = getprotoent()) != NULL && i <= 10) {
+ ATF_REQUIRE(p->p_proto == i);
+ i++;
+ }
+
+ endprotoent();
+}
+
+ATF_TC(getprotobyname_basic);
+ATF_TC_HEAD(getprotobyname_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A naive test of getprotobyname(3)");
+}
+
+ATF_TC_BODY(getprotobyname_basic, tc)
+{
+ struct protoent *p;
+ size_t i;
+
+ for (i = 0; i < __arraycount(protos); i++) {
+
+ p = getprotobyname(protos[i].name);
+
+ ATF_REQUIRE(p != NULL);
+ ATF_REQUIRE(p->p_proto == protos[i].number);
+ ATF_REQUIRE(strcmp(p->p_name, protos[i].name) == 0);
+ }
+
+ endprotoent();
+}
+
+ATF_TC(getprotobyname_err);
+ATF_TC_HEAD(getprotobyname_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test EOF from getprotobyname(3)");
+}
+
+ATF_TC_BODY(getprotobyname_err, tc)
+{
+ static const char * name[] =
+ { "xxx", "yyy", "xyz", ".as.d}9x.._?!!#\xa4,\xa8^//&%%,",
+ "0", "", "tCp", "uDp", "t c p", "tcp ", " tcp" };
+
+ size_t i;
+
+ for (i = 0; i < __arraycount(name); i++)
+ ATF_REQUIRE(getprotobyname(name[i]) == NULL);
+
+ endprotoent();
+}
+
+ATF_TC(getprotobynumber_basic);
+ATF_TC_HEAD(getprotobynumber_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A naive test of getprotobynumber(3)");
+}
+
+ATF_TC_BODY(getprotobynumber_basic, tc)
+{
+ struct protoent *p;
+ size_t i;
+
+ /*
+ * No ATF_CHECK() due static storage.
+ */
+ for (i = 0; i < __arraycount(protos); i++) {
+
+ p = getprotobynumber(protos[i].number);
+
+ ATF_REQUIRE(p != NULL);
+ ATF_REQUIRE(p->p_proto == protos[i].number);
+ ATF_REQUIRE(strcmp(p->p_name, protos[i].name) == 0);
+ }
+
+ endprotoent();
+}
+
+ATF_TC(getprotobynumber_err);
+ATF_TC_HEAD(getprotobynumber_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test EOF from getprotobynumber(3)");
+}
+
+ATF_TC_BODY(getprotobynumber_err, tc)
+{
+ static const int number[] = { -1, -99999, INT_MAX, 1000000000 };
+ size_t i;
+
+ for (i = 0; i < __arraycount(number); i++)
+ ATF_REQUIRE(getprotobynumber(number[i]) == NULL);
+
+ endprotoent();
+}
+
+ATF_TC(getprotoent_next);
+ATF_TC_HEAD(getprotoent_next, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "getprotoent(3) returns next line?");
+}
+
+ATF_TC_BODY(getprotoent_next, tc)
+{
+ struct protoent *p;
+ int i = 0;
+
+ /*
+ * The range [0, 60] is already reserved by IANA.
+ */
+ while ((p = getprotoent()) != NULL && i <= 60) {
+ ATF_CHECK(p->p_proto == i);
+ i++;
+ }
+
+ endprotoent();
+}
+
+ATF_TC(setprotoent_rewind);
+ATF_TC_HEAD(setprotoent_rewind, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check that setprotoent(3) rewinds");
+}
+
+ATF_TC_BODY(setprotoent_rewind, tc)
+{
+ struct protoent *p;
+
+ setprotoent(0);
+
+ p = getprotoent();
+ ATF_REQUIRE(p->p_proto == 0);
+
+ p = getprotoent();
+ ATF_REQUIRE(p->p_proto == 1);
+
+ p = getprotoent();
+ ATF_REQUIRE(p->p_proto == 2);
+
+ setprotoent(0);
+
+ p = getprotoent();
+ ATF_REQUIRE(p->p_proto == 0);
+
+ p = getprotoent();
+ ATF_REQUIRE(p->p_proto == 1);
+
+ p = getprotoent();
+ ATF_REQUIRE(p->p_proto == 2);
+
+ endprotoent();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getprotobyname_basic);
+ ATF_TP_ADD_TC(tp, getprotobyname_err);
+ ATF_TP_ADD_TC(tp, getprotobynumber_basic);
+ ATF_TP_ADD_TC(tp, getprotobynumber_err);
+ ATF_TP_ADD_TC(tp, endprotoent_rewind);
+ ATF_TP_ADD_TC(tp, getprotoent_next);
+ ATF_TP_ADD_TC(tp, setprotoent_rewind);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/t_hostent.sh b/contrib/netbsd-tests/lib/libc/net/t_hostent.sh
new file mode 100755
index 0000000..b597b6d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/t_hostent.sh
@@ -0,0 +1,240 @@
+# $NetBSD: t_hostent.sh,v 1.10 2014/01/13 11:08:14 gson Exp $
+#
+# 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.
+#
+
+n6="sixthavenue.astron.com"
+a6="2620:106:3003:1f00:3e4a:92ff:fef4:e180"
+ans6="name=$n6, length=16, addrtype=24, aliases=[] addr_list=[$a6]\n"
+
+n4="sixthavenue.astron.com"
+a4="38.117.134.16"
+ans4="name=$n4, length=4, addrtype=2, aliases=[] addr_list=[$a4]\n"
+
+l6="localhost"
+al6="::1"
+loc6="name=$l6, length=16, addrtype=24, aliases=[localhost. localhost.localdomain.] addr_list=[$al6]\n"
+
+l4="localhost"
+al4="127.0.0.1"
+loc4="name=$l4, length=4, addrtype=2, aliases=[localhost. localhost.localdomain.] addr_list=[$al4]\n"
+
+dir="$(atf_get_srcdir)"
+res="-r ${dir}/resolv.conf"
+
+# Hijack DNS traffic using a single rump server instance and a DNS
+# server listening on its loopback address.
+
+start_dns_server() {
+ export RUMP_SERVER=unix:///tmp/rumpserver
+ rump_server -lrumpdev -lrumpnet -lrumpnet_net -lrumpnet_netinet \
+ -lrumpnet_netinet6 -lrumpnet_local $RUMP_SERVER
+ HIJACK_DNS="LD_PRELOAD=/usr/lib/librumphijack.so RUMPHIJACK='socket=inet:inet6'"
+ eval $HIJACK_DNS ${dir}/h_dns_server $1
+}
+
+stop_dns_server() {
+ export RUMP_SERVER=unix:///tmp/rumpserver
+ kill $(cat dns_server_$1.pid)
+ rump.halt
+}
+
+atf_test_case gethostbyname4 cleanup
+gethostbyname4_head()
+{
+ atf_set "descr" "Checks gethostbyname2(3) for AF_INET (auto, as determined by nsswitch.conf(5)"
+}
+gethostbyname4_body()
+{
+ start_dns_server 4
+ atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -4 $n4"
+}
+gethostbyname4_cleanup()
+{
+ stop_dns_server 4
+}
+
+atf_test_case gethostbyname6 cleanup cleanup
+gethostbyname6_head()
+{
+ atf_set "descr" "Checks gethostbyname2(3) for AF_INET6 (auto, as determined by nsswitch.conf(5)"
+}
+gethostbyname6_body()
+{
+ start_dns_server 4
+ atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -6 $n6"
+}
+gethostbyname6_cleanup()
+{
+ stop_dns_server 4
+}
+
+atf_test_case gethostbyaddr4 cleanup
+gethostbyaddr4_head()
+{
+ atf_set "descr" "Checks gethostbyaddr(3) for AF_INET (auto, as determined by nsswitch.conf(5)"
+}
+gethostbyaddr4_body()
+{
+ start_dns_server 4
+ atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -a $a4"
+}
+gethostbyaddr4_cleanup()
+{
+ stop_dns_server 4
+}
+
+atf_test_case gethostbyaddr6 cleanup
+gethostbyaddr6_head()
+{
+ atf_set "descr" "Checks gethostbyaddr(3) for AF_INET6 (auto, as determined by nsswitch.conf(5)"
+}
+gethostbyaddr6_body()
+{
+ start_dns_server 4
+ atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t auto -a $a6"
+}
+gethostbyaddr6_cleanup()
+{
+ stop_dns_server 4
+}
+
+atf_test_case hostsbynamelookup4
+hostsbynamelookup4_head()
+{
+ atf_set "descr" "Checks /etc/hosts name lookup for AF_INET"
+}
+hostsbynamelookup4_body()
+{
+ atf_check -o inline:"$loc4" -x "${dir}/h_hostent -f ${dir}/hosts -t file -4 $l4"
+}
+
+atf_test_case hostsbynamelookup6
+hostsbynamelookup6_head()
+{
+ atf_set "descr" "Checks /etc/hosts name lookup for AF_INET6"
+}
+hostsbynamelookup6_body()
+{
+ atf_check -o inline:"$loc6" -x "${dir}/h_hostent -f ${dir}/hosts -t file -6 $l6"
+}
+
+atf_test_case hostsbyaddrlookup4
+hostsbyaddrlookup4_head()
+{
+ atf_set "descr" "Checks /etc/hosts address lookup for AF_INET"
+}
+hostsbyaddrlookup4_body()
+{
+ atf_check -o inline:"$loc4" -x "${dir}/h_hostent -f ${dir}/hosts -t file -4 -a $al4"
+}
+
+atf_test_case hostsbyaddrlookup6
+hostsbyaddrlookup6_head()
+{
+ atf_set "descr" "Checks /etc/hosts address lookup for AF_INET6"
+}
+hostsbyaddrlookup6_body()
+{
+ atf_check -o inline:"$loc6" -x "${dir}/h_hostent -f ${dir}/hosts -t file -6 -a $al6"
+}
+
+atf_test_case dnsbynamelookup4 cleanup
+dnsbynamelookup4_head()
+{
+ atf_set "descr" "Checks DNS name lookup for AF_INET"
+}
+dnsbynamelookup4_body()
+{
+ start_dns_server 4
+ atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -4 $n4"
+}
+dnsbynamelookup4_cleanup()
+{
+ stop_dns_server 4
+}
+
+atf_test_case dnsbynamelookup6 cleanup
+dnsbynamelookup6_head()
+{
+ atf_set "descr" "Checks DNS name lookup for AF_INET6"
+}
+dnsbynamelookup6_body()
+{
+ start_dns_server 4
+ atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -6 $n6"
+}
+dnsbynamelookup6_cleanup()
+{
+ stop_dns_server 4
+}
+
+atf_test_case dnsbyaddrlookup4 cleanup
+dnsbyaddrlookup4_head()
+{
+ atf_set "descr" "Checks DNS address lookup for AF_INET"
+}
+dnsbyaddrlookup4_body()
+{
+ start_dns_server 4
+ atf_check -o inline:"$ans4" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -4 -a $a4"
+}
+dnsbyaddrlookup4_cleanup()
+{
+ stop_dns_server 4
+}
+
+atf_test_case dnsbyaddrlookup6 cleanup
+dnsbyaddrlookup6_head()
+{
+ atf_set "descr" "Checks dns address lookup for AF_INET6"
+}
+dnsbyaddrlookup6_body()
+{
+ start_dns_server 4
+ atf_check -o inline:"$ans6" -x "$HIJACK_DNS ${dir}/h_hostent ${res} -t dns -6 -a $a6"
+}
+dnsbyaddrlookup6_cleanup()
+{
+ stop_dns_server 4
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case gethostbyname4
+ atf_add_test_case gethostbyname6
+ atf_add_test_case gethostbyaddr4
+ atf_add_test_case gethostbyaddr6
+
+ atf_add_test_case hostsbynamelookup4
+ atf_add_test_case hostsbynamelookup6
+ atf_add_test_case hostsbyaddrlookup4
+ atf_add_test_case hostsbyaddrlookup6
+
+ atf_add_test_case dnsbynamelookup4
+ atf_add_test_case dnsbynamelookup6
+ atf_add_test_case dnsbyaddrlookup4
+ atf_add_test_case dnsbyaddrlookup6
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh b/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh
new file mode 100755
index 0000000..b584369
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh
@@ -0,0 +1,51 @@
+# $NetBSD: t_nsdispatch.sh,v 1.1 2011/01/13 01:56:44 pgoyette Exp $
+#
+# 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.
+#
+
+atf_test_case recurse
+recurse_head()
+{
+ atf_set "descr" "Checks recursive calls to nsdispatch()" \
+ "within threaded program"
+}
+recurse_body()
+{
+ cat >exp <<EOF
+func1: enter
+func2: enter
+func3: enter
+func3: exit
+func2: exit
+func1: exit
+EOF
+
+ atf_check -o file:exp "$(atf_get_srcdir)/h_nsd_recurse"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case recurse
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/t_protoent.sh b/contrib/netbsd-tests/lib/libc/net/t_protoent.sh
new file mode 100755
index 0000000..322d426
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/t_protoent.sh
@@ -0,0 +1,91 @@
+# $NetBSD: t_protoent.sh,v 1.2 2012/09/03 15:32:18 christos Exp $
+#
+# 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.
+#
+
+atf_test_case protoent
+protoent_head()
+{
+ atf_set "descr" "Checks {get,set,end}protoent(3)"
+}
+protoent_body()
+{
+ #
+ # Munge original to:
+ # (1) match output format of the test program
+ # (2) fold all names for the same port/proto together
+ # (3) prune duplicates
+ #
+ tr '\t' ' ' </etc/protocols | awk '
+ function add(key, name, i, n, ar) {
+ n = split(names[key], ar);
+ for (i = 1; i <= n; i++) {
+ if (name == ar[i]) {
+ return;
+ }
+ }
+ delete ar;
+ names[key] = names[key] " " name;
+ }
+ {
+ sub("#.*", "", $0);
+ gsub(" *", " ", $0);
+ if (NF == 0) {
+ next;
+ }
+ add($2, $1, 0);
+ for (i = 3; i <= NF; i++) {
+ add($2, $i, 1);
+ }
+ }
+ END {
+ for (key in names) {
+ proto = key;
+
+ n = split(names[key], ar);
+ printf "name=%s, proto=%s, aliases=", ar[1], proto;
+ for (i=2; i<=n; i++) {
+ if (i>2) {
+ printf " ";
+ }
+ printf "%s", ar[i];
+ }
+ printf "\n";
+ delete ar;
+ }
+ }
+ ' | sort >exp
+
+ # run test program
+ "$(atf_get_srcdir)/h_protoent" | sed 's/ *$//' | sort >out
+
+ diff -u exp out || \
+ atf_fail "Observed output does not match reference output"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case protoent
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/t_servent.sh b/contrib/netbsd-tests/lib/libc/net/t_servent.sh
new file mode 100755
index 0000000..0979eb3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/t_servent.sh
@@ -0,0 +1,111 @@
+# $NetBSD: t_servent.sh,v 1.1 2011/01/12 17:32:27 pgoyette Exp $
+#
+# 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.
+#
+
+atf_test_case servent
+servent_head()
+{
+ atf_set "descr" "Checks {get,set,end}servent(3)"
+}
+servent_body()
+{
+ #
+ # Munge original to:
+ # (1) match output format of the test program
+ # (2) fold all names for the same port/proto together
+ # (3) prune duplicates
+ #
+ tr '\t' ' ' </etc/services | awk '
+ function add(key, name, i, n, ar) {
+ n = split(names[key], ar);
+ for (i=1; i<=n; i++) {
+ if (name == ar[i]) {
+ return;
+ }
+ }
+ delete ar;
+ names[key] = names[key] " " name;
+ }
+
+ {
+ sub("#.*", "", $0);
+ gsub(" *", " ", $0);
+ if (NF==0) {
+ next;
+ }
+ add($2, $1, 0);
+ for (i=3; i<=NF; i++) {
+ add($2, $i, 1);
+ }
+ }
+ END {
+ for (key in names) {
+ portproto = key;
+ sub("/", ", proto=", portproto);
+ portproto = "port=" portproto;
+
+ n = split(names[key], ar);
+ printf "name=%s, %s, aliases=", ar[1], portproto;
+ for (i=2; i<=n; i++) {
+ if (i>2) {
+ printf " ";
+ }
+ printf "%s", ar[i];
+ }
+ printf "\n";
+ delete ar;
+ }
+ }
+ ' | sort >exp
+
+ case "$(uname)" in
+ FreeBSD)
+ # (3) Don't prune duplicates
+ tr '\t' ' ' < /etc/services |
+ sed 's/#.*//;s/ */ /g; /^$/d;s#\([0-9]\)/#\1 #;s/ *$//' |
+ sort |
+ while read l; do
+ set $l
+ name=$1; shift
+ port=$1; shift
+ proto=$1; shift
+ alias="$@"
+ printf "name=%s, port=%s, proto=%s, aliases=%s\n" \
+ $name $port $proto "$alias"
+ done > exp
+ ;;
+ esac
+
+ # run test program
+ "$(atf_get_srcdir)/h_servent" | sed 's/ *$//' | sort >out
+
+ diff -u exp out || atf_fail "Observed output does not match reference output"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case servent
+}
diff --git a/contrib/netbsd-tests/lib/libc/regex/README b/contrib/netbsd-tests/lib/libc/regex/README
new file mode 100644
index 0000000..6d9a28c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/README
@@ -0,0 +1,33 @@
+regular expression test set
+Lines are at least three fields, separated by one or more tabs. "" stands
+for an empty field. First field is an RE. Second field is flags. If
+C flag given, regcomp() is expected to fail, and the third field is the
+error name (minus the leading REG_).
+
+Otherwise it is expected to succeed, and the third field is the string to
+try matching it against. If there is no fourth field, the match is
+expected to fail. If there is a fourth field, it is the substring that
+the RE is expected to match. If there is a fifth field, it is a comma-
+separated list of what the subexpressions should match, with - indicating
+no match for that one. In both the fourth and fifth fields, a (sub)field
+starting with @ indicates that the (sub)expression is expected to match
+a null string followed by the stuff after the @; this provides a way to
+test where null strings match. The character `N' in REs and strings
+is newline, `S' is space, `T' is tab, `Z' is NUL.
+
+The full list of flags:
+ - placeholder, does nothing
+ b RE is a BRE, not an ERE
+ & try it as both an ERE and a BRE
+ C regcomp() error expected, third field is error name
+ i REG_ICASE
+ m ("mundane") REG_NOSPEC
+ s REG_NOSUB (not really testable)
+ n REG_NEWLINE
+ ^ REG_NOTBOL
+ $ REG_NOTEOL
+ # REG_STARTEND (see below)
+ p REG_PEND
+
+For REG_STARTEND, the start/end offsets are those of the substring
+enclosed in ().
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/anchor.in b/contrib/netbsd-tests/lib/libc/regex/data/anchor.in
new file mode 100644
index 0000000..d145408
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/anchor.in
@@ -0,0 +1,33 @@
+# anchoring and REG_NEWLINE
+^abc$ & abc abc
+a^b - a^b
+a^b b a^b a^b
+a$b - a$b
+a$b b a$b a$b
+^ & abc @abc
+$ & abc @
+^$ & "" @
+$^ - "" @
+\($\)\(^\) b "" @
+# stop retching, those are legitimate (although disgusting)
+^^ - "" @
+$$ - "" @
+b$ & abNc
+b$ &n abNc b
+^b$ & aNbNc
+^b$ &n aNbNc b
+^$ &n aNNb @Nb
+^$ n abc
+^$ n abcN @
+$^ n aNNb @Nb
+\($\)\(^\) bn aNNb @Nb
+^^ n^ aNNb @Nb
+$$ n aNNb @NN
+^a ^ a
+a$ $ a
+^a ^n aNb
+^b ^n aNb b
+a$ $n bNa
+b$ $n bNa b
+a*(^b$)c* - b b
+a*\(^b$\)c* b b b
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/README b/contrib/netbsd-tests/lib/libc/regex/data/att/README
new file mode 100644
index 0000000..e2ee6f6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/att/README
@@ -0,0 +1,8 @@
+AT&T test data from: http://www2.research.att.com/~gsf/testregex/
+
+Quoting from the page:
+ testregex.c 2004-05-31 is the latest source for the AT&T Research
+ regression test harness for the X/Open regex pattern match interface.
+ See testregex(1) for option and test input details. The source and
+ test data posted here are license free.
+
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat
new file mode 100644
index 0000000..4399ca1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat
@@ -0,0 +1,216 @@
+NOTE all standard compliant implementations should pass these : 2002-05-31
+
+BE abracadabra$ abracadabracadabra (7,18)
+BE a...b abababbb (2,7)
+BE XXXXXX ..XXXXXX (2,8)
+E \) () (1,2)
+BE a] a]a (0,2)
+B } } (0,1)
+E \} } (0,1)
+BE \] ] (0,1)
+B ] ] (0,1)
+E ] ] (0,1)
+B { { (0,1)
+B } } (0,1)
+BE ^a ax (0,1)
+BE \^a a^a (1,3)
+BE a\^ a^ (0,2)
+BE a$ aa (1,2)
+BE a\$ a$ (0,2)
+BE ^$ NULL (0,0)
+E $^ NULL (0,0)
+E a($) aa (1,2)(2,2)
+E a*(^a) aa (0,1)(0,1)
+E (..)*(...)* a (0,0)
+E (..)*(...)* abcd (0,4)(2,4)
+E (ab|a)(bc|c) abc (0,3)(0,2)(2,3)
+E (ab)c|abc abc (0,3)(0,2)
+E a{0}b ab (1,2)
+E (a*)(b?)(b+)b{3} aaabbbbbbb (0,10)(0,3)(3,4)(4,7)
+E (a*)(b{0,1})(b{1,})b{3} aaabbbbbbb (0,10)(0,3)(3,4)(4,7)
+E a{9876543210} NULL BADBR
+E ((a|a)|a) a (0,1)(0,1)(0,1)
+E (a*)(a|aa) aaaa (0,4)(0,3)(3,4)
+E a*(a.|aa) aaaa (0,4)(2,4)
+E a(b)|c(d)|a(e)f aef (0,3)(?,?)(?,?)(1,2)
+E (a|b)?.* b (0,1)(0,1)
+E (a|b)c|a(b|c) ac (0,2)(0,1)
+E (a|b)c|a(b|c) ab (0,2)(?,?)(1,2)
+E (a|b)*c|(a|ab)*c abc (0,3)(1,2)
+E (a|b)*c|(a|ab)*c xc (1,2)
+E (.a|.b).*|.*(.a|.b) xa (0,2)(0,2)
+E a?(ab|ba)ab abab (0,4)(0,2)
+E a?(ac{0}b|ba)ab abab (0,4)(0,2)
+E ab|abab abbabab (0,2)
+E aba|bab|bba baaabbbaba (5,8)
+E aba|bab baaabbbaba (6,9)
+E (aa|aaa)*|(a|aaaaa) aa (0,2)(0,2)
+E (a.|.a.)*|(a|.a...) aa (0,2)(0,2)
+E ab|a xabc (1,3)
+E ab|a xxabc (2,4)
+Ei (Ab|cD)* aBcD (0,4)(2,4)
+BE [^-] --a (2,3)
+BE [a-]* --a (0,3)
+BE [a-m-]* --amoma-- (0,4)
+E :::1:::0:|:::1:1:0: :::0:::1:::1:::0: (8,17)
+E :::1:::0:|:::1:1:1: :::0:::1:::1:::0: (8,17)
+{E [[:upper:]] A (0,1) [[<element>]] not supported
+E [[:lower:]]+ `az{ (1,3)
+E [[:upper:]]+ @AZ[ (1,3)
+BE [[-]] [[-]] (2,4)
+BE [[.NIL.]] NULL ECOLLATE
+BE [[=aleph=]] NULL ECOLLATE
+}
+BE$ \n \n (0,1)
+BEn$ \n \n (0,1)
+BE$ [^a] \n (0,1)
+BE$ \na \na (0,2)
+E (a)(b)(c) abc (0,3)(0,1)(1,2)(2,3)
+BE xxx xxx (0,3)
+E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) feb 6, (0,6)
+E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) 2/7 (0,3)
+E1 (^|[ (,;])((([Ff]eb[^ ]* *|0*2/|\* */?)0*[6-7]))([^0-9]|$) feb 1,Feb 6 (5,11)
+E3 ((((((((((((((((((((((((((((((x)))))))))))))))))))))))))))))) x (0,1)(0,1)(0,1)
+E3 ((((((((((((((((((((((((((((((x))))))))))))))))))))))))))))))* xx (0,2)(1,2)(1,2)
+E a?(ab|ba)* ababababababababababababababababababababababababababababababababababababababababa (0,81)(79,81)
+E abaa|abbaa|abbbaa|abbbbaa ababbabbbabbbabbbbabbbbaa (18,25)
+E abaa|abbaa|abbbaa|abbbbaa ababbabbbabbbabbbbabaa (18,22)
+E aaac|aabc|abac|abbc|baac|babc|bbac|bbbc baaabbbabac (7,11)
+BE$ .* \x01\xff (0,2)
+E aaaa|bbbb|cccc|ddddd|eeeeee|fffffff|gggg|hhhh|iiiii|jjjjj|kkkkk|llll XaaaXbbbXcccXdddXeeeXfffXgggXhhhXiiiXjjjXkkkXlllXcbaXaaaa (53,57)
+L aaaa\nbbbb\ncccc\nddddd\neeeeee\nfffffff\ngggg\nhhhh\niiiii\njjjjj\nkkkkk\nllll XaaaXbbbXcccXdddXeeeXfffXgggXhhhXiiiXjjjXkkkXlllXcbaXaaaa NOMATCH
+E a*a*a*a*a*b aaaaaaaaab (0,10)
+BE ^ NULL (0,0)
+BE $ NULL (0,0)
+BE ^$ NULL (0,0)
+BE ^a$ a (0,1)
+BE abc abc (0,3)
+BE abc xabcy (1,4)
+BE abc ababc (2,5)
+BE ab*c abc (0,3)
+BE ab*bc abc (0,3)
+BE ab*bc abbc (0,4)
+BE ab*bc abbbbc (0,6)
+E ab+bc abbc (0,4)
+E ab+bc abbbbc (0,6)
+E ab?bc abbc (0,4)
+E ab?bc abc (0,3)
+E ab?c abc (0,3)
+BE ^abc$ abc (0,3)
+BE ^abc abcc (0,3)
+BE abc$ aabc (1,4)
+BE ^ abc (0,0)
+BE $ abc (3,3)
+BE a.c abc (0,3)
+BE a.c axc (0,3)
+BE a.*c axyzc (0,5)
+BE a[bc]d abd (0,3)
+BE a[b-d]e ace (0,3)
+BE a[b-d] aac (1,3)
+BE a[-b] a- (0,2)
+BE a[b-] a- (0,2)
+BE a] a] (0,2)
+BE a[]]b a]b (0,3)
+BE a[^bc]d aed (0,3)
+BE a[^-b]c adc (0,3)
+BE a[^]b]c adc (0,3)
+E ab|cd abc (0,2)
+E ab|cd abcd (0,2)
+E a\(b a(b (0,3)
+E a\(*b ab (0,2)
+E a\(*b a((b (0,4)
+E ((a)) abc (0,1)(0,1)(0,1)
+E (a)b(c) abc (0,3)(0,1)(2,3)
+E a+b+c aabbabc (4,7)
+E a* aaa (0,3)
+E (a*)* - (0,0)(0,0)
+E (a*)+ - (0,0)(0,0)
+E (a*|b)* - (0,0)(0,0)
+E (a+|b)* ab (0,2)(1,2)
+E (a+|b)+ ab (0,2)(1,2)
+E (a+|b)? ab (0,1)(0,1)
+BE [^ab]* cde (0,3)
+E (^)* - (0,0)(0,0)
+BE a* NULL (0,0)
+E ([abc])*d abbbcd (0,6)(4,5)
+E ([abc])*bcd abcd (0,4)(0,1)
+E a|b|c|d|e e (0,1)
+E (a|b|c|d|e)f ef (0,2)(0,1)
+E ((a*|b))* - (0,0)(0,0)(0,0)
+BE abcd*efg abcdefg (0,7)
+BE ab* xabyabbbz (1,3)
+BE ab* xayabbbz (1,2)
+E (ab|cd)e abcde (2,5)(2,4)
+BE [abhgefdc]ij hij (0,3)
+E (a|b)c*d abcd (1,4)(1,2)
+E (ab|ab*)bc abc (0,3)(0,1)
+E a([bc]*)c* abc (0,3)(1,3)
+E a([bc]*)(c*d) abcd (0,4)(1,3)(3,4)
+E a([bc]+)(c*d) abcd (0,4)(1,3)(3,4)
+E a([bc]*)(c+d) abcd (0,4)(1,2)(2,4)
+E a[bcd]*dcdcde adcdcde (0,7)
+E (ab|a)b*c abc (0,3)(0,2)
+E ((a)(b)c)(d) abcd (0,4)(0,3)(0,1)(1,2)(3,4)
+BE [A-Za-z_][A-Za-z0-9_]* alpha (0,5)
+E ^a(bc+|b[eh])g|.h$ abh (1,3)
+E (bc+d$|ef*g.|h?i(j|k)) effgz (0,5)(0,5)
+E (bc+d$|ef*g.|h?i(j|k)) ij (0,2)(0,2)(1,2)
+E (bc+d$|ef*g.|h?i(j|k)) reffgz (1,6)(1,6)
+E (((((((((a))))))))) a (0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)(0,1)
+BE multiple words multiple words yeah (0,14)
+E (.*)c(.*) abcde (0,5)(0,2)(3,5)
+BE abcd abcd (0,4)
+E a(bc)d abcd (0,4)(1,3)
+E a[-]?c ac (0,3)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Qaddafi (0,15)(?,?)(10,12)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mo'ammar Gadhafi (0,16)(?,?)(11,13)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Kaddafi (0,15)(?,?)(10,12)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Qadhafi (0,15)(?,?)(10,12)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Gadafi (0,14)(?,?)(10,11)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mu'ammar Qadafi (0,15)(?,?)(11,12)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moamar Gaddafi (0,14)(?,?)(9,11)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Mu'ammar Qadhdhafi (0,18)(?,?)(13,15)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Khaddafi (0,16)(?,?)(11,13)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghaddafy (0,16)(?,?)(11,13)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghadafi (0,15)(?,?)(11,12)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Ghaddafi (0,16)(?,?)(11,13)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muamar Kaddafi (0,14)(?,?)(9,11)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Quathafi (0,16)(?,?)(11,13)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Muammar Gheddafi (0,16)(?,?)(11,13)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moammar Khadafy (0,15)(?,?)(11,12)
+E M[ou]'?am+[ae]r .*([AEae]l[- ])?[GKQ]h?[aeu]+([dtz][dhz]?)+af[iy] Moammar Qudhafi (0,15)(?,?)(10,12)
+E a+(b|c)*d+ aabcdd (0,6)(3,4)
+E ^.+$ vivi (0,4)
+E ^(.+)$ vivi (0,4)(0,4)
+E ^([^!.]+).att.com!(.+)$ gryphon.att.com!eby (0,19)(0,7)(16,19)
+E ^([^!]+!)?([^!]+)$ bas (0,3)(?,?)(0,3)
+E ^([^!]+!)?([^!]+)$ bar!bas (0,7)(0,4)(4,7)
+E ^([^!]+!)?([^!]+)$ foo!bas (0,7)(0,4)(4,7)
+E ^.+!([^!]+!)([^!]+)$ foo!bar!bas (0,11)(4,8)(8,11)
+E ((foo)|(bar))!bas bar!bas (0,7)(0,3)(?,?)(0,3)
+E ((foo)|(bar))!bas foo!bar!bas (4,11)(4,7)(?,?)(4,7)
+E ((foo)|(bar))!bas foo!bas (0,7)(0,3)(0,3)
+E ((foo)|bar)!bas bar!bas (0,7)(0,3)
+E ((foo)|bar)!bas foo!bar!bas (4,11)(4,7)
+E ((foo)|bar)!bas foo!bas (0,7)(0,3)(0,3)
+E (foo|(bar))!bas bar!bas (0,7)(0,3)(0,3)
+E (foo|(bar))!bas foo!bar!bas (4,11)(4,7)(4,7)
+E (foo|(bar))!bas foo!bas (0,7)(0,3)
+E (foo|bar)!bas bar!bas (0,7)(0,3)
+E (foo|bar)!bas foo!bar!bas (4,11)(4,7)
+E (foo|bar)!bas foo!bas (0,7)(0,3)
+E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bar!bas (0,11)(0,11)(?,?)(?,?)(4,8)(8,11)
+E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ bas (0,3)(?,?)(0,3)
+E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ bar!bas (0,7)(0,4)(4,7)
+E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ foo!bar!bas (0,11)(?,?)(?,?)(4,8)(8,11)
+E ^([^!]+!)?([^!]+)$|^.+!([^!]+!)([^!]+)$ foo!bas (0,7)(0,4)(4,7)
+E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ bas (0,3)(0,3)(?,?)(0,3)
+E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ bar!bas (0,7)(0,7)(0,4)(4,7)
+E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bar!bas (0,11)(0,11)(?,?)(?,?)(4,8)(8,11)
+E ^(([^!]+!)?([^!]+)|.+!([^!]+!)([^!]+))$ foo!bas (0,7)(0,7)(0,4)(4,7)
+E .*(/XXX).* /XXX (0,4)(0,4)
+E .*(\\XXX).* \XXX (0,4)(0,4)
+E \\XXX \XXX (0,4)
+E .*(/000).* /000 (0,4)(0,4)
+E .*(\\000).* \000 (0,4)(0,4)
+E \\000 \000 (0,4)
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat
new file mode 100644
index 0000000..d348512
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat
@@ -0,0 +1,62 @@
+NOTE regex implementation categorization 2004-05-31
+
+?E aa* xaxaax (1,2) POSITION=leftmost
+; POSITION=bug
+
+?E (a*)(ab)*(b*) abc (0,2)(0,1)(?,?)(1,2) ASSOCIATIVITY=right
+|E (a*)(ab)*(b*) abc (0,2)(0,0)(0,2)(2,2) ASSOCIATIVITY=left
+; ASSOCIATIVITY=bug
+
+?E ((a*)(ab)*)((b*)(a*)) aba (0,3)(0,2)(0,0)(0,2)(2,3)(2,2)(2,3) SUBEXPRESSION=precedence
+|E ((a*)(ab)*)((b*)(a*)) aba (0,3)(0,1)(0,1)(?,?)(1,3)(1,2)(2,3) SUBEXPRESSION=grouping
+; SUBEXPRESSION=bug
+
+?E (...?.?)* xxxxxx (0,6)(4,6) REPEAT_LONGEST=first
+|E (...?.?)* xxxxxx (0,6)(2,6) REPEAT_LONGEST=last
+|E (...?.?)* xxxxxx OK REPEAT_LONGEST=unknown
+; REPEAT_LONGEST=bug
+
+?E (a|ab)(bc|c) abcabc (0,3)(0,2)(2,3) EXPECTED
+|E (a|ab)(bc|c) abcabc (0,3)(0,1)(1,3) BUG=alternation-order
+; BUG=alternation-order-UNKNOWN
+
+?E (aba|a*b)(aba|a*b) ababa (0,5)(0,2)(2,5) EXPECTED
+|E (aba|a*b)(aba|a*b) ababa (0,4)(0,3)(3,4) BUG=first-match
+; BUG=unknown-match
+
+?B a\(b\)*\1 a NOMATCH EXPECTED
+|B a\(b\)*\1 a (0,1) BUG=nomatch-match
+|B a\(b\)*\1 abab (0,2)(1,2) # BUG=repeat-any
+; BUG=nomatch-match-UNKNOWN
+
+?E (a*){2} xxxxx (0,0)(0,0) EXPECTED
+|E (a*){2} xxxxx (5,5)(5,5) BUG=range-null
+; BUG=range-null-UNKNOWN
+
+?B a\(b\)*\1 abab NOMATCH EXPECTED
+|B a\(b\)*\1 abab (0,1) # BUG=nomatch-match
+|B a\(b\)*\1 abab (0,2)(1,2) BUG=repeat-any
+; BUG=repeat-any-UNKNOWN
+
+?E (a*)* a (0,1)(0,1) EXPECTED
+|E (a*)* ax (0,1)(0,1) BUG=repeat-null-unknown
+|E (a*)* a (0,1)(1,1) BUG=repeat-null
+; BUG=repeat-null-UNKNOWN
+
+?E (aba|a*b)* ababa (0,5)(2,5) EXPECTED
+|E (aba|a*b)* ababa (0,5)(3,4) BUG=repeat-short
+|E (aba|a*b)* ababa (0,4)(3,4) # LENGTH=first
+; BUG=repeat-short-UNKNOWN
+
+?E (a(b)?)+ aba (0,3)(2,3) EXPECTED
+|E (a(b)?)+ aba (0,3)(2,3)(1,2) BUG=repeat-artifact
+; BUG=repeat-artifact-UNKNOWN
+
+?B \(a\(b\)*\)*\2 abab NOMATCH EXPECTED
+|B \(a\(b\)*\)*\2 abab (0,4)(2,3)(1,2) BUG=repeat-artifact-nomatch
+; BUG=repeat-artifact-nomatch-UNKNOWN
+
+?E (a?)((ab)?)(b?)a?(ab)?b? abab (0,4)(0,1)(1,1)(?,?)(1,2)(2,4) BUG=subexpression-first
+|E .*(.*) ab (0,2)(2,2) EXPECTED
+|E .*(.*) ab (0,2)(0,2) BUG=subexpression-first
+; BUG=subexpression-first-UNKNOWN
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat
new file mode 100644
index 0000000..39f3111
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat
@@ -0,0 +1,30 @@
+NOTE left-assoc:pass-all right-assoc:pass-all : 2002-04-29
+
+E (a|ab)(c|bcd) abcd (0,4)(0,1)(1,4)
+E (a|ab)(bcd|c) abcd (0,4)(0,1)(1,4)
+E (ab|a)(c|bcd) abcd (0,4)(0,1)(1,4)
+E (ab|a)(bcd|c) abcd (0,4)(0,1)(1,4)
+E ((a|ab)(c|bcd))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4)
+E ((a|ab)(bcd|c))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4)
+E ((ab|a)(c|bcd))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4)
+E ((ab|a)(bcd|c))(d*) abcd (0,4)(0,4)(0,1)(1,4)(4,4)
+E (a|ab)((c|bcd)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4)
+E (a|ab)((bcd|c)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4)
+E (ab|a)((c|bcd)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4)
+E (ab|a)((bcd|c)(d*)) abcd (0,4)(0,2)(2,4)(2,3)(3,4)
+E (a*)(b|abc) abc (0,3)(0,0)(0,3)
+E (a*)(abc|b) abc (0,3)(0,0)(0,3)
+E ((a*)(b|abc))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3)
+E ((a*)(abc|b))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3)
+E (a*)((b|abc)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3)
+E (a*)((abc|b)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3)
+E (a*)(b|abc) abc (0,3)(0,0)(0,3)
+E (a*)(abc|b) abc (0,3)(0,0)(0,3)
+E ((a*)(b|abc))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3)
+E ((a*)(abc|b))(c*) abc (0,3)(0,3)(0,0)(0,3)(3,3)
+E (a*)((b|abc)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3)
+E (a*)((abc|b)(c*)) abc (0,3)(0,1)(1,3)(1,2)(2,3)
+E (a|ab) ab (0,2)(0,2)
+E (ab|a) ab (0,2)(0,2)
+E (a|ab)(b*) ab (0,2)(0,2)(2,2)
+E (ab|a)(b*) ab (0,2)(0,2)(2,2)
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat
new file mode 100644
index 0000000..9c068c6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat
@@ -0,0 +1,16 @@
+NOTE left-assoc:pass-all right-assoc:pass-none : 2002-04-29
+
+E (a|ab)(c|bcd)(d*) abcd (0,4)(0,1)(1,4)(4,4)
+E (a|ab)(bcd|c)(d*) abcd (0,4)(0,1)(1,4)(4,4)
+E (ab|a)(c|bcd)(d*) abcd (0,4)(0,1)(1,4)(4,4)
+E (ab|a)(bcd|c)(d*) abcd (0,4)(0,1)(1,4)(4,4)
+
+E (a*)(b|abc)(c*) abc (0,3)(0,0)(0,3)(3,3)
+E (a*)(abc|b)(c*) abc (0,3)(0,0)(0,3)(3,3)
+E (a*)(b|abc)(c*) abc (0,3)(0,0)(0,3)(3,3)
+E (a*)(abc|b)(c*) abc (0,3)(0,0)(0,3)(3,3)
+
+E (a|ab)(c|bcd)(d|.*) abcd (0,4)(0,1)(1,4)(4,4)
+E (a|ab)(bcd|c)(d|.*) abcd (0,4)(0,1)(1,4)(4,4)
+E (ab|a)(c|bcd)(d|.*) abcd (0,4)(0,1)(1,4)(4,4)
+E (ab|a)(bcd|c)(d|.*) abcd (0,4)(0,1)(1,4)(4,4)
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat
new file mode 100644
index 0000000..c73d8f0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat
@@ -0,0 +1,73 @@
+NOTE null subexpression matches : 2002-06-06
+
+E (a*)* a (0,1)(0,1)
+E SAME x (0,0)(0,0)
+E SAME aaaaaa (0,6)(0,6)
+E SAME aaaaaax (0,6)(0,6)
+E (a*)+ a (0,1)(0,1)
+E SAME x (0,0)(0,0)
+E SAME aaaaaa (0,6)(0,6)
+E SAME aaaaaax (0,6)(0,6)
+E (a+)* a (0,1)(0,1)
+E SAME x (0,0)
+E SAME aaaaaa (0,6)(0,6)
+E SAME aaaaaax (0,6)(0,6)
+E (a+)+ a (0,1)(0,1)
+E SAME x NOMATCH
+E SAME aaaaaa (0,6)(0,6)
+E SAME aaaaaax (0,6)(0,6)
+
+E ([a]*)* a (0,1)(0,1)
+E SAME x (0,0)(0,0)
+E SAME aaaaaa (0,6)(0,6)
+E SAME aaaaaax (0,6)(0,6)
+E ([a]*)+ a (0,1)(0,1)
+E SAME x (0,0)(0,0)
+E SAME aaaaaa (0,6)(0,6)
+E SAME aaaaaax (0,6)(0,6)
+E ([^b]*)* a (0,1)(0,1)
+E SAME b (0,0)(0,0)
+E SAME aaaaaa (0,6)(0,6)
+E SAME aaaaaab (0,6)(0,6)
+E ([ab]*)* a (0,1)(0,1)
+E SAME aaaaaa (0,6)(0,6)
+E SAME ababab (0,6)(0,6)
+E SAME bababa (0,6)(0,6)
+E SAME b (0,1)(0,1)
+E SAME bbbbbb (0,6)(0,6)
+E SAME aaaabcde (0,5)(0,5)
+E ([^a]*)* b (0,1)(0,1)
+E SAME bbbbbb (0,6)(0,6)
+E SAME aaaaaa (0,0)(0,0)
+E ([^ab]*)* ccccxx (0,6)(0,6)
+E SAME ababab (0,0)(0,0)
+
+E ((z)+|a)* zabcde (0,2)(1,2)
+
+{E a+? aaaaaa (0,1) no *? +? mimimal match ops
+E (a) aaa (0,1)(0,1)
+E (a*?) aaa (0,0)(0,0)
+E (a)*? aaa (0,0)
+E (a*?)*? aaa (0,0)
+}
+
+B \(a*\)*\(x\) x (0,1)(0,0)(0,1)
+B \(a*\)*\(x\) ax (0,2)(0,1)(1,2)
+B \(a*\)*\(x\) axa (0,2)(0,1)(1,2)
+B \(a*\)*\(x\)\(\1\) x (0,1)(0,0)(0,1)(1,1)
+B \(a*\)*\(x\)\(\1\) ax (0,2)(1,1)(1,2)(2,2)
+B \(a*\)*\(x\)\(\1\) axa (0,3)(0,1)(1,2)(2,3)
+B \(a*\)*\(x\)\(\1\)\(x\) axax (0,4)(0,1)(1,2)(2,3)(3,4)
+B \(a*\)*\(x\)\(\1\)\(x\) axxa (0,3)(1,1)(1,2)(2,2)(2,3)
+
+E (a*)*(x) x (0,1)(0,0)(0,1)
+E (a*)*(x) ax (0,2)(0,1)(1,2)
+E (a*)*(x) axa (0,2)(0,1)(1,2)
+
+E (a*)+(x) x (0,1)(0,0)(0,1)
+E (a*)+(x) ax (0,2)(0,1)(1,2)
+E (a*)+(x) axa (0,2)(0,1)(1,2)
+
+E (a*){2}(x) x (0,1)(0,0)(0,1)
+E (a*){2}(x) ax (0,2)(1,1)(1,2)
+E (a*){2}(x) axa (0,2)(1,1)(1,2)
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat
new file mode 100644
index 0000000..c24749c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat
@@ -0,0 +1,140 @@
+NOTE implicit vs. explicit repetitions : 2009-02-02
+
+# Glenn Fowler <gsf@research.att.com>
+# conforming matches (column 4) must match one of the following BREs
+# NOMATCH
+# (0,.)\((\(.\),\(.\))(?,?)(\2,\3)\)*
+# (0,.)\((\(.\),\(.\))(\2,\3)(?,?)\)*
+# i.e., each 3-tuple has two identical elements and one (?,?)
+
+E ((..)|(.)) NULL NOMATCH
+E ((..)|(.))((..)|(.)) NULL NOMATCH
+E ((..)|(.))((..)|(.))((..)|(.)) NULL NOMATCH
+
+E ((..)|(.)){1} NULL NOMATCH
+E ((..)|(.)){2} NULL NOMATCH
+E ((..)|(.)){3} NULL NOMATCH
+
+E ((..)|(.))* NULL (0,0)
+
+E ((..)|(.)) a (0,1)(0,1)(?,?)(0,1)
+E ((..)|(.))((..)|(.)) a NOMATCH
+E ((..)|(.))((..)|(.))((..)|(.)) a NOMATCH
+
+E ((..)|(.)){1} a (0,1)(0,1)(?,?)(0,1)
+E ((..)|(.)){2} a NOMATCH
+E ((..)|(.)){3} a NOMATCH
+
+E ((..)|(.))* a (0,1)(0,1)(?,?)(0,1)
+
+E ((..)|(.)) aa (0,2)(0,2)(0,2)(?,?)
+E ((..)|(.))((..)|(.)) aa (0,2)(0,1)(?,?)(0,1)(1,2)(?,?)(1,2)
+E ((..)|(.))((..)|(.))((..)|(.)) aa NOMATCH
+
+E ((..)|(.)){1} aa (0,2)(0,2)(0,2)(?,?)
+E ((..)|(.)){2} aa (0,2)(1,2)(?,?)(1,2)
+E ((..)|(.)){3} aa NOMATCH
+
+E ((..)|(.))* aa (0,2)(0,2)(0,2)(?,?)
+
+E ((..)|(.)) aaa (0,2)(0,2)(0,2)(?,?)
+E ((..)|(.))((..)|(.)) aaa (0,3)(0,2)(0,2)(?,?)(2,3)(?,?)(2,3)
+E ((..)|(.))((..)|(.))((..)|(.)) aaa (0,3)(0,1)(?,?)(0,1)(1,2)(?,?)(1,2)(2,3)(?,?)(2,3)
+
+E ((..)|(.)){1} aaa (0,2)(0,2)(0,2)(?,?)
+E ((..)|(.)){2} aaa (0,3)(2,3)(?,?)(2,3)
+E ((..)|(.)){3} aaa (0,3)(2,3)(?,?)(2,3)
+
+E ((..)|(.))* aaa (0,3)(2,3)(?,?)(2,3)
+
+E ((..)|(.)) aaaa (0,2)(0,2)(0,2)(?,?)
+E ((..)|(.))((..)|(.)) aaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)
+E ((..)|(.))((..)|(.))((..)|(.)) aaaa (0,4)(0,2)(0,2)(?,?)(2,3)(?,?)(2,3)(3,4)(?,?)(3,4)
+
+E ((..)|(.)){1} aaaa (0,2)(0,2)(0,2)(?,?)
+E ((..)|(.)){2} aaaa (0,4)(2,4)(2,4)(?,?)
+E ((..)|(.)){3} aaaa (0,4)(3,4)(?,?)(3,4)
+
+E ((..)|(.))* aaaa (0,4)(2,4)(2,4)(?,?)
+
+E ((..)|(.)) aaaaa (0,2)(0,2)(0,2)(?,?)
+E ((..)|(.))((..)|(.)) aaaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)
+E ((..)|(.))((..)|(.))((..)|(.)) aaaaa (0,5)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)(4,5)(?,?)(4,5)
+
+E ((..)|(.)){1} aaaaa (0,2)(0,2)(0,2)(?,?)
+E ((..)|(.)){2} aaaaa (0,4)(2,4)(2,4)(?,?)
+E ((..)|(.)){3} aaaaa (0,5)(4,5)(?,?)(4,5)
+
+E ((..)|(.))* aaaaa (0,5)(4,5)(?,?)(4,5)
+
+E ((..)|(.)) aaaaaa (0,2)(0,2)(0,2)(?,?)
+E ((..)|(.))((..)|(.)) aaaaaa (0,4)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)
+E ((..)|(.))((..)|(.))((..)|(.)) aaaaaa (0,6)(0,2)(0,2)(?,?)(2,4)(2,4)(?,?)(4,6)(4,6)(?,?)
+
+E ((..)|(.)){1} aaaaaa (0,2)(0,2)(0,2)(?,?)
+E ((..)|(.)){2} aaaaaa (0,4)(2,4)(2,4)(?,?)
+E ((..)|(.)){3} aaaaaa (0,6)(4,6)(4,6)(?,?)
+
+E ((..)|(.))* aaaaaa (0,6)(4,6)(4,6)(?,?)
+
+NOTE additional repetition tests graciously provided by Chris Kuklewicz www.haskell.org 2009-02-02
+
+# These test a bug in OS X / FreeBSD / NetBSD, and libtree.
+# Linux/GLIBC gets the {8,} and {8,8} wrong.
+
+:HA#100:E X(.?){0,}Y X1234567Y (0,9)(7,8)
+:HA#101:E X(.?){1,}Y X1234567Y (0,9)(7,8)
+:HA#102:E X(.?){2,}Y X1234567Y (0,9)(7,8)
+:HA#103:E X(.?){3,}Y X1234567Y (0,9)(7,8)
+:HA#104:E X(.?){4,}Y X1234567Y (0,9)(7,8)
+:HA#105:E X(.?){5,}Y X1234567Y (0,9)(7,8)
+:HA#106:E X(.?){6,}Y X1234567Y (0,9)(7,8)
+:HA#107:E X(.?){7,}Y X1234567Y (0,9)(7,8)
+:HA#108:E X(.?){8,}Y X1234567Y (0,9)(8,8)
+:HA#110:E X(.?){0,8}Y X1234567Y (0,9)(7,8)
+:HA#111:E X(.?){1,8}Y X1234567Y (0,9)(7,8)
+:HA#112:E X(.?){2,8}Y X1234567Y (0,9)(7,8)
+:HA#113:E X(.?){3,8}Y X1234567Y (0,9)(7,8)
+:HA#114:E X(.?){4,8}Y X1234567Y (0,9)(7,8)
+:HA#115:E X(.?){5,8}Y X1234567Y (0,9)(7,8)
+:HA#116:E X(.?){6,8}Y X1234567Y (0,9)(7,8)
+:HA#117:E X(.?){7,8}Y X1234567Y (0,9)(7,8)
+:HA#118:E X(.?){8,8}Y X1234567Y (0,9)(8,8)
+
+# These test a fixed bug in my regex-tdfa that did not keep the expanded
+# form properly grouped, so right association did the wrong thing with
+# these ambiguous patterns (crafted just to test my code when I became
+# suspicious of my implementation). The first subexpression should use
+# "ab" then "a" then "bcd".
+
+# OS X / FreeBSD / NetBSD badly fail many of these, with impossible
+# results like (0,6)(4,5)(6,6).
+
+:HA#260:E (a|ab|c|bcd){0,}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#261:E (a|ab|c|bcd){1,}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#262:E (a|ab|c|bcd){2,}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#263:E (a|ab|c|bcd){3,}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#264:E (a|ab|c|bcd){4,}(d*) ababcd NOMATCH
+:HA#265:E (a|ab|c|bcd){0,10}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#266:E (a|ab|c|bcd){1,10}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#267:E (a|ab|c|bcd){2,10}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#268:E (a|ab|c|bcd){3,10}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#269:E (a|ab|c|bcd){4,10}(d*) ababcd NOMATCH
+:HA#270:E (a|ab|c|bcd)*(d*) ababcd (0,6)(3,6)(6,6)
+:HA#271:E (a|ab|c|bcd)+(d*) ababcd (0,6)(3,6)(6,6)
+
+# The above worked on Linux/GLIBC but the following often fail.
+# They also trip up OS X / FreeBSD / NetBSD:
+
+:HA#280:E (ab|a|c|bcd){0,}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#281:E (ab|a|c|bcd){1,}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#282:E (ab|a|c|bcd){2,}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#283:E (ab|a|c|bcd){3,}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#284:E (ab|a|c|bcd){4,}(d*) ababcd NOMATCH
+:HA#285:E (ab|a|c|bcd){0,10}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#286:E (ab|a|c|bcd){1,10}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#287:E (ab|a|c|bcd){2,10}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#288:E (ab|a|c|bcd){3,10}(d*) ababcd (0,6)(3,6)(6,6)
+:HA#289:E (ab|a|c|bcd){4,10}(d*) ababcd NOMATCH
+:HA#290:E (ab|a|c|bcd)*(d*) ababcd (0,6)(3,6)(6,6)
+:HA#291:E (ab|a|c|bcd)+(d*) ababcd (0,6)(3,6)(6,6)
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat b/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat
new file mode 100644
index 0000000..ed7f28e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat
@@ -0,0 +1,16 @@
+NOTE left-assoc:pass-none right-assoc:pass-all : 2002-04-29
+
+E (a|ab)(c|bcd)(d*) abcd (0,4)(0,2)(2,3)(3,4)
+E (a|ab)(bcd|c)(d*) abcd (0,4)(0,2)(2,3)(3,4)
+E (ab|a)(c|bcd)(d*) abcd (0,4)(0,2)(2,3)(3,4)
+E (ab|a)(bcd|c)(d*) abcd (0,4)(0,2)(2,3)(3,4)
+
+E (a*)(b|abc)(c*) abc (0,3)(0,1)(1,2)(2,3)
+E (a*)(abc|b)(c*) abc (0,3)(0,1)(1,2)(2,3)
+E (a*)(b|abc)(c*) abc (0,3)(0,1)(1,2)(2,3)
+E (a*)(abc|b)(c*) abc (0,3)(0,1)(1,2)(2,3)
+
+E (a|ab)(c|bcd)(d|.*) abcd (0,4)(0,2)(2,3)(3,4)
+E (a|ab)(bcd|c)(d|.*) abcd (0,4)(0,2)(2,3)(3,4)
+E (ab|a)(c|bcd)(d|.*) abcd (0,4)(0,2)(2,3)(3,4)
+E (ab|a)(bcd|c)(d|.*) abcd (0,4)(0,2)(2,3)(3,4)
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/backref.in b/contrib/netbsd-tests/lib/libc/regex/data/backref.in
new file mode 100644
index 0000000..cc59b06
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/backref.in
@@ -0,0 +1,21 @@
+# back references, ugh
+a\(b\)\2c bC ESUBREG
+a\(b\1\)c bC ESUBREG
+a\(b*\)c\1d b abbcbbd abbcbbd bb
+a\(b*\)c\1d b abbcbd
+a\(b*\)c\1d b abbcbbbd
+^\(.\)\1 b abc
+a\([bc]\)\1d b abcdabbd abbd b
+a\(\([bc]\)\2\)*d b abbccd abbccd
+a\(\([bc]\)\2\)*d b abbcbd
+# actually, this next one probably ought to fail, but the spec is unclear
+a\(\(b\)*\2\)*d b abbbd abbbd
+# here is a case that no NFA implementation does right
+\(ab*\)[ab]*\1 b ababaaa ababaaa a
+# check out normal matching in the presence of back refs
+\(a\)\1bcd b aabcd aabcd
+\(a\)\1bc*d b aabcd aabcd
+\(a\)\1bc*d b aabd aabd
+\(a\)\1bc*d b aabcccd aabcccd
+\(a\)\1bc*[ce]d b aabcccd aabcccd
+^\(a\)\1b\(c\)*cd$ b aabcccd aabcccd
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/basic.in b/contrib/netbsd-tests/lib/libc/regex/data/basic.in
new file mode 100644
index 0000000..d1e3aa9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/basic.in
@@ -0,0 +1,5 @@
+# basics
+a & a a
+abc & abc abc
+abc|de - abc abc
+a|b|c - abc a
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/bracket.in b/contrib/netbsd-tests/lib/libc/regex/data/bracket.in
new file mode 100644
index 0000000..53a0b20
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/bracket.in
@@ -0,0 +1,55 @@
+# brackets, and numerous perversions thereof
+a[b]c & abc abc
+a[ab]c & abc abc
+a[^ab]c & adc adc
+a[]b]c & a]c a]c
+a[[b]c & a[c a[c
+a[-b]c & a-c a-c
+a[^]b]c & adc adc
+a[^-b]c & adc adc
+a[b-]c & a-c a-c
+a[b &C EBRACK
+a[] &C EBRACK
+a[1-3]c & a2c a2c
+a[3-1]c &C ERANGE
+a[1-3-5]c &C ERANGE
+a[[.-.]--]c & a-c a-c
+a[1- &C ERANGE
+a[[. &C EBRACK
+a[[.x &C EBRACK
+a[[.x. &C EBRACK
+a[[.x.] &C EBRACK
+a[[.x.]] & ax ax
+a[[.x,.]] &C ECOLLATE
+a[[.one.]]b & a1b a1b
+a[[.notdef.]]b &C ECOLLATE
+a[[.].]]b & a]b a]b
+a[[:alpha:]]c & abc abc
+a[[:notdef:]]c &C ECTYPE
+a[[: &C EBRACK
+a[[:alpha &C EBRACK
+a[[:alpha:] &C EBRACK
+a[[:alpha,:] &C ECTYPE
+a[[:]:]]b &C ECTYPE
+a[[:-:]]b &C ECTYPE
+a[[:alph:]] &C ECTYPE
+a[[:alphabet:]] &C ECTYPE
+[[:alnum:]]+ - -%@a0X- a0X
+[[:alpha:]]+ - -%@aX0- aX
+[[:blank:]]+ - aSSTb SST
+[[:cntrl:]]+ - aNTb NT
+[[:digit:]]+ - a019b 019
+[[:graph:]]+ - Sa%bS a%b
+[[:lower:]]+ - AabC ab
+[[:print:]]+ - NaSbN aSb
+[[:punct:]]+ - S%-&T %-&
+[[:space:]]+ - aSNTb SNT
+[[:upper:]]+ - aBCd BC
+[[:xdigit:]]+ - p0f3Cq 0f3C
+a[[=b=]]c & abc abc
+a[[= &C EBRACK
+a[[=b &C EBRACK
+a[[=b= &C EBRACK
+a[[=b=] &C EBRACK
+a[[=b,=]] &C ECOLLATE
+a[[=one=]]b & a1b a1b
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in b/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in
new file mode 100644
index 0000000..ea3faf9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/c_comments.in
@@ -0,0 +1,17 @@
+# Let's have some fun -- try to match a C comment.
+# first the obvious, which looks okay at first glance...
+/\*.*\*/ - /*x*/ /*x*/
+# but...
+/\*.*\*/ - /*x*/y/*z*/ /*x*/y/*z*/
+# okay, we must not match */ inside; try to do that...
+/\*([^*]|\*[^/])*\*/ - /*x*/ /*x*/
+/\*([^*]|\*[^/])*\*/ - /*x*/y/*z*/ /*x*/
+# but...
+/\*([^*]|\*[^/])*\*/ - /*x**/y/*z*/ /*x**/y/*z*/
+# and a still fancier version, which does it right (I think)...
+/\*([^*]|\*+[^*/])*\*+/ - /*x*/ /*x*/
+/\*([^*]|\*+[^*/])*\*+/ - /*x*/y/*z*/ /*x*/
+/\*([^*]|\*+[^*/])*\*+/ - /*x**/y/*z*/ /*x**/
+/\*([^*]|\*+[^*/])*\*+/ - /*x****/y/*z*/ /*x****/
+/\*([^*]|\*+[^*/])*\*+/ - /*x**x*/y/*z*/ /*x**x*/
+/\*([^*]|\*+[^*/])*\*+/ - /*x***x/y/*z*/ /*x***x/y/*z*/
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/complex.in b/contrib/netbsd-tests/lib/libc/regex/data/complex.in
new file mode 100644
index 0000000..e114058
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/complex.in
@@ -0,0 +1,23 @@
+# complexities
+a(((b)))c - abc abc
+a(b|(c))d - abd abd
+a(b*|c)d - abbd abbd
+# just gotta have one DFA-buster, of course
+a[ab]{20} - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab
+# and an inline expansion in case somebody gets tricky
+a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab] - aaaaabaaaabaaaabaaaab aaaaabaaaabaaaabaaaab
+# and in case somebody just slips in an NFA...
+a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night) - aaaaabaaaabaaaabaaaabweeknights aaaaabaaaabaaaabaaaabweeknights
+# fish for anomalies as the number of states passes 32
+12345678901234567890123456789 - a12345678901234567890123456789b 12345678901234567890123456789
+123456789012345678901234567890 - a123456789012345678901234567890b 123456789012345678901234567890
+1234567890123456789012345678901 - a1234567890123456789012345678901b 1234567890123456789012345678901
+12345678901234567890123456789012 - a12345678901234567890123456789012b 12345678901234567890123456789012
+123456789012345678901234567890123 - a123456789012345678901234567890123b 123456789012345678901234567890123
+# and one really big one, beyond any plausible word width
+1234567890123456789012345678901234567890123456789012345678901234567890 - a1234567890123456789012345678901234567890123456789012345678901234567890b 1234567890123456789012345678901234567890123456789012345678901234567890
+# fish for problems as brackets go past 8
+[ab][cd][ef][gh][ij][kl][mn] - xacegikmoq acegikm
+[ab][cd][ef][gh][ij][kl][mn][op] - xacegikmoq acegikmo
+[ab][cd][ef][gh][ij][kl][mn][op][qr] - xacegikmoqy acegikmoq
+[ab][cd][ef][gh][ij][kl][mn][op][q] - xacegikmoqy acegikmoq
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/error.in b/contrib/netbsd-tests/lib/libc/regex/data/error.in
new file mode 100644
index 0000000..61e0ea4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/error.in
@@ -0,0 +1,30 @@
+# certain syntax errors and non-errors
+| C EMPTY
+| b | |
+* C BADRPT
+* b * *
++ C BADRPT
+? C BADRPT
+"" &C EMPTY
+() - abc @abc
+\(\) b abc @abc
+a||b C EMPTY
+|ab C EMPTY
+ab| C EMPTY
+(|a)b C EMPTY
+(a|)b C EMPTY
+(*a) C BADRPT
+(+a) C BADRPT
+(?a) C BADRPT
+({1}a) C BADRPT
+\(\{1\}a\) bC BADRPT
+(a|*b) C BADRPT
+(a|+b) C BADRPT
+(a|?b) C BADRPT
+(a|{1}b) C BADRPT
+^* C BADRPT
+^* b * *
+^+ C BADRPT
+^? C BADRPT
+^{1} C BADRPT
+^\{1\} bC BADRPT
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/meta.in b/contrib/netbsd-tests/lib/libc/regex/data/meta.in
new file mode 100644
index 0000000..4533d35
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/meta.in
@@ -0,0 +1,21 @@
+# metacharacters, backslashes
+a.c & abc abc
+a[bc]d & abd abd
+a\*c & a*c a*c
+a\\b & a\b a\b
+a\\\*b & a\*b a\*b
+a\bc & abc abc
+a\ &C EESCAPE
+a\\bc & a\bc a\bc
+\{ bC BADRPT
+a\[b & a[b a[b
+a[b &C EBRACK
+# trailing $ is a peculiar special case for the BRE code
+a$ & a a
+a$ & a$
+a\$ & a
+a\$ & a$ a$
+a\\$ & a
+a\\$ & a$
+a\\$ & a\$
+a\\$ & a\ a\
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/nospec.in b/contrib/netbsd-tests/lib/libc/regex/data/nospec.in
new file mode 100644
index 0000000..baf8d04
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/nospec.in
@@ -0,0 +1,7 @@
+# plain strings, with the NOSPEC flag
+abc m abc abc
+abc m xabcy abc
+abc m xyz
+a*b m aba*b a*b
+a*b m ab
+"" mC EMPTY
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/paren.in b/contrib/netbsd-tests/lib/libc/regex/data/paren.in
new file mode 100644
index 0000000..9d206ce
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/paren.in
@@ -0,0 +1,19 @@
+# parentheses and perversions thereof
+a(b)c - abc abc
+a\(b\)c b abc abc
+a( C EPAREN
+a( b a( a(
+a\( - a( a(
+a\( bC EPAREN
+a\(b bC EPAREN
+a(b C EPAREN
+a(b b a(b a(b
+# gag me with a right parenthesis -- 1003.2 goofed here (my fault, partly)
+a) - a) a)
+) - ) )
+# end gagging (in a just world, those *should* give EPAREN)
+a) b a) a)
+a\) bC EPAREN
+\) bC EPAREN
+a()b - ab ab
+a\(\)b b ab ab
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/regress.in b/contrib/netbsd-tests/lib/libc/regex/data/regress.in
new file mode 100644
index 0000000..afd832a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/regress.in
@@ -0,0 +1,9 @@
+# past problems, and suspected problems
+(A[1])|(A[2])|(A[3])|(A[4])|(A[5])|(A[6])|(A[7])|(A[8])|(A[9])|(A[A]) - A1 A1
+abcdefghijklmnop i abcdefghijklmnop abcdefghijklmnop
+abcdefghijklmnopqrstuv i abcdefghijklmnopqrstuv abcdefghijklmnopqrstuv
+(ALAK)|(ALT[AB])|(CC[123]1)|(CM[123]1)|(GAMC)|(LC[23][EO ])|(SEM[1234])|(SL[ES][12])|(SLWW)|(SLF )|(SLDT)|(VWH[12])|(WH[34][EW])|(WP1[ESN]) - CC11 CC11
+CC[13]1|a{21}[23][EO][123][Es][12]a{15}aa[34][EW]aaaaaaa[X]a - CC11 CC11
+Char \([a-z0-9_]*\)\[.* b Char xyz[k Char xyz[k xyz
+a?b - ab ab
+-\{0,1\}[0-9]*$ b -5 -5
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in
new file mode 100644
index 0000000..ee6ff4c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in
@@ -0,0 +1,45 @@
+# the dreaded bounded repetitions
+{ & { {
+{abc & {abc {abc
+{1 C BADRPT
+{1} C BADRPT
+a{b & a{b a{b
+a{1}b - ab ab
+a\{1\}b b ab ab
+a{1,}b - ab ab
+a\{1,\}b b ab ab
+a{1,2}b - aab aab
+a\{1,2\}b b aab aab
+a{1 C EBRACE
+a\{1 bC EBRACE
+a{1a C EBRACE
+a\{1a bC EBRACE
+a{1a} C BADBR
+a\{1a\} bC BADBR
+a{,2} - a{,2} a{,2}
+a\{,2\} bC BADBR
+a{,} - a{,} a{,}
+a\{,\} bC BADBR
+a{1,x} C BADBR
+a\{1,x\} bC BADBR
+a{1,x C EBRACE
+a\{1,x bC EBRACE
+a{300} C BADBR
+a\{300\} bC BADBR
+a{1,0} C BADBR
+a\{1,0\} bC BADBR
+ab{0,0}c - abcac ac
+ab\{0,0\}c b abcac ac
+ab{0,1}c - abcac abc
+ab\{0,1\}c b abcac abc
+ab{0,3}c - abbcac abbc
+ab\{0,3\}c b abbcac abbc
+ab{1,1}c - acabc abc
+ab\{1,1\}c b acabc abc
+ab{1,3}c - acabc abc
+ab\{1,3\}c b acabc abc
+ab{2,2}c - abcabbc abbc
+ab\{2,2\}c b abcabbc abbc
+ab{2,4}c - abcabbc abbc
+ab\{2,4\}c b abcabbc abbc
+((a{1,10}){1,10}){1,10} - a a a,a
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in
new file mode 100644
index 0000000..da97bad
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in
@@ -0,0 +1,21 @@
+# multiple repetitions
+a** &C BADRPT
+a++ C BADRPT
+a?? C BADRPT
+a*+ C BADRPT
+a*? C BADRPT
+a+* C BADRPT
+a+? C BADRPT
+a?* C BADRPT
+a?+ C BADRPT
+a{1}{1} C BADRPT
+a*{1} C BADRPT
+a+{1} C BADRPT
+a?{1} C BADRPT
+a{1}* C BADRPT
+a{1}+ C BADRPT
+a{1}? C BADRPT
+a*{b} - a{b} a{b}
+a\{1\}\{1\} bC BADRPT
+a*\{1\} bC BADRPT
+a\{1\}* bC BADRPT
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in b/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in
new file mode 100644
index 0000000..08bc286
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in
@@ -0,0 +1,10 @@
+# ordinary repetitions
+ab*c & abc abc
+ab+c - abc abc
+ab?c - abc abc
+a\(*\)b b a*b a*b
+a\(**\)b b ab ab
+a\(***\)b bC BADRPT
+*a b *a *a
+**a b a a
+***a bC BADRPT
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/startend.in b/contrib/netbsd-tests/lib/libc/regex/data/startend.in
new file mode 100644
index 0000000..c396e58
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/startend.in
@@ -0,0 +1,9 @@
+# check out the STARTEND option
+[abc] &# a(b)c b
+[abc] &# a(d)c
+[abc] &# a(bc)d b
+[abc] &# a(dc)d c
+. &# a()c
+b.*c &# b(bc)c bc
+b.* &# b(bc)c bc
+.*c &# b(bc)c bc
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/subexp.in b/contrib/netbsd-tests/lib/libc/regex/data/subexp.in
new file mode 100644
index 0000000..c7bcc06
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/subexp.in
@@ -0,0 +1,57 @@
+# subexpressions
+a(b)(c)d - abcd abcd b,c
+a(((b)))c - abc abc b,b,b
+a(b|(c))d - abd abd b,-
+a(b*|c|e)d - abbd abbd bb
+a(b*|c|e)d - acd acd c
+a(b*|c|e)d - ad ad @d
+a(b?)c - abc abc b
+a(b?)c - ac ac @c
+a(b+)c - abc abc b
+a(b+)c - abbbc abbbc bbb
+a(b*)c - ac ac @c
+(a|ab)(bc([de]+)f|cde) - abcdef abcdef a,bcdef,de
+# the regression tester only asks for 9 subexpressions
+a(b)(c)(d)(e)(f)(g)(h)(i)(j)k - abcdefghijk abcdefghijk b,c,d,e,f,g,h,i,j
+a(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)l - abcdefghijkl abcdefghijkl b,c,d,e,f,g,h,i,j,k
+a([bc]?)c - abc abc b
+a([bc]?)c - ac ac @c
+a([bc]+)c - abc abc b
+a([bc]+)c - abcc abcc bc
+a([bc]+)bc - abcbc abcbc bc
+a(bb+|b)b - abb abb b
+a(bbb+|bb+|b)b - abb abb b
+a(bbb+|bb+|b)b - abbb abbb bb
+a(bbb+|bb+|b)bb - abbb abbb b
+(.*).* - abcdef abcdef abcdef
+(a*)* - bc @b @b
+
+# do we get the right subexpression when it is used more than once?
+a(b|c)*d - ad ad -
+a(b|c)*d - abcd abcd c
+a(b|c)+d - abd abd b
+a(b|c)+d - abcd abcd c
+a(b|c?)+d - ad ad @d
+a(b|c?)+d - abcd abcd @d
+a(b|c){0,0}d - ad ad -
+a(b|c){0,1}d - ad ad -
+a(b|c){0,1}d - abd abd b
+a(b|c){0,2}d - ad ad -
+a(b|c){0,2}d - abcd abcd c
+a(b|c){0,}d - ad ad -
+a(b|c){0,}d - abcd abcd c
+a(b|c){1,1}d - abd abd b
+a(b|c){1,1}d - acd acd c
+a(b|c){1,2}d - abd abd b
+a(b|c){1,2}d - abcd abcd c
+a(b|c){1,}d - abd abd b
+a(b|c){1,}d - abcd abcd c
+a(b|c){2,2}d - acbd acbd b
+a(b|c){2,2}d - abcd abcd c
+a(b|c){2,4}d - abcd abcd c
+a(b|c){2,4}d - abcbd abcbd b
+a(b|c){2,4}d - abcbcd abcbcd c
+a(b|c){2,}d - abcd abcd c
+a(b|c){2,}d - abcbd abcbd b
+a(b+|((c)*))+d - abd abd @d,@d,-
+a(b+|((c)*))+d - abcd abcd @d,@d,-
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/subtle.in b/contrib/netbsd-tests/lib/libc/regex/data/subtle.in
new file mode 100644
index 0000000..92d68bb
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/subtle.in
@@ -0,0 +1,21 @@
+# subtleties of matching
+abc & xabcy abc
+a\(b\)?c\1d b acd
+aBc i Abc Abc
+a[Bc]*d i abBCcd abBCcd
+0[[:upper:]]1 &i 0a1 0a1
+0[[:lower:]]1 &i 0A1 0A1
+a[^b]c &i abc
+a[^b]c &i aBc
+a[^b]c &i adc adc
+[a]b[c] - abc abc
+[a]b[a] - aba aba
+[abc]b[abc] - abc abc
+[abc]b[abd] - abd abd
+a(b?c)+d - accd accd
+(wee|week)(knights|night) - weeknights weeknights
+(we|wee|week|frob)(knights|night|day) - weeknights weeknights
+a[bc]d - xyzaaabcaababdacd abd
+a[ab]c - aaabc abc
+abc s abc abc
+a* & b @b
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in b/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in
new file mode 100644
index 0000000..e09a329
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/word_bound.in
@@ -0,0 +1,13 @@
+# word boundaries (ick)
+[[:<:]]a & a a
+[[:<:]]a & ba
+[[:<:]]a & -a a
+a[[:>:]] & a a
+a[[:>:]] & ab
+a[[:>:]] & a- a
+[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc abc
+[[:<:]]a.c[[:>:]] & axcd-dayc-dazce-abc-q abc
+[[:<:]]a.c[[:>:]] & axc-dayc-dazce-abc axc
+[[:<:]]b.c[[:>:]] & a_bxc-byc_d-bzc-q bzc
+[[:<:]].x..[[:>:]] & y_xa_-_xb_y-_xc_-axdc _xc_
+[[:<:]]a_b[[:>:]] & x_a_b
diff --git a/contrib/netbsd-tests/lib/libc/regex/data/zero.in b/contrib/netbsd-tests/lib/libc/regex/data/zero.in
new file mode 100644
index 0000000..2786944
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/data/zero.in
@@ -0,0 +1,7 @@
+# cases involving NULs
+aZb & a a
+aZb &p a
+aZb &p# (aZb) aZb
+aZ*b &p# (ab) ab
+a.b &# (aZb) aZb
+a.* &# (aZb)c aZb
diff --git a/contrib/netbsd-tests/lib/libc/regex/debug.c b/contrib/netbsd-tests/lib/libc/regex/debug.c
new file mode 100644
index 0000000..f1d2b15
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/debug.c
@@ -0,0 +1,278 @@
+/* $NetBSD: debug.c,v 1.2 2011/10/10 04:32:41 christos Exp $ */
+
+/*-
+ * Copyright (c) 1993 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 <ctype.h>
+#include <limits.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#ifdef __FreeBSD__
+#include <wchar.h>
+#include <wctype.h>
+#endif
+
+/* Don't sort these! */
+#include "utils.h"
+#include "regex2.h"
+
+#include "test_regex.h"
+
+static void s_print(struct re_guts *, FILE *);
+static char *regchar(int);
+
+/*
+ * regprint - print a regexp for debugging
+ */
+void
+regprint(regex_t *r, FILE *d)
+{
+#ifdef __NetBSD__
+ struct re_guts *g = r->re_g;
+ int c;
+ int last;
+ int nincat[NC];
+
+ fprintf(d, "%ld states, %zu categories", (long)g->nstates,
+ g->ncategories);
+ fprintf(d, ", first %ld last %ld", (long)g->firststate,
+ (long)g->laststate);
+ if (g->iflags&USEBOL)
+ fprintf(d, ", USEBOL");
+ if (g->iflags&USEEOL)
+ fprintf(d, ", USEEOL");
+ if (g->iflags&BAD)
+ fprintf(d, ", BAD");
+ if (g->nsub > 0)
+ fprintf(d, ", nsub=%ld", (long)g->nsub);
+ if (g->must != NULL)
+ fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
+ g->must);
+ if (g->backrefs)
+ fprintf(d, ", backrefs");
+ if (g->nplus > 0)
+ fprintf(d, ", nplus %ld", (long)g->nplus);
+ fprintf(d, "\n");
+ s_print(g, d);
+ for (size_t i = 0; i < g->ncategories; i++) {
+ nincat[i] = 0;
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (g->categories[c] == i)
+ nincat[i]++;
+ }
+ fprintf(d, "cc0#%d", nincat[0]);
+ for (size_t i = 1; i < g->ncategories; i++)
+ if (nincat[i] == 1) {
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (g->categories[c] == i)
+ break;
+ fprintf(d, ", %zu=%s", i, regchar(c));
+ }
+ fprintf(d, "\n");
+ for (size_t i = 1; i < g->ncategories; i++)
+ if (nincat[i] != 1) {
+ fprintf(d, "cc%zu\t", i);
+ last = -1;
+ for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */
+ if (c <= CHAR_MAX && g->categories[c] == i) {
+ if (last < 0) {
+ fprintf(d, "%s", regchar(c));
+ last = c;
+ }
+ } else {
+ if (last >= 0) {
+ if (last != c-1)
+ fprintf(d, "-%s",
+ regchar(c-1));
+ last = -1;
+ }
+ }
+ fprintf(d, "\n");
+ }
+#endif
+}
+
+/*
+ * s_print - print the strip for debugging
+ */
+static void
+s_print(struct re_guts *g, FILE *d)
+{
+ sop *s;
+ cset *cs;
+ int done = 0;
+ sop opnd;
+ int col = 0;
+ ssize_t last;
+ sopno offset = 2;
+# define GAP() { if (offset % 5 == 0) { \
+ if (col > 40) { \
+ fprintf(d, "\n\t"); \
+ col = 0; \
+ } else { \
+ fprintf(d, " "); \
+ col++; \
+ } \
+ } else \
+ col++; \
+ offset++; \
+ }
+
+ if (OP(g->strip[0]) != OEND)
+ fprintf(d, "missing initial OEND!\n");
+ for (s = &g->strip[1]; !done; s++) {
+ opnd = OPND(*s);
+ switch (OP(*s)) {
+ case OEND:
+ fprintf(d, "\n");
+ done = 1;
+ break;
+ case OCHAR:
+ if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
+ fprintf(d, "\\%c", (char)opnd);
+ else
+ fprintf(d, "%s", regchar((char)opnd));
+ break;
+ case OBOL:
+ fprintf(d, "^");
+ break;
+ case OEOL:
+ fprintf(d, "$");
+ break;
+ case OBOW:
+ fprintf(d, "\\{");
+ break;
+ case OEOW:
+ fprintf(d, "\\}");
+ break;
+ case OANY:
+ fprintf(d, ".");
+ break;
+ case OANYOF:
+ fprintf(d, "[(%ld)", (long)opnd);
+#ifdef __NetBSD__
+ cs = &g->sets[opnd];
+ last = -1;
+ for (size_t i = 0; i < g->csetsize+1; i++) /* +1 flushes */
+ if (CHIN(cs, i) && i < g->csetsize) {
+ if (last < 0) {
+ fprintf(d, "%s", regchar(i));
+ last = i;
+ }
+ } else {
+ if (last >= 0) {
+ if (last != (ssize_t)i - 1)
+ fprintf(d, "-%s",
+ regchar(i - 1));
+ last = -1;
+ }
+ }
+#endif
+ fprintf(d, "]");
+ break;
+ case OBACK_:
+ fprintf(d, "(\\<%ld>", (long)opnd);
+ break;
+ case O_BACK:
+ fprintf(d, "<%ld>\\)", (long)opnd);
+ break;
+ case OPLUS_:
+ fprintf(d, "(+");
+ if (OP(*(s+opnd)) != O_PLUS)
+ fprintf(d, "<%ld>", (long)opnd);
+ break;
+ case O_PLUS:
+ if (OP(*(s-opnd)) != OPLUS_)
+ fprintf(d, "<%ld>", (long)opnd);
+ fprintf(d, "+)");
+ break;
+ case OQUEST_:
+ fprintf(d, "(?");
+ if (OP(*(s+opnd)) != O_QUEST)
+ fprintf(d, "<%ld>", (long)opnd);
+ break;
+ case O_QUEST:
+ if (OP(*(s-opnd)) != OQUEST_)
+ fprintf(d, "<%ld>", (long)opnd);
+ fprintf(d, "?)");
+ break;
+ case OLPAREN:
+ fprintf(d, "((<%ld>", (long)opnd);
+ break;
+ case ORPAREN:
+ fprintf(d, "<%ld>))", (long)opnd);
+ break;
+ case OCH_:
+ fprintf(d, "<");
+ if (OP(*(s+opnd)) != OOR2)
+ fprintf(d, "<%ld>", (long)opnd);
+ break;
+ case OOR1:
+ if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
+ fprintf(d, "<%ld>", (long)opnd);
+ fprintf(d, "|");
+ break;
+ case OOR2:
+ fprintf(d, "|");
+ if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
+ fprintf(d, "<%ld>", (long)opnd);
+ break;
+ case O_CH:
+ if (OP(*(s-opnd)) != OOR1)
+ fprintf(d, "<%ld>", (long)opnd);
+ fprintf(d, ">");
+ break;
+ default:
+#ifdef __FreeBSD__
+ fprintf(d, "!%ld(%ld)!", OP(*s), opnd);
+#else
+ fprintf(d, "!%d(%d)!", OP(*s), opnd);
+#endif
+ break;
+ }
+ if (!done)
+ GAP();
+ }
+}
+
+/*
+ * regchar - make a character printable
+ */
+static char * /* -> representation */
+regchar(int ch)
+{
+ static char buf[10];
+
+ if (isprint(ch) || ch == ' ')
+ sprintf(buf, "%c", ch);
+ else
+ sprintf(buf, "\\%o", ch);
+ return(buf);
+}
diff --git a/contrib/netbsd-tests/lib/libc/regex/main.c b/contrib/netbsd-tests/lib/libc/regex/main.c
new file mode 100644
index 0000000..eac4e2d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/main.c
@@ -0,0 +1,523 @@
+/* $NetBSD: main.c,v 1.2 2011/09/16 16:13:18 plunky Exp $ */
+
+/*-
+ * Copyright (c) 1993 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 <assert.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+
+#include "test_regex.h"
+
+char *progname;
+int debug = 0;
+int line = 0;
+int status = 0;
+
+int copts = REG_EXTENDED;
+int eopts = 0;
+regoff_t startoff = 0;
+regoff_t endoff = 0;
+
+static char empty = '\0';
+
+static char *eprint(int);
+static int efind(char *);
+
+/*
+ * main - do the simple case, hand off to regress() for regression
+ */
+int
+main(int argc, char *argv[])
+{
+ regex_t re;
+# define NS 10
+ regmatch_t subs[NS];
+ char erbuf[100];
+ int err;
+ size_t len;
+ int c;
+ int errflg = 0;
+ int i;
+ extern int optind;
+ extern char *optarg;
+
+ progname = argv[0];
+
+ while ((c = getopt(argc, argv, "c:e:S:E:x")) != -1)
+ switch (c) {
+ case 'c': /* compile options */
+ copts = options('c', optarg);
+ break;
+ case 'e': /* execute options */
+ eopts = options('e', optarg);
+ break;
+ case 'S': /* start offset */
+ startoff = (regoff_t)atoi(optarg);
+ break;
+ case 'E': /* end offset */
+ endoff = (regoff_t)atoi(optarg);
+ break;
+ case 'x': /* Debugging. */
+ debug++;
+ break;
+ case '?':
+ default:
+ errflg++;
+ break;
+ }
+ if (errflg) {
+ fprintf(stderr, "usage: %s ", progname);
+ fprintf(stderr, "[-c copt][-C][-d] [re]\n");
+ exit(2);
+ }
+
+ if (optind >= argc) {
+ regress(stdin);
+ exit(status);
+ }
+
+ err = regcomp(&re, argv[optind++], copts);
+ if (err) {
+ len = regerror(err, &re, erbuf, sizeof(erbuf));
+ fprintf(stderr, "error %s, %zd/%zd `%s'\n",
+ eprint(err), len, (size_t)sizeof(erbuf), erbuf);
+ exit(status);
+ }
+ regprint(&re, stdout);
+
+ if (optind >= argc) {
+ regfree(&re);
+ exit(status);
+ }
+
+ if (eopts&REG_STARTEND) {
+ subs[0].rm_so = startoff;
+ subs[0].rm_eo = strlen(argv[optind]) - endoff;
+ }
+ err = regexec(&re, argv[optind], (size_t)NS, subs, eopts);
+ if (err) {
+ len = regerror(err, &re, erbuf, sizeof(erbuf));
+ fprintf(stderr, "error %s, %zd/%zd `%s'\n",
+ eprint(err), len, (size_t)sizeof(erbuf), erbuf);
+ exit(status);
+ }
+ if (!(copts&REG_NOSUB)) {
+ len = (int)(subs[0].rm_eo - subs[0].rm_so);
+ if (subs[0].rm_so != -1) {
+ if (len != 0)
+ printf("match `%.*s'\n", (int)len,
+ argv[optind] + subs[0].rm_so);
+ else
+ printf("match `'@%.1s\n",
+ argv[optind] + subs[0].rm_so);
+ }
+ for (i = 1; i < NS; i++)
+ if (subs[i].rm_so != -1)
+ printf("(%d) `%.*s'\n", i,
+ (int)(subs[i].rm_eo - subs[i].rm_so),
+ argv[optind] + subs[i].rm_so);
+ }
+ exit(status);
+}
+
+/*
+ * regress - main loop of regression test
+ */
+void
+regress(FILE *in)
+{
+ char inbuf[1000];
+# define MAXF 10
+ char *f[MAXF];
+ int nf;
+ int i;
+ char erbuf[100];
+ size_t ne;
+ const char *badpat = "invalid regular expression";
+# define SHORT 10
+ const char *bpname = "REG_BADPAT";
+ regex_t re;
+
+ while (fgets(inbuf, sizeof(inbuf), in) != NULL) {
+ line++;
+ if (inbuf[0] == '#' || inbuf[0] == '\n')
+ continue; /* NOTE CONTINUE */
+ inbuf[strlen(inbuf)-1] = '\0'; /* get rid of stupid \n */
+ if (debug)
+ fprintf(stdout, "%d:\n", line);
+ nf = split(inbuf, f, MAXF, "\t\t");
+ if (nf < 3) {
+ fprintf(stderr, "bad input, line %d\n", line);
+ exit(1);
+ }
+ for (i = 0; i < nf; i++)
+ if (strcmp(f[i], "\"\"") == 0)
+ f[i] = &empty;
+ if (nf <= 3)
+ f[3] = NULL;
+ if (nf <= 4)
+ f[4] = NULL;
+ try(f[0], f[1], f[2], f[3], f[4], options('c', f[1]));
+ if (opt('&', f[1])) /* try with either type of RE */
+ try(f[0], f[1], f[2], f[3], f[4],
+ options('c', f[1]) &~ REG_EXTENDED);
+ }
+
+ ne = regerror(REG_BADPAT, NULL, erbuf, sizeof(erbuf));
+ if (strcmp(erbuf, badpat) != 0 || ne != strlen(badpat)+1) {
+ fprintf(stderr, "end: regerror() test gave `%s' not `%s'\n",
+ erbuf, badpat);
+ status = 1;
+ }
+ ne = regerror(REG_BADPAT, NULL, erbuf, (size_t)SHORT);
+ if (strncmp(erbuf, badpat, SHORT-1) != 0 || erbuf[SHORT-1] != '\0' ||
+ ne != strlen(badpat)+1) {
+ fprintf(stderr, "end: regerror() short test gave `%s' not `%.*s'\n",
+ erbuf, SHORT-1, badpat);
+ status = 1;
+ }
+ ne = regerror(REG_ITOA|REG_BADPAT, NULL, erbuf, sizeof(erbuf));
+ if (strcmp(erbuf, bpname) != 0 || ne != strlen(bpname)+1) {
+ fprintf(stderr, "end: regerror() ITOA test gave `%s' not `%s'\n",
+ erbuf, bpname);
+ status = 1;
+ }
+ re.re_endp = bpname;
+ ne = regerror(REG_ATOI, &re, erbuf, sizeof(erbuf));
+ if (atoi(erbuf) != (int)REG_BADPAT) {
+ fprintf(stderr, "end: regerror() ATOI test gave `%s' not `%ld'\n",
+ erbuf, (long)REG_BADPAT);
+ status = 1;
+ } else if (ne != strlen(erbuf)+1) {
+ fprintf(stderr, "end: regerror() ATOI test len(`%s') = %ld\n",
+ erbuf, (long)REG_BADPAT);
+ status = 1;
+ }
+}
+
+/*
+ - try - try it, and report on problems
+ == void try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts);
+ */
+void
+try(char *f0, char *f1, char *f2, char *f3, char *f4, int opts)
+{
+ regex_t re;
+# define NSUBS 10
+ regmatch_t subs[NSUBS];
+# define NSHOULD 15
+ char *should[NSHOULD];
+ int nshould;
+ char erbuf[100];
+ int err;
+ int len;
+ const char *type = (opts & REG_EXTENDED) ? "ERE" : "BRE";
+ int i;
+ char *grump;
+ char f0copy[1000];
+ char f2copy[1000];
+
+ strcpy(f0copy, f0);
+ re.re_endp = (opts&REG_PEND) ? f0copy + strlen(f0copy) : NULL;
+ fixstr(f0copy);
+ err = regcomp(&re, f0copy, opts);
+ if (err != 0 && (!opt('C', f1) || err != efind(f2))) {
+ /* unexpected error or wrong error */
+ len = regerror(err, &re, erbuf, sizeof(erbuf));
+ fprintf(stderr, "%d: %s error %s, %d/%d `%s'\n",
+ line, type, eprint(err), len,
+ (int)sizeof(erbuf), erbuf);
+ status = 1;
+ } else if (err == 0 && opt('C', f1)) {
+ /* unexpected success */
+ fprintf(stderr, "%d: %s should have given REG_%s\n",
+ line, type, f2);
+ status = 1;
+ err = 1; /* so we won't try regexec */
+ }
+
+ if (err != 0) {
+ regfree(&re);
+ return;
+ }
+
+ strcpy(f2copy, f2);
+ fixstr(f2copy);
+
+ if (options('e', f1)&REG_STARTEND) {
+ if (strchr(f2, '(') == NULL || strchr(f2, ')') == NULL)
+ fprintf(stderr, "%d: bad STARTEND syntax\n", line);
+ subs[0].rm_so = strchr(f2, '(') - f2 + 1;
+ subs[0].rm_eo = strchr(f2, ')') - f2;
+ }
+ err = regexec(&re, f2copy, NSUBS, subs, options('e', f1));
+
+ if (err != 0 && (f3 != NULL || err != REG_NOMATCH)) {
+ /* unexpected error or wrong error */
+ len = regerror(err, &re, erbuf, sizeof(erbuf));
+ fprintf(stderr, "%d: %s exec error %s, %d/%d `%s'\n",
+ line, type, eprint(err), len,
+ (int)sizeof(erbuf), erbuf);
+ status = 1;
+ } else if (err != 0) {
+ /* nothing more to check */
+ } else if (f3 == NULL) {
+ /* unexpected success */
+ fprintf(stderr, "%d: %s exec should have failed\n",
+ line, type);
+ status = 1;
+ err = 1; /* just on principle */
+ } else if (opts&REG_NOSUB) {
+ /* nothing more to check */
+ } else if ((grump = check(f2, subs[0], f3)) != NULL) {
+ fprintf(stderr, "%d: %s %s\n", line, type, grump);
+ status = 1;
+ err = 1;
+ }
+
+ if (err != 0 || f4 == NULL) {
+ regfree(&re);
+ return;
+ }
+
+ for (i = 1; i < NSHOULD; i++)
+ should[i] = NULL;
+ nshould = split(f4, &should[1], NSHOULD-1, ",");
+ if (nshould == 0) {
+ nshould = 1;
+ should[1] = &empty;
+ }
+ for (i = 1; i < NSUBS; i++) {
+ grump = check(f2, subs[i], should[i]);
+ if (grump != NULL) {
+ fprintf(stderr, "%d: %s $%d %s\n", line,
+ type, i, grump);
+ status = 1;
+ err = 1;
+ }
+ }
+
+ regfree(&re);
+}
+
+/*
+ - options - pick options out of a regression-test string
+ == int options(int type, char *s);
+ */
+int
+options(int type, char *s)
+{
+ char *p;
+ int o = (type == 'c') ? copts : eopts;
+ const char *legal = (type == 'c') ? "bisnmp" : "^$#tl";
+
+ for (p = s; *p != '\0'; p++)
+ if (strchr(legal, *p) != NULL)
+ switch (*p) {
+ case 'b':
+ o &= ~REG_EXTENDED;
+ break;
+ case 'i':
+ o |= REG_ICASE;
+ break;
+ case 's':
+ o |= REG_NOSUB;
+ break;
+ case 'n':
+ o |= REG_NEWLINE;
+ break;
+ case 'm':
+ o &= ~REG_EXTENDED;
+ o |= REG_NOSPEC;
+ break;
+ case 'p':
+ o |= REG_PEND;
+ break;
+ case '^':
+ o |= REG_NOTBOL;
+ break;
+ case '$':
+ o |= REG_NOTEOL;
+ break;
+ case '#':
+ o |= REG_STARTEND;
+ break;
+ case 't': /* trace */
+ o |= REG_TRACE;
+ break;
+ case 'l': /* force long representation */
+ o |= REG_LARGE;
+ break;
+ case 'r': /* force backref use */
+ o |= REG_BACKR;
+ break;
+ }
+ return(o);
+}
+
+/*
+ - opt - is a particular option in a regression string?
+ == int opt(int c, char *s);
+ */
+int /* predicate */
+opt(int c, char *s)
+{
+ return(strchr(s, c) != NULL);
+}
+
+/*
+ - fixstr - transform magic characters in strings
+ == void fixstr(char *p);
+ */
+void
+fixstr(char *p)
+{
+ if (p == NULL)
+ return;
+
+ for (; *p != '\0'; p++)
+ if (*p == 'N')
+ *p = '\n';
+ else if (*p == 'T')
+ *p = '\t';
+ else if (*p == 'S')
+ *p = ' ';
+ else if (*p == 'Z')
+ *p = '\0';
+}
+
+/*
+ * check - check a substring match
+ */
+char * /* NULL or complaint */
+check(char *str, regmatch_t sub, char *should)
+{
+ int len;
+ int shlen;
+ char *p;
+ static char grump[500];
+ char *at = NULL;
+
+ if (should != NULL && strcmp(should, "-") == 0)
+ should = NULL;
+ if (should != NULL && should[0] == '@') {
+ at = should + 1;
+ should = &empty;
+ }
+
+ /* check rm_so and rm_eo for consistency */
+ if (sub.rm_so > sub.rm_eo || (sub.rm_so == -1 && sub.rm_eo != -1) ||
+ (sub.rm_so != -1 && sub.rm_eo == -1) ||
+ (sub.rm_so != -1 && sub.rm_so < 0) ||
+ (sub.rm_eo != -1 && sub.rm_eo < 0) ) {
+ sprintf(grump, "start %ld end %ld", (long)sub.rm_so,
+ (long)sub.rm_eo);
+ return(grump);
+ }
+
+ /* check for no match */
+ if (sub.rm_so == -1) {
+ if (should == NULL)
+ return(NULL);
+ else {
+ sprintf(grump, "did not match");
+ return(grump);
+ }
+ }
+
+ /* check for in range */
+ if (sub.rm_eo > (ssize_t)strlen(str)) {
+ sprintf(grump, "start %ld end %ld, past end of string",
+ (long)sub.rm_so, (long)sub.rm_eo);
+ return(grump);
+ }
+
+ len = (int)(sub.rm_eo - sub.rm_so);
+ p = str + sub.rm_so;
+
+ /* check for not supposed to match */
+ if (should == NULL) {
+ sprintf(grump, "matched `%.*s'", len, p);
+ return(grump);
+ }
+
+ /* check for wrong match */
+ shlen = (int)strlen(should);
+ if (len != shlen || strncmp(p, should, (size_t)shlen) != 0) {
+ sprintf(grump, "matched `%.*s' instead", len, p);
+ return(grump);
+ }
+ if (shlen > 0)
+ return(NULL);
+
+ /* check null match in right place */
+ if (at == NULL)
+ return(NULL);
+ shlen = strlen(at);
+ if (shlen == 0)
+ shlen = 1; /* force check for end-of-string */
+ if (strncmp(p, at, shlen) != 0) {
+ sprintf(grump, "matched null at `%.20s'", p);
+ return(grump);
+ }
+ return(NULL);
+}
+
+/*
+ * eprint - convert error number to name
+ */
+static char *
+eprint(int err)
+{
+ static char epbuf[100];
+ size_t len;
+
+ len = regerror(REG_ITOA|err, NULL, epbuf, sizeof(epbuf));
+ assert(len <= sizeof(epbuf));
+ return(epbuf);
+}
+
+/*
+ * efind - convert error name to number
+ */
+static int
+efind(char *name)
+{
+ static char efbuf[100];
+ regex_t re;
+
+ sprintf(efbuf, "REG_%s", name);
+ assert(strlen(efbuf) < sizeof(efbuf));
+ re.re_endp = efbuf;
+ (void) regerror(REG_ATOI, &re, efbuf, sizeof(efbuf));
+ return(atoi(efbuf));
+}
diff --git a/contrib/netbsd-tests/lib/libc/regex/split.c b/contrib/netbsd-tests/lib/libc/regex/split.c
new file mode 100644
index 0000000..2a26b50
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/split.c
@@ -0,0 +1,344 @@
+/* $NetBSD: split.c,v 1.1 2011/01/08 18:10:31 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 1993 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 <regex.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "test_regex.h"
+
+/*
+ * split - divide a string into fields, like awk split()
+ *
+ * returns number of fields, including overflow
+ *
+ * fields[] list is not NULL-terminated
+ * nfields number of entries available in fields[]
+ * sep "" white, "c" single char, "ab" [ab]+
+ */
+int
+split(char *string, char *fields[], int nfields, const char *sep)
+{
+ char *p = string;
+ char c; /* latest character */
+ char sepc = *sep;
+ char sepc2;
+ int fn;
+ char **fp = fields;
+ const char *sepp;
+ int trimtrail;
+
+ /* white space */
+ if (sepc == '\0') {
+ while ((c = *p++) == ' ' || c == '\t')
+ continue;
+ p--;
+ trimtrail = 1;
+ sep = " \t"; /* note, code below knows this is 2 long */
+ sepc = ' ';
+ } else
+ trimtrail = 0;
+ sepc2 = sep[1]; /* now we can safely pick this up */
+
+ /* catch empties */
+ if (*p == '\0')
+ return(0);
+
+ /* single separator */
+ if (sepc2 == '\0') {
+ fn = nfields;
+ for (;;) {
+ *fp++ = p;
+ fn--;
+ if (fn == 0)
+ break;
+ while ((c = *p++) != sepc)
+ if (c == '\0')
+ return(nfields - fn);
+ *(p-1) = '\0';
+ }
+ /* we have overflowed the fields vector -- just count them */
+ fn = nfields;
+ for (;;) {
+ while ((c = *p++) != sepc)
+ if (c == '\0')
+ return(fn);
+ fn++;
+ }
+ /* not reached */
+ }
+
+ /* two separators */
+ if (sep[2] == '\0') {
+ fn = nfields;
+ for (;;) {
+ *fp++ = p;
+ fn--;
+ while ((c = *p++) != sepc && c != sepc2)
+ if (c == '\0') {
+ if (trimtrail && **(fp-1) == '\0')
+ fn++;
+ return(nfields - fn);
+ }
+ if (fn == 0)
+ break;
+ *(p-1) = '\0';
+ while ((c = *p++) == sepc || c == sepc2)
+ continue;
+ p--;
+ }
+ /* we have overflowed the fields vector -- just count them */
+ fn = nfields;
+ while (c != '\0') {
+ while ((c = *p++) == sepc || c == sepc2)
+ continue;
+ p--;
+ fn++;
+ while ((c = *p++) != '\0' && c != sepc && c != sepc2)
+ continue;
+ }
+ /* might have to trim trailing white space */
+ if (trimtrail) {
+ p--;
+ while ((c = *--p) == sepc || c == sepc2)
+ continue;
+ p++;
+ if (*p != '\0') {
+ if (fn == nfields+1)
+ *p = '\0';
+ fn--;
+ }
+ }
+ return(fn);
+ }
+
+ /* n separators */
+ fn = 0;
+ for (;;) {
+ if (fn < nfields)
+ *fp++ = p;
+ fn++;
+ for (;;) {
+ c = *p++;
+ if (c == '\0')
+ return(fn);
+ sepp = sep;
+ while ((sepc = *sepp++) != '\0' && sepc != c)
+ continue;
+ if (sepc != '\0') /* it was a separator */
+ break;
+ }
+ if (fn < nfields)
+ *(p-1) = '\0';
+ for (;;) {
+ c = *p++;
+ sepp = sep;
+ while ((sepc = *sepp++) != '\0' && sepc != c)
+ continue;
+ if (sepc == '\0') /* it wasn't a separator */
+ break;
+ }
+ p--;
+ }
+
+ /* not reached */
+}
+
+#ifdef TEST_SPLIT
+
+
+/*
+ * test program
+ * pgm runs regression
+ * pgm sep splits stdin lines by sep
+ * pgm str sep splits str by sep
+ * pgm str sep n splits str by sep n times
+ */
+int
+main(int argc, char *argv[])
+{
+ char buf[512];
+ int n;
+# define MNF 10
+ char *fields[MNF];
+
+ if (argc > 4)
+ for (n = atoi(argv[3]); n > 0; n--) {
+ (void) strcpy(buf, argv[1]);
+ }
+ else if (argc > 3)
+ for (n = atoi(argv[3]); n > 0; n--) {
+ (void) strcpy(buf, argv[1]);
+ (void) split(buf, fields, MNF, argv[2]);
+ }
+ else if (argc > 2)
+ dosplit(argv[1], argv[2]);
+ else if (argc > 1)
+ while (fgets(buf, sizeof(buf), stdin) != NULL) {
+ buf[strlen(buf)-1] = '\0'; /* stomp newline */
+ dosplit(buf, argv[1]);
+ }
+ else
+ regress();
+
+ exit(0);
+}
+
+void
+dosplit(char *string, char *seps)
+{
+# define NF 5
+ char *fields[NF];
+ int nf;
+
+ nf = split(string, fields, NF, seps);
+ print(nf, NF, fields);
+}
+
+void
+print(int nf, int nfp, char *fields)
+{
+ int fn;
+ int bound;
+
+ bound = (nf > nfp) ? nfp : nf;
+ printf("%d:\t", nf);
+ for (fn = 0; fn < bound; fn++)
+ printf("\"%s\"%s", fields[fn], (fn+1 < nf) ? ", " : "\n");
+}
+
+#define RNF 5 /* some table entries know this */
+struct {
+ char *str;
+ char *seps;
+ int nf;
+ char *fi[RNF];
+} tests[] = {
+ "", " ", 0, { "" },
+ " ", " ", 2, { "", "" },
+ "x", " ", 1, { "x" },
+ "xy", " ", 1, { "xy" },
+ "x y", " ", 2, { "x", "y" },
+ "abc def g ", " ", 5, { "abc", "def", "", "g", "" },
+ " a bcd", " ", 4, { "", "", "a", "bcd" },
+ "a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" },
+ " a b c d ", " ", 6, { "", "a", "b", "c", "d " },
+
+ "", " _", 0, { "" },
+ " ", " _", 2, { "", "" },
+ "x", " _", 1, { "x" },
+ "x y", " _", 2, { "x", "y" },
+ "ab _ cd", " _", 2, { "ab", "cd" },
+ " a_b c ", " _", 5, { "", "a", "b", "c", "" },
+ "a b c_d e f", " _", 6, { "a", "b", "c", "d", "e f" },
+ " a b c d ", " _", 6, { "", "a", "b", "c", "d " },
+
+ "", " _~", 0, { "" },
+ " ", " _~", 2, { "", "" },
+ "x", " _~", 1, { "x" },
+ "x y", " _~", 2, { "x", "y" },
+ "ab _~ cd", " _~", 2, { "ab", "cd" },
+ " a_b c~", " _~", 5, { "", "a", "b", "c", "" },
+ "a b_c d~e f", " _~", 6, { "a", "b", "c", "d", "e f" },
+ "~a b c d ", " _~", 6, { "", "a", "b", "c", "d " },
+
+ "", " _~-", 0, { "" },
+ " ", " _~-", 2, { "", "" },
+ "x", " _~-", 1, { "x" },
+ "x y", " _~-", 2, { "x", "y" },
+ "ab _~- cd", " _~-", 2, { "ab", "cd" },
+ " a_b c~", " _~-", 5, { "", "a", "b", "c", "" },
+ "a b_c-d~e f", " _~-", 6, { "a", "b", "c", "d", "e f" },
+ "~a-b c d ", " _~-", 6, { "", "a", "b", "c", "d " },
+
+ "", " ", 0, { "" },
+ " ", " ", 2, { "", "" },
+ "x", " ", 1, { "x" },
+ "xy", " ", 1, { "xy" },
+ "x y", " ", 2, { "x", "y" },
+ "abc def g ", " ", 4, { "abc", "def", "g", "" },
+ " a bcd", " ", 3, { "", "a", "bcd" },
+ "a b c d e f", " ", 6, { "a", "b", "c", "d", "e f" },
+ " a b c d ", " ", 6, { "", "a", "b", "c", "d " },
+
+ "", "", 0, { "" },
+ " ", "", 0, { "" },
+ "x", "", 1, { "x" },
+ "xy", "", 1, { "xy" },
+ "x y", "", 2, { "x", "y" },
+ "abc def g ", "", 3, { "abc", "def", "g" },
+ "\t a bcd", "", 2, { "a", "bcd" },
+ " a \tb\t c ", "", 3, { "a", "b", "c" },
+ "a b c d e ", "", 5, { "a", "b", "c", "d", "e" },
+ "a b\tc d e f", "", 6, { "a", "b", "c", "d", "e f" },
+ " a b c d e f ", "", 6, { "a", "b", "c", "d", "e f " },
+
+ NULL, NULL, 0, { NULL },
+};
+
+void
+regress(void)
+{
+ char buf[512];
+ int n;
+ char *fields[RNF+1];
+ int nf;
+ int i;
+ int printit;
+ char *f;
+
+ for (n = 0; tests[n].str != NULL; n++) {
+ (void) strcpy(buf, tests[n].str);
+ fields[RNF] = NULL;
+ nf = split(buf, fields, RNF, tests[n].seps);
+ printit = 0;
+ if (nf != tests[n].nf) {
+ printf("split `%s' by `%s' gave %d fields, not %d\n",
+ tests[n].str, tests[n].seps, nf, tests[n].nf);
+ printit = 1;
+ } else if (fields[RNF] != NULL) {
+ printf("split() went beyond array end\n");
+ printit = 1;
+ } else {
+ for (i = 0; i < nf && i < RNF; i++) {
+ f = fields[i];
+ if (f == NULL)
+ f = "(NULL)";
+ if (strcmp(f, tests[n].fi[i]) != 0) {
+ printf("split `%s' by `%s', field %d is `%s', not `%s'\n",
+ tests[n].str, tests[n].seps,
+ i, fields[i], tests[n].fi[i]);
+ printit = 1;
+ }
+ }
+ }
+ if (printit)
+ print(nf, RNF, fields);
+ }
+}
+#endif
diff --git a/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c b/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c
new file mode 100644
index 0000000..0670e51
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c
@@ -0,0 +1,224 @@
+/* $NetBSD: t_exhaust.c,v 1.7 2011/11/16 18:37:31 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 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/cdefs.h>
+__RCSID("$NetBSD: t_exhaust.c,v 1.7 2011/11/16 18:37:31 christos Exp $");
+
+#include <stdio.h>
+#include <regex.h>
+#include <string.h>
+#include <stdlib.h>
+#include <err.h>
+#include <atf-c.h>
+#ifdef __FreeBSD__
+#include <sys/resource.h>
+#endif
+
+#ifndef REGEX_MAXSIZE
+#define REGEX_MAXSIZE 9999
+#endif
+
+static char *
+mkstr(const char *str, size_t len)
+{
+ size_t slen = strlen(str);
+ char *p = malloc(slen * len + 1);
+ ATF_REQUIRE(p != NULL);
+ for (size_t i = 0; i < len; i++)
+ strcpy(&p[i * slen], str);
+ return p;
+}
+
+static char *
+concat(const char *d, const char *s)
+{
+ size_t dlen = strlen(d);
+ size_t slen = strlen(s);
+ char *p = malloc(dlen + slen + 1);
+
+ ATF_REQUIRE(p != NULL);
+ strcpy(p, d);
+ strcpy(p + dlen, s);
+ return p;
+}
+
+static char *
+p0(size_t len)
+{
+ char *d, *s1, *s2;
+ s1 = mkstr("\\(", len);
+ s2 = concat(s1, ")");
+ free(s1);
+ d = concat("(", s2);
+ free(s2);
+ return d;
+}
+
+static char *
+p1(size_t len)
+{
+ char *d, *s1, *s2, *s3;
+ s1 = mkstr("\\(", 60);
+ s2 = mkstr("(.*)", len);
+ s3 = concat(s1, s2);
+ free(s2);
+ free(s1);
+ s1 = concat(s3, ")");
+ free(s3);
+ d = concat("(", s1);
+ free(s1);
+ return d;
+}
+
+static char *
+ps(const char *m, const char *s, size_t len)
+{
+ char *d, *s1, *s2, *s3;
+ s1 = mkstr(m, len);
+ s2 = mkstr(s, len);
+ s3 = concat(s1, s2);
+ free(s2);
+ free(s1);
+ d = concat("(.?)", s3);
+ free(s3);
+ return d;
+}
+
+static char *
+p2(size_t len)
+{
+ return ps("((.*){0,255}", ")", len);
+}
+
+static char *
+p3(size_t len)
+{
+ return ps("(.\\{0,}", ")", len);
+}
+
+static char *
+p4(size_t len)
+{
+ return ps("((.*){1,255}", ")", len);
+}
+
+static char *
+p5(size_t len)
+{
+ return ps("(", "){1,100}", len);
+}
+
+static char *
+p6(size_t len)
+{
+ char *d, *s1, *s2;
+ s1 = mkstr("(?:(.*)|", len);
+ s2 = concat(s1, "(.*)");
+ free(s1);
+ s1 = mkstr(")", len);
+ d = concat(s2, s1);
+ free(s1);
+ free(s2);
+ return d;
+}
+
+static const struct {
+ char *(*pattern)(size_t);
+ int type;
+} tests[] = {
+ { p0, REG_EXTENDED },
+ { p1, REG_EXTENDED },
+ { p2, REG_EXTENDED },
+ { p3, REG_EXTENDED },
+ { p4, REG_EXTENDED },
+ { p5, REG_EXTENDED },
+ { p6, REG_BASIC },
+};
+
+ATF_TC(regcomp_too_big);
+
+ATF_TC_HEAD(regcomp_too_big, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Check that large patterns don't"
+ " crash, but return a proper error code");
+ // libtre needs it.
+ atf_tc_set_md_var(tc, "timeout", "600");
+#ifdef __FreeBSD__
+ atf_tc_set_md_var(tc, "require.memory", "64M");
+#else
+ atf_tc_set_md_var(tc, "require.memory", "120M");
+#endif
+}
+
+ATF_TC_BODY(regcomp_too_big, tc)
+{
+ regex_t re;
+#ifdef __FreeBSD__
+ struct rlimit limit;
+#endif
+ int e;
+
+#ifdef __FreeBSD__
+ limit.rlim_cur = limit.rlim_max = 64 * 1024 * 1024;
+ ATF_REQUIRE(setrlimit(RLIMIT_VMEM, &limit) != -1);
+#endif
+ for (size_t i = 0; i < __arraycount(tests); i++) {
+ char *d = (*tests[i].pattern)(REGEX_MAXSIZE);
+ e = regcomp(&re, d, tests[i].type);
+ if (e) {
+ char ebuf[1024];
+ (void)regerror(e, &re, ebuf, sizeof(ebuf));
+ ATF_REQUIRE_MSG(e == REG_ESPACE,
+ "regcomp returned %d (%s) for pattern %zu [%s]", e, ebuf,
+ i, d);
+ free(d);
+ continue;
+ }
+ free(d);
+ (void)regexec(&re, "aaaaaaaaaaa", 0, NULL, 0);
+ regfree(&re);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, regcomp_too_big);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/regex/t_regex.sh b/contrib/netbsd-tests/lib/libc/regex/t_regex.sh
new file mode 100755
index 0000000..bef3ac9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/t_regex.sh
@@ -0,0 +1,73 @@
+# $NetBSD: t_regex.sh,v 1.1 2012/08/24 20:24:40 jmmv Exp $
+#
+# 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.
+#
+
+check()
+{
+ local dataname="${1}"; shift
+
+ prog="$(atf_get_srcdir)/h_regex"
+ data="$(atf_get_srcdir)/data/${dataname}.in"
+
+ atf_check -x "${prog} <${data}"
+ atf_check -x "${prog} -el <${data}"
+ atf_check -x "${prog} -er <${data}"
+}
+
+create_tc()
+{
+ local name="${1}"; shift
+ local descr="${1}"; shift
+
+ atf_test_case "${name}"
+ eval "${name}_head() { atf_set 'descr' '${descr}'; }"
+ eval "${name}_body() { check '${name}'; }"
+
+ atf_add_test_case "${name}"
+}
+
+atf_init_test_cases()
+{
+ create_tc basic "Checks basic functionality"
+ create_tc paren "Checks parentheses"
+ create_tc anchor "Checks anchors and REG_NEWLINE"
+ create_tc error "Checks syntax errors and non-errors"
+ create_tc meta "Checks metacharacters and backslashes"
+ create_tc backref "Checks back references"
+ create_tc repet_ordinary "Checks ordinary repetitions"
+ create_tc repet_bounded "Checks bounded repetitions"
+ create_tc repet_multi "Checks multiple repetitions"
+ create_tc bracket "Checks brackets"
+ create_tc complex "Checks various complex examples"
+ create_tc subtle "Checks various subtle examples"
+ create_tc c_comments "Checks matching C comments"
+ create_tc subexp "Checks subexpressions"
+ create_tc startend "Checks STARTEND option"
+ create_tc nospec "Checks NOSPEC option"
+ create_tc zero "Checks NULs"
+ create_tc word_bound "Checks word boundaries"
+ create_tc regress "Checks various past problems and suspected problems"
+}
diff --git a/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c
new file mode 100644
index 0000000..0ca44b4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c
@@ -0,0 +1,639 @@
+/* $NetBSD: t_regex_att.c,v 1.1 2012/08/24 20:24:40 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 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/cdefs.h>
+__RCSID("$NetBSD: t_regex_att.c,v 1.1 2012/08/24 20:24:40 jmmv Exp $");
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <regex.h>
+#include <string.h>
+#include <stdlib.h>
+#include <vis.h>
+#include <ctype.h>
+#include <atf-c.h>
+#ifdef __FreeBSD__
+#include <libutil.h>
+#endif
+
+static const char sep[] = "\r\n\t";
+static const char delim[3] = "\\\\\0";
+
+
+static void
+fail(const char *pattern, const char *input, size_t lineno) {
+ fprintf(stderr,
+ "skipping failed test at line %zu (pattern=%s, input=%s)\n",
+ lineno, pattern, input);
+}
+
+static int
+bug(const char *pattern, const char *input, size_t lineno) {
+ static const struct {
+ const char *p;
+ const char *i;
+ } b[] = {
+#if defined(REGEX_SPENCER)
+ /*
+ * The default libc implementation by Henry Spencer
+ */
+ { "a[-]?c", "ac" }, // basic.dat
+ { "(a*)*", "a" }, // categorization.dat
+ { "(aba|a*b)*", "ababa" }, // categorization.dat
+ { "\\(a\\(b\\)*\\)*\\2", "abab" }, // categorization.dat
+ { "(a*)*", "aaaaaa" }, // nullsubexpression.dat
+ { "(a*)*", "aaaaaax" }, // nullsubexpression.dat
+ { "(a*)+", "a" }, // nullsubexpression.dat
+ { "(a*)+", "aaaaaa" }, // nullsubexpression.dat
+ { "(a*)+", "aaaaaax" }, // nullsubexpression.dat
+ { "([a]*)*", "a" }, // nullsubexpression.dat
+ { "([a]*)*", "aaaaaa" }, // nullsubexpression.dat
+ { "([a]*)*", "aaaaaax" }, // nullsubexpression.dat
+ { "([a]*)+", "a" }, // nullsubexpression.dat
+ { "([a]*)+", "aaaaaa" }, // nullsubexpression.dat
+ { "([a]*)+", "aaaaaax" }, // nullsubexpression.dat
+ { "([^b]*)*", "a" }, // nullsubexpression.dat
+ { "([^b]*)*", "aaaaaa" }, // nullsubexpression.dat
+ { "([^b]*)*", "aaaaaab" }, // nullsubexpression.dat
+ { "([ab]*)*", "a" }, // nullsubexpression.dat
+ { "([ab]*)*", "aaaaaa" }, // nullsubexpression.dat
+ { "([ab]*)*", "ababab" }, // nullsubexpression.dat
+ { "([ab]*)*", "bababa" }, // nullsubexpression.dat
+ { "([ab]*)*", "b" }, // nullsubexpression.dat
+ { "([ab]*)*", "bbbbbb" }, // nullsubexpression.dat
+ { "([ab]*)*", "aaaabcde" }, // nullsubexpression.dat
+ { "([^a]*)*", "b" }, // nullsubexpression.dat
+ { "([^a]*)*", "bbbbbb" }, // nullsubexpression.dat
+ { "([^ab]*)*", "ccccxx" }, // nullsubexpression.dat
+ { "\\(a*\\)*\\(x\\)", "ax" }, // nullsubexpression.dat
+ { "\\(a*\\)*\\(x\\)", "axa" }, // nullsubexpression.dat
+ { "\\(a*\\)*\\(x\\)\\(\\1\\)", "x" }, // nullsubexpression.dat
+/* crash! */ { "\\(a*\\)*\\(x\\)\\(\\1\\)", "ax" }, // nullsubexpression.dat
+/* crash! */ { "\\(a*\\)*\\(x\\)\\(\\1\\)\\(x\\)", "axxa" }, // ""
+ { "(a*)*(x)", "ax" }, // nullsubexpression.dat
+ { "(a*)*(x)", "axa" }, // nullsubexpression.dat
+ { "(a*)+(x)", "ax" }, // nullsubexpression.dat
+ { "(a*)+(x)", "axa" }, // nullsubexpression.dat
+ { "((a|ab)(c|bcd))(d*)", "abcd" }, // forcedassoc.dat
+ { "((a|ab)(bcd|c))(d*)", "abcd" }, // forcedassoc.dat
+ { "((ab|a)(c|bcd))(d*)", "abcd" }, // forcedassoc.dat
+ { "((ab|a)(bcd|c))(d*)", "abcd" }, // forcedassoc.dat
+ { "((a*)(b|abc))(c*)", "abc" }, // forcedassoc.dat
+ { "((a*)(abc|b))(c*)", "abc" }, // forcedassoc.dat
+ { "((..)|(.)){2}", "aaa" }, // repetition.dat
+ { "((..)|(.)){3}", "aaa" }, // repetition.dat
+ { "((..)|(.)){3}", "aaaa" }, // repetition.dat
+ { "((..)|(.)){3}", "aaaaa" }, // repetition.dat
+ { "X(.?){0,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){1,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){2,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){3,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){4,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){5,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){6,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){7,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){0,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){1,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){2,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){3,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){4,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){5,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){6,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){7,8}Y", "X1234567Y" }, // repetition.dat
+ { "(a|ab|c|bcd){0,}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){1,}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){2,}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){3,}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){1,10}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){2,10}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){3,10}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd)*(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd)+(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){0,}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){1,}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){2,}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){3,}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){1,10}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){2,10}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){3,10}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd)*(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd)+(d*)", "ababcd" }, // repetition.dat
+#elif defined(REGEX_TRE)
+ { "a[-]?c", "ac" }, // basic.dat
+ { "a\\(b\\)*\\1", "a" }, // categorization.dat
+ { "a\\(b\\)*\\1", "abab" }, // categorization.dat
+ { "\\(a\\(b\\)*\\)*\\2", "abab" }, // categorization.dat
+ { "\\(a*\\)*\\(x\\)\\(\\1\\)", "ax" }, // categorization.dat
+ { "\\(a*\\)*\\(x\\)\\(\\1\\)\\(x\\)", "axxa" }, // ""
+ { "((..)|(.))*", "aa" }, // repetition.dat
+ { "((..)|(.))*", "aaa" }, // repetition.dat
+ { "((..)|(.))*", "aaaaa" }, // repetition.dat
+ { "X(.?){7,}Y", "X1234567Y" }, // repetition.dat
+#else
+ { "", "" }
+#endif
+ };
+
+ for (size_t i = 0; i < __arraycount(b); i++) {
+ if (strcmp(pattern, b[i].p) == 0 &&
+ strcmp(input, b[i].i) == 0) {
+ fail(pattern, input, lineno);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#ifdef REGEX_SPENCER
+#define HAVE_BRACES 1
+#define HAVE_MINIMAL 0
+#endif
+#ifndef HAVE_BRACES
+#define HAVE_BRACES 1
+#endif
+#ifndef HAVE_MINIMAL
+#define HAVE_MINIMAL 1
+#endif
+
+static int
+optional(const char *s)
+{
+ static const struct{
+ const char *n;
+ int v;
+ } nv[]= {
+ { "[[<element>]] not supported", HAVE_BRACES },
+ { "no *? +? mimimal match ops", HAVE_MINIMAL },
+ };
+
+ for (size_t i = 0; i < __arraycount(nv); i++)
+ if (strcmp(nv[i].n, s) == 0) {
+ if (nv[i].v)
+ return 0;
+ fprintf(stderr, "skipping unsupported [%s] tests\n", s);
+ return 1;
+ }
+
+ ATF_REQUIRE_MSG(0, "Unknown feature: %s", s);
+ return 0;
+}
+
+static int
+unsupported(const char *s)
+{
+ static const char *we[] = {
+#if defined(REGEX_SPENCER)
+ "ASSOCIATIVITY=left", // have right associativity
+ "SUBEXPRESSION=precedence", // have grouping subexpression
+ "REPEAT_LONGEST=last", // have first repeat longest
+ "BUG=alternation-order", // don't have it
+ "BUG=first-match", // don't have it
+ "BUG=nomatch-match", // don't have it
+ "BUG=repeat-any", // don't have it
+ "BUG=range-null", // don't have it
+ "BUG=repeat-null-unknown", // don't have it
+ "BUG=repeat-null", // don't have it
+ "BUG=repeat-artifact", // don't have it
+ "BUG=subexpression-first", // don't have it
+#elif defined(REGEX_TRE)
+ "ASSOCIATIVITY=right", // have left associativity
+ "SUBEXPRESSION=grouping", // have precedence subexpression
+ "REPEAT_LONGEST=first", // have last repeat longest
+ "LENGTH=first", // have last length
+ "BUG=alternation-order", // don't have it
+ "BUG=first-match", // don't have it
+ "BUG=range-null", // don't have it
+ "BUG=repeat-null", // don't have it
+ "BUG=repeat-artifact", // don't have it
+ "BUG=subexpression-first", // don't have it
+ "BUG=repeat-short", // don't have it
+#endif
+ };
+
+ if (s == NULL)
+ return 0;
+
+ while (*s == '#' || isspace((unsigned char)*s))
+ s++;
+
+ for (size_t i = 0; i < __arraycount(we); i++)
+ if (strcmp(we[i], s) == 0)
+ return 1;
+ return 0;
+}
+
+static void
+geterror(const char *s, int *comp, int *exec)
+{
+ static const struct {
+ const char *n;
+ int v;
+ int ce;
+ } nv[] = {
+#define COMP 1
+#define EXEC 2
+ { "OK", 0, COMP|EXEC },
+#define _DO(a, b) { # a, REG_ ## a, b },
+ _DO(NOMATCH, EXEC)
+ _DO(BADPAT, COMP)
+ _DO(ECOLLATE, COMP)
+ _DO(ECTYPE, COMP)
+ _DO(EESCAPE, COMP)
+ _DO(ESUBREG, COMP)
+ _DO(EBRACK, COMP)
+ _DO(EPAREN, COMP)
+ _DO(EBRACE, COMP)
+ _DO(BADBR, COMP)
+ _DO(ERANGE, COMP)
+ _DO(ESPACE, EXEC)
+ _DO(BADRPT, COMP)
+ _DO(EMPTY, COMP)
+ _DO(ASSERT, COMP)
+ _DO(INVARG, COMP)
+ _DO(ENOSYS, COMP)
+#undef _DO
+ };
+ *comp = 0;
+ *exec = 0;
+ for (size_t i = 0; i < __arraycount(nv); i++)
+ if (strcmp(s, nv[i].n) == 0) {
+ if (nv[i].ce & COMP)
+ *comp = nv[i].v;
+ if (nv[i].ce & EXEC)
+ *exec = nv[i].v;
+ return;
+ }
+ ATF_REQUIRE_MSG(0, "Unknown error %s", s);
+ return;
+}
+
+static int
+getflags(char *s)
+{
+ int flags = 0;
+
+ for (;; s++)
+ switch (*s) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ *s = '\0';
+ break;
+ case '\0':
+ return flags;
+ case 'B':
+ case 'E':
+ case 'F':
+ case 'L':
+ break;
+ case 'i':
+ flags |= REG_ICASE;
+ *s = '\0';
+ break;
+ case '$':
+ *s = '\0';
+ break;
+ case 'n':
+ *s = '\0';
+ break;
+ default:
+ ATF_REQUIRE_MSG(0, "Unknown char %c", *s);
+ break;
+ }
+}
+
+static size_t
+getmatches(const char *s)
+{
+ size_t i;
+ char *q;
+ for (i = 0; (q = strchr(s, '(')) != NULL; i++, s = q + 1)
+ continue;
+ ATF_REQUIRE_MSG(i != 0, "No parentheses found");
+ return i;
+}
+
+static void
+checkcomment(const char *s, size_t lineno)
+{
+ if (s && strstr(s, "BUG") != NULL)
+ fprintf(stderr, "Expected %s at line %zu\n", s, lineno);
+}
+
+static void
+checkmatches(const char *matches, size_t nm, const regmatch_t *pm,
+ size_t lineno)
+{
+ if (nm == 0)
+ return;
+
+ char *res;
+ size_t len = strlen(matches) + 1, off = 0;
+
+ ATF_REQUIRE((res = strdup(matches)) != NULL);
+ for (size_t i = 0; i < nm; i++) {
+ int l;
+ if (pm[i].rm_so == -1 && pm[i].rm_eo == -1)
+ l = snprintf(res + off, len - off, "(?,?)");
+ else
+ l = snprintf(res + off, len - off, "(%lld,%lld)",
+ (long long)pm[i].rm_so, (long long)pm[i].rm_eo);
+ ATF_REQUIRE_MSG((size_t) l < len - off, "String too long %s"
+ " cur=%d, max=%zu", res, l, len - off);
+ off += l;
+ }
+#ifdef __FreeBSD__
+ ATF_CHECK_STREQ_MSG(res, matches, " at line %zu", lineno);
+#else
+ ATF_REQUIRE_STREQ_MSG(res, matches, " at line %zu", lineno);
+#endif
+ free(res);
+}
+
+static void
+att_test(const struct atf_tc *tc, const char *data_name)
+{
+ regex_t re;
+ char *line, *lastpattern = NULL, data_path[MAXPATHLEN];
+ size_t len, lineno = 0;
+ int skipping = 0;
+ FILE *input_file;
+
+ snprintf(data_path, sizeof(data_path), "%s/data/%s.dat",
+ atf_tc_get_config_var(tc, "srcdir"), data_name);
+
+ input_file = fopen(data_path, "r");
+ if (input_file == NULL)
+ atf_tc_fail("Failed to open input file %s", data_path);
+
+ for (; (line = fparseln(input_file, &len, &lineno, delim, 0))
+ != NULL; free(line)) {
+ char *name, *pattern, *input, *matches, *comment;
+ regmatch_t *pm;
+ size_t nm;
+#ifdef DEBUG
+ fprintf(stderr, "[%s]\n", line);
+#endif
+ if ((name = strtok(line, sep)) == NULL)
+ continue;
+
+ /*
+ * We check these early so that we skip the lines quickly
+ * in order to do more strict testing on the other arguments
+ * The same characters are also tested in the switch below
+ */
+ if (*name == '}') {
+ skipping = 0;
+ continue;
+ }
+ if (skipping)
+ continue;
+ if (*name == ';' || *name == '#' || strcmp(name, "NOTE") == 0)
+ continue;
+ if (*name == ':') {
+ /* Skip ":HA#???:" prefix */
+ while (*++name && *name != ':')
+ continue;
+ if (*name)
+ name++;
+ }
+
+ ATF_REQUIRE_MSG((pattern = strtok(NULL, sep)) != NULL,
+ "Missing pattern at line %zu", lineno);
+ ATF_REQUIRE_MSG((input = strtok(NULL, sep)) != NULL,
+ "Missing input at line %zu", lineno);
+
+ if (strchr(name, '$')) {
+ ATF_REQUIRE(strunvis(pattern, pattern) != -1);
+ ATF_REQUIRE(strunvis(input, input) != -1);
+ }
+
+
+ if (strcmp(input, "NULL") == 0)
+ *input = '\0';
+
+ if (strcmp(pattern, "SAME") == 0) {
+ ATF_REQUIRE(lastpattern != NULL);
+ pattern = lastpattern;
+ } else {
+ free(lastpattern);
+ ATF_REQUIRE((lastpattern = strdup(pattern)) != NULL);
+ }
+
+ ATF_REQUIRE_MSG((matches = strtok(NULL, sep)) != NULL,
+ "Missing matches at line %zu", lineno);
+
+ comment = strtok(NULL, sep);
+ switch (*name) {
+ case '{': /* Begin optional implementation */
+ if (optional(comment)) {
+ skipping++;
+ continue;
+ }
+ name++; /* We have it, so ignore */
+ break;
+ case '}': /* End optional implementation */
+ skipping = 0;
+ continue;
+ case '?': /* Optional */
+ case '|': /* Alternative */
+ if (unsupported(comment))
+ continue;
+ name++; /* We have it, so ignore */
+ break;
+ case '#': /* Comment */
+ case ';': /* Skip */
+ continue;
+ default:
+ break;
+ }
+
+ /* XXX: Our bug */
+ if (bug(pattern, input, lineno))
+ continue;
+
+ int comp, exec;
+ if (*matches != '(') {
+ geterror(matches, &comp, &exec);
+ pm = NULL;
+ nm = 0;
+ } else {
+ comp = exec = 0;
+ nm = getmatches(matches);
+ ATF_REQUIRE((pm = calloc(nm, sizeof(*pm))) != NULL);
+ }
+
+
+
+ int iflags = getflags(name);
+ for (; *name; name++) {
+ int flags;
+ switch (*name) {
+ case 'B':
+ flags = REG_BASIC;
+ break;
+ case 'E':
+ flags = REG_EXTENDED;
+ break;
+ case 'L':
+ flags = REG_NOSPEC;
+ break;
+ default:
+ ATF_REQUIRE_MSG(0, "Bad name %c", *name);
+ continue;
+ }
+ int c = regcomp(&re, pattern, flags | iflags);
+ ATF_REQUIRE_MSG(c == comp,
+ "regcomp returned %d for pattern %s at line %zu",
+ c, pattern, lineno);
+ if (c)
+ continue;
+ int e = regexec(&re, input, nm, pm, 0);
+ ATF_REQUIRE_MSG(e == exec, "Expected error %d,"
+ " got %d at line %zu", exec, e, lineno);
+ checkmatches(matches, nm, pm, lineno);
+ checkcomment(comment, lineno);
+ regfree(&re);
+ }
+ free(pm);
+ }
+
+ fclose(input_file);
+}
+
+ATF_TC(basic);
+ATF_TC_HEAD(basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests basic functionality");
+}
+ATF_TC_BODY(basic, tc)
+{
+ att_test(tc, "basic");
+}
+
+ATF_TC(categorization);
+ATF_TC_HEAD(categorization, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests implementation categorization");
+}
+ATF_TC_BODY(categorization, tc)
+{
+ att_test(tc, "categorization");
+}
+
+ATF_TC(nullsubexpr);
+ATF_TC_HEAD(nullsubexpr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests (...)*");
+}
+ATF_TC_BODY(nullsubexpr, tc)
+{
+ att_test(tc, "nullsubexpr");
+}
+
+ATF_TC(leftassoc);
+ATF_TC_HEAD(leftassoc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests left-associative "
+ "implementations");
+}
+ATF_TC_BODY(leftassoc, tc)
+{
+#if SKIP_LEFTASSOC
+ /* jmmv: I converted the original shell-based tests to C and they
+ * disabled this test in a very unconventional way without giving
+ * any explation. Mark as broken here, but I don't know why. */
+ atf_tc_expect_fail("Reason for breakage unknown");
+#endif
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("The expected and matched groups are mismatched on FreeBSD");
+#endif
+ att_test(tc, "leftassoc");
+}
+
+ATF_TC(rightassoc);
+ATF_TC_HEAD(rightassoc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests right-associative "
+ "implementations");
+}
+ATF_TC_BODY(rightassoc, tc)
+{
+#if SKIP_RIGHTASSOC
+ /* jmmv: I converted the original shell-based tests to C and they
+ * disabled this test in a very unconventional way without giving
+ * any explation. Mark as broken here, but I don't know why. */
+ atf_tc_expect_fail("Reason for breakage unknown");
+#endif
+ att_test(tc, "rightassoc");
+}
+
+ATF_TC(forcedassoc);
+ATF_TC_HEAD(forcedassoc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests subexpression grouping to "
+ "force association");
+}
+ATF_TC_BODY(forcedassoc, tc)
+{
+ att_test(tc, "forcedassoc");
+}
+
+ATF_TC(repetition);
+ATF_TC_HEAD(repetition, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests implicit vs. explicit "
+ "repetition");
+}
+ATF_TC_BODY(repetition, tc)
+{
+ att_test(tc, "repetition");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, basic);
+ ATF_TP_ADD_TC(tp, categorization);
+ ATF_TP_ADD_TC(tp, nullsubexpr);
+ ATF_TP_ADD_TC(tp, leftassoc);
+ ATF_TP_ADD_TC(tp, rightassoc);
+ ATF_TP_ADD_TC(tp, forcedassoc);
+ ATF_TP_ADD_TC(tp, repetition);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/regex/test_regex.h b/contrib/netbsd-tests/lib/libc/regex/test_regex.h
new file mode 100644
index 0000000..1d9f59d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/test_regex.h
@@ -0,0 +1,44 @@
+/* $NetBSD: test_regex.h,v 1.1 2011/01/08 18:10:31 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by
+ *
+ * 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.
+ */
+
+/* from main.c */
+void regress(FILE *);
+void try(char *, char *, char *, char *, char *, int);
+int options(int, char *);
+int opt(int, char *);
+void fixstr(char *);
+char *check(char *, regmatch_t, char *);
+
+/* from split.c */
+int split(char *string, char *fields[], int nfields, const char *sep);
+
+/* from debug.c */
+void regprint(regex_t *r, FILE *d);
diff --git a/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x b/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x
new file mode 100644
index 0000000..cbddfcc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/rpc/h_testbits.x
@@ -0,0 +1,21 @@
+/* $NetBSD: h_testbits.x,v 1.1 2011/01/08 06:59:37 pgoyette Exp $ */
+
+enum smallenum {
+ SE_ONE = 1,
+ SE_TWO = 2
+};
+
+enum medenum {
+ ME_NEG = -1234,
+ ME_ONE = 1,
+ ME_TWO = 2,
+ ME_MANY = 1234
+};
+
+enum bigenum {
+ BE_ONE = 1,
+ BE_TWO = 2,
+ BE_MANY = 1234,
+ BE_LOTS = 1234567
+};
+
diff --git a/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c
new file mode 100644
index 0000000..67bc8c7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c
@@ -0,0 +1,161 @@
+/* $NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $");
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <rpc/rpc.h>
+#include <stdlib.h>
+#include <err.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+#ifndef TEST
+#include <atf-c.h>
+
+#define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__)
+
+#define SKIPX(ev, msg, ...) do { \
+ atf_tc_skip(msg, __VA_ARGS__); \
+ return; \
+} while(/*CONSTCOND*/0)
+
+#else
+#define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__)
+#define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__)
+#endif
+
+
+#define RPCBPROC_NULL 0
+
+static int
+reply(caddr_t replyp, struct netbuf * raddrp, struct netconfig * nconf)
+{
+ char host[NI_MAXHOST];
+ struct sockaddr *sock = raddrp->buf;
+ int error;
+
+
+ error = getnameinfo(sock, sock->sa_len, host, sizeof(host), NULL, 0, 0);
+ if (error)
+ warnx("Cannot resolve address (%s)", gai_strerror(error));
+ else
+ printf("response from: %s\n", host);
+ return 0;
+}
+
+#ifdef __FreeBSD__
+#define __rpc_control rpc_control
+#endif
+
+extern bool __rpc_control(int, void *);
+
+static void
+onehost(const char *host, const char *transp)
+{
+ CLIENT *clnt;
+ struct netbuf addr;
+ struct timeval tv;
+
+ /*
+ * Magic!
+ */
+ tv.tv_sec = 0;
+ tv.tv_usec = 500000;
+#define CLCR_SET_RPCB_TIMEOUT 2
+ __rpc_control(CLCR_SET_RPCB_TIMEOUT, &tv);
+
+ if ((clnt = clnt_create(host, RPCBPROG, RPCBVERS, transp)) == NULL)
+ SKIPX(EXIT_FAILURE, "clnt_create (%s)", clnt_spcreateerror(""));
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv)
+ != RPC_SUCCESS)
+ ERRX(EXIT_FAILURE, "clnt_call (%s)", clnt_sperror(clnt, ""));
+ clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr);
+ reply(NULL, &addr, NULL);
+}
+
+#ifdef TEST
+static void
+allhosts(void)
+{
+ enum clnt_stat clnt_stat;
+
+ clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL,
+ (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void,
+ NULL, (resultproc_t)reply, transp);
+ if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT)
+ ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat));
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+ const char *transp = "udp";
+
+
+ while ((ch = getopt(argc, argv, "ut")) != -1)
+ switch (ch) {
+ case 't':
+ transp = "tcp";
+ break;
+ case 'u':
+ transp = "udp";
+ break;
+ default:
+ fprintf(stderr, "Usage: %s -[t|u] [<hostname>...]\n",
+ getprogname());
+ return EXIT_FAILURE;
+ }
+
+ if (argc == optind)
+ allhosts();
+ else
+ for (; optind < argc; optind++)
+ onehost(argv[optind], transp);
+
+ return EXIT_SUCCESS;
+}
+
+#else
+
+ATF_TC(get_svc_addr_tcp);
+ATF_TC_HEAD(get_svc_addr_tcp, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for tcp");
+
+}
+
+ATF_TC_BODY(get_svc_addr_tcp, tc)
+{
+ onehost("localhost", "tcp");
+
+}
+
+ATF_TC(get_svc_addr_udp);
+ATF_TC_HEAD(get_svc_addr_udp, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for udp");
+}
+
+ATF_TC_BODY(get_svc_addr_udp, tc)
+{
+ onehost("localhost", "udp");
+
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, get_svc_addr_udp);
+ ATF_TP_ADD_TC(tp, get_svc_addr_tcp);
+
+ return atf_no_error();
+}
+
+#endif
diff --git a/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c b/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c
new file mode 100644
index 0000000..2a68eb4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c
@@ -0,0 +1,129 @@
+/* $NetBSD: t_xdr.c,v 1.1 2011/01/08 06:59:37 pgoyette Exp $ */
+
+/*
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Ben Harris.
+ *
+ * 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 (c) 2001 Ben Harris
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_xdr.c,v 1.1 2011/01/08 06:59:37 pgoyette Exp $");
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "h_testbits.h"
+
+char xdrdata[] = {
+ 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* double 1.0 */
+ 0x00, 0x00, 0x00, 0x01, /* enum smallenum SE_ONE */
+ 0xff, 0xff, 0xfb, 0x2e, /* enum medenum ME_NEG */
+ 0x00, 0x12, 0xd6, 0x87, /* enum bigenum BE_LOTS */
+};
+
+ATF_TC(xdr);
+ATF_TC_HEAD(xdr, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks encoding/decoding of doubles and enumerations");
+}
+ATF_TC_BODY(xdr, tc)
+{
+ XDR x;
+ double d;
+ smallenum s;
+ medenum m;
+ bigenum b;
+ char newdata[sizeof(xdrdata)];
+
+ xdrmem_create(&x, xdrdata, sizeof(xdrdata), XDR_DECODE);
+
+ ATF_REQUIRE_MSG(xdr_double(&x, &d), "xdr_double DECODE failed");
+ ATF_REQUIRE_EQ_MSG(d, 1.0, "double 1.0 decoded as %g", d);
+
+ ATF_REQUIRE_MSG(xdr_smallenum(&x, &s), "xdr_smallenum DECODE failed");
+ ATF_REQUIRE_EQ_MSG(s, SE_ONE, "SE_ONE decoded as %d", s);
+
+ ATF_REQUIRE_MSG(xdr_medenum(&x, &m), "xdr_medenum DECODE failed");
+ ATF_REQUIRE_EQ_MSG(m, ME_NEG, "ME_NEG decoded as %d", m);
+
+ ATF_REQUIRE_MSG(xdr_bigenum(&x, &b), "xdr_bigenum DECODE failed");
+ ATF_REQUIRE_EQ_MSG(b, BE_LOTS, "BE_LOTS decoded as %d", b);
+
+ xdr_destroy(&x);
+
+
+ xdrmem_create(&x, newdata, sizeof(newdata), XDR_ENCODE);
+
+ ATF_REQUIRE_MSG(xdr_double(&x, &d), "xdr_double ENCODE failed");
+ ATF_REQUIRE_MSG(xdr_smallenum(&x, &s), "xdr_smallenum ENCODE failed");
+ ATF_REQUIRE_MSG(xdr_medenum(&x, &m), "xdr_medenum ENCODE failed");
+ ATF_REQUIRE_MSG(xdr_bigenum(&x, &b), "xdr_bigenum ENCODE failed");
+ ATF_REQUIRE_MSG(memcmp(newdata, xdrdata, sizeof(xdrdata)) == 0,
+ "xdr ENCODE result differs");
+
+ xdr_destroy(&x);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, xdr);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c b/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c
new file mode 100644
index 0000000..4d2a93b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c
@@ -0,0 +1,196 @@
+/* $NetBSD: t_setjmp.c,v 1.1 2010/12/27 19:35:31 pgoyette Exp $ */
+
+/*-
+ * 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.
+ */
+
+/*
+ * Copyright (c) 1994 Christopher G. Demetriou
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the
+ * NetBSD Project. See http://www.NetBSD.org/ for
+ * information about NetBSD.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_setjmp.c,v 1.1 2010/12/27 19:35:31 pgoyette Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno))
+
+#define TEST_SETJMP 0
+#define TEST_U_SETJMP 1
+#define TEST_SIGSETJMP_SAVE 2
+#define TEST_SIGSETJMP_NOSAVE 3
+
+static int expectsignal;
+
+static void
+aborthandler(int signo)
+{
+ ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded");
+ atf_tc_pass();
+}
+
+static void
+h_check(int test)
+{
+ struct sigaction sa;
+ jmp_buf jb;
+ sigjmp_buf sjb;
+ sigset_t ss;
+ int i, x;
+
+ i = getpid();
+
+ if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE)
+ expectsignal = 0;
+ else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE)
+ expectsignal = 1;
+ else
+ atf_tc_fail("unknown test");
+
+ sa.sa_handler = aborthandler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1);
+ REQUIRE_ERRNO(sigemptyset(&ss) != -1);
+ REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1);
+ REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1);
+
+ if (test == TEST_SETJMP)
+ x = setjmp(jb);
+ else if (test == TEST_U_SETJMP)
+ x = _setjmp(jb);
+ else
+ x = sigsetjmp(sjb, !expectsignal);
+
+ if (x != 0) {
+ ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value");
+ kill(i, SIGABRT);
+ ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed");
+ atf_tc_pass();
+ }
+
+ REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1);
+
+ if (test == TEST_SETJMP)
+ longjmp(jb, i);
+ else if (test == TEST_U_SETJMP)
+ _longjmp(jb, i);
+ else
+ siglongjmp(sjb, i);
+
+ atf_tc_fail("jmp failed");
+}
+
+ATF_TC(setjmp);
+ATF_TC_HEAD(setjmp, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks setjmp(3)");
+}
+ATF_TC_BODY(setjmp, tc)
+{
+ h_check(TEST_SETJMP);
+}
+
+ATF_TC(_setjmp);
+ATF_TC_HEAD(_setjmp, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks _setjmp(3)");
+}
+ATF_TC_BODY(_setjmp, tc)
+{
+ h_check(TEST_U_SETJMP);
+}
+
+ATF_TC(sigsetjmp_save);
+ATF_TC_HEAD(sigsetjmp_save, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask enabled");
+}
+ATF_TC_BODY(sigsetjmp_save, tc)
+{
+ h_check(TEST_SIGSETJMP_SAVE);
+}
+
+ATF_TC(sigsetjmp_nosave);
+ATF_TC_HEAD(sigsetjmp_nosave, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks sigsetjmp(3) with savemask disabled");
+}
+ATF_TC_BODY(sigsetjmp_nosave, tc)
+{
+ h_check(TEST_SIGSETJMP_NOSAVE);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, setjmp);
+ ATF_TP_ADD_TC(tp, _setjmp);
+ ATF_TP_ADD_TC(tp, sigsetjmp_save);
+ ATF_TP_ADD_TC(tp, sigsetjmp_nosave);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c b/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c
new file mode 100644
index 0000000..4437c92
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c
@@ -0,0 +1,218 @@
+/* $NetBSD: t_threadjmp.c,v 1.1 2011/04/21 18:58:20 martin Exp $ */
+
+/*-
+ * 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.
+ */
+
+/*
+ * Copyright (c) 1994 Christopher G. Demetriou
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the
+ * NetBSD Project. See http://www.NetBSD.org/ for
+ * information about NetBSD.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_threadjmp.c,v 1.1 2011/04/21 18:58:20 martin Exp $");
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <pthread.h>
+
+#include <atf-c.h>
+
+#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno))
+
+#define TEST_SETJMP 0
+#define TEST_U_SETJMP 1
+#define TEST_SIGSETJMP_SAVE 2
+#define TEST_SIGSETJMP_NOSAVE 3
+
+static pthread_t myself = NULL;
+
+static int expectsignal;
+
+static void
+aborthandler(int signo)
+{
+ ATF_REQUIRE(myself == pthread_self());
+ ATF_REQUIRE_MSG(expectsignal, "kill(SIGABRT) succeeded");
+ atf_tc_pass();
+}
+
+static void
+h_check(int test)
+{
+ struct sigaction sa;
+ jmp_buf jb;
+ sigjmp_buf sjb;
+ sigset_t ss;
+ int i, x;
+
+ myself = pthread_self();
+ i = getpid();
+
+ if (test == TEST_SETJMP || test == TEST_SIGSETJMP_SAVE)
+ expectsignal = 0;
+ else if (test == TEST_U_SETJMP || test == TEST_SIGSETJMP_NOSAVE)
+ expectsignal = 1;
+ else
+ atf_tc_fail("unknown test");
+
+ sa.sa_handler = aborthandler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ REQUIRE_ERRNO(sigaction(SIGABRT, &sa, NULL) != -1);
+ REQUIRE_ERRNO(sigemptyset(&ss) != -1);
+ REQUIRE_ERRNO(sigaddset(&ss, SIGABRT) != -1);
+ REQUIRE_ERRNO(sigprocmask(SIG_BLOCK, &ss, NULL) != -1);
+ ATF_REQUIRE(myself == pthread_self());
+
+ if (test == TEST_SETJMP)
+ x = setjmp(jb);
+ else if (test == TEST_U_SETJMP)
+ x = _setjmp(jb);
+ else
+ x = sigsetjmp(sjb, !expectsignal);
+
+ if (x != 0) {
+ ATF_REQUIRE(myself == pthread_self());
+ ATF_REQUIRE_MSG(x == i, "setjmp returned wrong value");
+ kill(i, SIGABRT);
+ ATF_REQUIRE_MSG(!expectsignal, "kill(SIGABRT) failed");
+ ATF_REQUIRE(myself == pthread_self());
+ atf_tc_pass();
+ }
+
+ ATF_REQUIRE(myself == pthread_self());
+ REQUIRE_ERRNO(sigprocmask(SIG_UNBLOCK, &ss, NULL) != -1);
+
+ if (test == TEST_SETJMP)
+ longjmp(jb, i);
+ else if (test == TEST_U_SETJMP)
+ _longjmp(jb, i);
+ else
+ siglongjmp(sjb, i);
+
+ atf_tc_fail("jmp failed");
+}
+
+ATF_TC(setjmp);
+ATF_TC_HEAD(setjmp, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks pthread_self() and setjmp(3)");
+}
+ATF_TC_BODY(setjmp, tc)
+{
+ h_check(TEST_SETJMP);
+}
+
+ATF_TC(_setjmp);
+ATF_TC_HEAD(_setjmp, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks pthread_self() and _setjmp(3)");
+}
+ATF_TC_BODY(_setjmp, tc)
+{
+ h_check(TEST_U_SETJMP);
+}
+
+ATF_TC(sigsetjmp_save);
+ATF_TC_HEAD(sigsetjmp_save, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks pthread_self() and sigsetjmp(3) with savemask enabled");
+}
+ATF_TC_BODY(sigsetjmp_save, tc)
+{
+ h_check(TEST_SIGSETJMP_SAVE);
+}
+
+ATF_TC(sigsetjmp_nosave);
+ATF_TC_HEAD(sigsetjmp_nosave, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks pthread_self() and sigsetjmp(3) with savemask disabled");
+}
+ATF_TC_BODY(sigsetjmp_nosave, tc)
+{
+ h_check(TEST_SIGSETJMP_NOSAVE);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ /*
+ * These test cases try to verify setjmp and friends in a program
+ * linked with pthreads, and verify that pthread_self() stays
+ * consistent throughout the program. A setcontext() call invoked
+ * by *setjmp() might clobber the TLS special register used to
+ * implement pthread_self().
+ */
+ ATF_TP_ADD_TC(tp, setjmp);
+ ATF_TP_ADD_TC(tp, _setjmp);
+ ATF_TP_ADD_TC(tp, sigsetjmp_save);
+ ATF_TP_ADD_TC(tp, sigsetjmp_nosave);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c b/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c
new file mode 100644
index 0000000..ad9376a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_fgets.c
@@ -0,0 +1,46 @@
+/* $NetBSD: h_fgets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_fgets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ int len = atoi(argv[1]);
+ (void)fgets(b, len, stdin);
+ (void)printf("%s\n", b);
+
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c b/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c
new file mode 100644
index 0000000..68e3a6f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c
@@ -0,0 +1,47 @@
+/* $NetBSD: h_getcwd.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_getcwd.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[MAXPATHLEN];
+ size_t len = atoi(argv[1]);
+ (void)getcwd(b, len);
+ (void)printf("%s\n", b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_gets.c b/contrib/netbsd-tests/lib/libc/ssp/h_gets.c
new file mode 100644
index 0000000..8c601b0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_gets.c
@@ -0,0 +1,43 @@
+/* $NetBSD: h_gets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_gets.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ (void)gets(b);
+ (void)printf("%s\n", b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c
new file mode 100644
index 0000000..1950f73
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c
@@ -0,0 +1,48 @@
+/* $NetBSD: h_memcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_memcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ int len = atoi(argv[1]);
+
+ (void)memcpy(b, "1020202020202", len);
+ (void)printf("%*.*s\n", len, len, b);
+
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c b/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c
new file mode 100644
index 0000000..0ebfd29
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_memmove.c
@@ -0,0 +1,48 @@
+/* $NetBSD: h_memmove.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_memmove.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ int len = atoi(argv[1]);
+
+ (void)memmove(b, "1020202020202", len);
+ (void)printf("%*.*s\n", len, len, b);
+
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_memset.c b/contrib/netbsd-tests/lib/libc/ssp/h_memset.c
new file mode 100644
index 0000000..c5ab607
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_memset.c
@@ -0,0 +1,49 @@
+/* $NetBSD: h_memset.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_memset.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ size_t len = atoi(argv[1]);
+ (void)memset(b, 0, len);
+#ifdef __FreeBSD__
+ return b[0]; /* keeps optimizer from zapping the call to memset() */
+#else
+ return 0;
+#endif
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_raw.c b/contrib/netbsd-tests/lib/libc/ssp/h_raw.c
new file mode 100644
index 0000000..a232481
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_raw.c
@@ -0,0 +1,57 @@
+/* $NetBSD: h_raw.c,v 1.6 2011/07/24 14:00:36 christos Exp $ */
+
+/*
+ * Copyright (c) 2011 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_raw.c,v 1.6 2011/07/24 14:00:36 christos Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void poke(int *, size_t);
+
+void
+poke(int *b, size_t index)
+{
+ size_t i;
+ volatile int sum = 0;
+
+ b[index] = 42;
+ for (i = 0; i < 10; i++)
+ sum += b[i];
+}
+
+int
+main(int argc, char *argv[])
+{
+ int b[10];
+
+ poke(b, atoi(argv[1]));
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_read.c b/contrib/netbsd-tests/lib/libc/ssp/h_read.c
new file mode 100644
index 0000000..1197b6c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_read.c
@@ -0,0 +1,65 @@
+/* $NetBSD: h_read.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_read.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#ifdef __FreeBSD__
+#include <fcntl.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[MAXPATHLEN];
+ int fd, n;
+ size_t len = atoi(argv[1]);
+
+ fd = open("/dev/zero", O_RDONLY);
+ if ((n = read(fd, b, len)) == -1)
+ abort();
+ (void)printf("%s\n", b);
+ return (0);
+}
+#else
+int
+main(int argc, char *argv[])
+{
+ char b[MAXPATHLEN];
+ size_t len = atoi(argv[1]);
+
+ (void)printf("%s\n", b);
+ return 0;
+}
+#endif
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c
new file mode 100644
index 0000000..7e8bff6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c
@@ -0,0 +1,66 @@
+/* $NetBSD: h_readlink.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_readlink.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#ifdef __FreeBSD__
+#include <err.h>
+#include <string.h>
+#endif
+
+int
+main(int argc, char *argv[])
+{
+#ifdef __FreeBSD__
+ char b[512], *sl;
+ int n;
+ size_t len = atoi(argv[1]);
+ sl = malloc(len);
+ memset(sl, 'a', len);
+ sl[len - 1] = 0;
+ unlink("symlink");
+ if (symlink(sl, "symlink") == -1)
+ err(1, "symlink()");
+ n = readlink("symlink", b, len);
+ unlink("symlink");
+#else
+ char b[MAXPATHLEN];
+ size_t len = atoi(argv[1]);
+ (void)readlink("/", b, len);
+#endif
+ (void)printf("%s\n", b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c
new file mode 100644
index 0000000..7576788
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c
@@ -0,0 +1,51 @@
+/* $NetBSD: h_snprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_snprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ size_t len = atoi(argv[1]);
+#ifdef __FreeBSD__
+ char c[] = "01234567890123456789";
+ c[len] = 0;
+ (void)snprintf(b, len, "%s", c);
+#else
+ (void)snprintf(b, len, "%s", "0123456789");
+#endif
+ (void)printf("%s\n", b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c
new file mode 100644
index 0000000..0f6d0cb
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c
@@ -0,0 +1,43 @@
+/* $NetBSD: h_sprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_sprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ (void)sprintf(b, "%s", argv[1]);
+ (void)printf("%s\n", b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c
new file mode 100644
index 0000000..c8dfbb7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c
@@ -0,0 +1,49 @@
+/* $NetBSD: h_stpcpy.c,v 1.1 2014/04/06 19:28:59 christos Exp $ */
+
+/*
+ * Copyright (c) 2014 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_stpcpy.c,v 1.1 2014/04/06 19:28:59 christos Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ char *q = stpcpy(b, argv[1]);
+
+ if ((size_t)(q - b) != strlen(argv[1]))
+ abort();
+
+ (void)printf("%s\n", b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c
new file mode 100644
index 0000000..c03d2a8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c
@@ -0,0 +1,56 @@
+/* $NetBSD: h_stpncpy.c,v 1.2 2014/04/07 15:09:20 christos Exp $ */
+
+/*
+ * Copyright (c) 2014 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_stpncpy.c,v 1.2 2014/04/07 15:09:20 christos Exp $");
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ int len = atoi(argv[1]);
+#if __GNUC_PREREQ__(4, 8)
+ char *q = stpncpy(b, "1020202020202", len);
+
+ if (q - b != len)
+ abort();
+#else
+ // gcc-4.5 lacks __builtin___stpncpy_chk, lose.
+ (void)strncpy(b, "1020202020202", len);
+#endif
+
+ (void)printf("%*.*s\n", len, len, b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c b/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c
new file mode 100644
index 0000000..687acf7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_strcat.c
@@ -0,0 +1,46 @@
+/* $NetBSD: h_strcat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_strcat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+#include <string.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ (void)strcpy(b, "1");
+ (void)strcat(b, argv[1]);
+
+ (void)printf("%s\n", b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c
new file mode 100644
index 0000000..2a7f1f5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c
@@ -0,0 +1,45 @@
+/* $NetBSD: h_strcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_strcpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+#include <string.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ (void)strcpy(b, argv[1]);
+
+ (void)printf("%s\n", b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c b/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c
new file mode 100644
index 0000000..0d66c7b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_strncat.c
@@ -0,0 +1,48 @@
+/* $NetBSD: h_strncat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_strncat.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ int len = atoi(argv[1]);
+ (void)strcpy(b, "1");
+ (void)strncat(b, "1020202020202", len);
+
+ (void)printf("%*.*s\n", len, len, b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c b/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c
new file mode 100644
index 0000000..fddf67b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c
@@ -0,0 +1,47 @@
+/* $NetBSD: h_strncpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_strncpy.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ int len = atoi(argv[1]);
+ (void)strncpy(b, "1020202020202", len);
+
+ (void)printf("%*.*s\n", len, len, b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c
new file mode 100644
index 0000000..0f6af85
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c
@@ -0,0 +1,57 @@
+/* $NetBSD: h_vsnprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_vsnprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+static void wrap(size_t, const char *, ...) __printflike(2, 3);
+
+void
+wrap(size_t len, const char *fmt, ...)
+{
+ char b[10];
+ va_list ap;
+ va_start(ap, fmt);
+ (void)vsnprintf(b, len, fmt, ap);
+ (void)printf("%s\n", b);
+ va_end(ap);
+}
+
+int
+main(int argc, char *argv[])
+{
+ size_t len = atoi(argv[1]);
+ wrap(len, "%s", "012345678901234567890");
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c
new file mode 100644
index 0000000..c7fc780
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c
@@ -0,0 +1,55 @@
+/* $NetBSD: h_vsprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_vsprintf.c,v 1.3 2012/03/15 02:02:22 joerg Exp $");
+
+#include <stdio.h>
+#include <stdarg.h>
+
+static void wrap(const char *, ...) __printflike(1, 2);
+
+static void
+wrap(const char *fmt, ...)
+{
+ char b[10];
+ va_list ap;
+ va_start(ap, fmt);
+ (void)vsprintf(b, fmt, ap);
+ (void)printf("%s\n", b);
+ va_end(ap);
+}
+
+int
+main(int argc, char *argv[])
+{
+ wrap("%s", argv[1]);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh b/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh
new file mode 100755
index 0000000..04adc67
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh
@@ -0,0 +1,459 @@
+# $NetBSD: t_ssp.sh,v 1.7 2014/04/06 19:28:59 christos Exp $
+#
+# 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.
+#
+
+h_pass()
+{
+ echo "Executing command [ $2$1 ]"
+ eval $2 atf_check -s exit:0 -o ignore -e ignore $1
+}
+
+h_fail()
+{
+ echo "Executing command [ $2$1 ]"
+ # Begin FreeBSD
+ if true; then
+ eval $2 atf_check -s signal -o ignore -e ignore $1
+ else
+ # End FreeBSD
+ eval $2 atf_check -s signal:6 -o ignore -e ignore $1
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case sprintf
+sprintf_head()
+{
+ atf_set "descr" "Checks sprintf(3)"
+}
+sprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_sprintf"
+
+ h_pass "$prog ok"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 0123456789ab"
+ else
+ # End FreeBSD
+ h_fail "$prog 0123456789"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case vsprintf
+vsprintf_head()
+{
+ atf_set "descr" "Checks vsprintf(3)"
+}
+vsprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_vsprintf"
+
+ h_pass "$prog ok"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 0123456789ab"
+ else
+ # End FreeBSD
+ h_fail "$prog 0123456789"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case snprintf
+snprintf_head()
+{
+ atf_set "descr" "Checks snprintf(3)"
+}
+snprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_snprintf"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case vsnprintf
+vsnprintf_head()
+{
+ atf_set "descr" "Checks vsnprintf(3)"
+}
+vsnprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_vsnprintf"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case gets
+gets_head()
+{
+ atf_set "descr" "Checks gets(3)"
+}
+gets_body()
+{
+ prog="$(atf_get_srcdir)/h_gets"
+
+ h_pass "$prog" "echo ok |"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog" "echo 0123456789ab |"
+ else
+ # End FreeBSD
+ h_fail "$prog" "echo 0123456789 |"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case fgets
+fgets_head()
+{
+ atf_set "descr" "Checks fgets(3)"
+}
+fgets_body()
+{
+ prog="$(atf_get_srcdir)/h_fgets"
+
+ h_pass "$prog 10" "echo ok |"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13" "echo 0123456789abc |"
+ else
+ # End FreeBSD
+ h_fail "$prog 11" "echo busted |"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case memcpy
+memcpy_head()
+{
+ atf_set "descr" "Checks memcpy(3)"
+}
+memcpy_body()
+{
+ prog="$(atf_get_srcdir)/h_memcpy"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case memmove
+memmove_head()
+{
+ atf_set "descr" "Checks memmove(3)"
+}
+memmove_body()
+{
+ prog="$(atf_get_srcdir)/h_memmove"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case memset
+memset_head()
+{
+ atf_set "descr" "Checks memset(3)"
+}
+memset_body()
+{
+ prog="$(atf_get_srcdir)/h_memset"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case strcpy
+strcpy_head()
+{
+ atf_set "descr" "Checks strcpy(3)"
+}
+strcpy_body()
+{
+ prog="$(atf_get_srcdir)/h_strcpy"
+
+ h_pass "$prog 0123456"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 0123456789ab"
+ else
+ # End FreeBSD
+ h_fail "$prog 0123456789"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case stpcpy
+stpcpy_head()
+{
+ atf_set "descr" "Checks stpcpy(3)"
+}
+stpcpy_body()
+{
+ prog="$(atf_get_srcdir)/h_stpcpy"
+
+ h_pass "$prog 0123456"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 0123456789ab"
+ else
+ # End FreeBSD
+ h_fail "$prog 0123456789"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case strcat
+strcat_head()
+{
+ atf_set "descr" "Checks strcat(3)"
+}
+strcat_body()
+{
+ prog="$(atf_get_srcdir)/h_strcat"
+
+ h_pass "$prog 0123456"
+ h_fail "$prog 0123456789ABCDEF"
+}
+
+atf_test_case strncpy
+strncpy_head()
+{
+ atf_set "descr" "Checks strncpy(3)"
+}
+strncpy_body()
+{
+ prog="$(atf_get_srcdir)/h_strncpy"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case stpncpy
+stpncpy_head()
+{
+ atf_set "descr" "Checks stpncpy(3)"
+}
+stpncpy_body()
+{
+ prog="$(atf_get_srcdir)/h_stpncpy"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case strncat
+strncat_head()
+{
+ atf_set "descr" "Checks strncat(3)"
+}
+strncat_body()
+{
+ prog="$(atf_get_srcdir)/h_strncat"
+
+ # Begin FreeBSD
+ h_pass "$prog 8"
+ if true; then
+ h_fail "$prog 11"
+ else
+ # End FreeBSD
+ h_fail "$prog 9"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case raw
+raw_head()
+{
+ atf_set "descr" "Checks raw array overflow"
+}
+raw_body()
+{
+ prog="$(atf_get_srcdir)/h_raw"
+
+ h_pass "$prog 9"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 12"
+ else
+ # End FreeBSD
+ h_fail "$prog 10"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case read
+read_head()
+{
+ atf_set "descr" "Checks read(2)"
+}
+read_body()
+{
+ prog="$(atf_get_srcdir)/h_read"
+
+ h_pass "$prog 1024" "echo foo |"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 1027" "echo bar |"
+ else
+ # End FreeBSD
+ h_fail "$prog 1025" "echo bar |"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case readlink
+readlink_head()
+{
+ atf_set "descr" "Checks readlink(2)"
+}
+readlink_body()
+{
+ prog="$(atf_get_srcdir)/h_readlink"
+
+ # Begin FreeBSD
+ if true; then
+ h_pass "$prog 512"
+ h_fail "$prog 523"
+ else
+ # End FreeBSD
+ h_pass "$prog 1024"
+ h_fail "$prog 1025"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case getcwd
+getcwd_head()
+{
+ atf_set "descr" "Checks getcwd(3)"
+}
+getcwd_body()
+{
+ prog="$(atf_get_srcdir)/h_getcwd"
+
+ h_pass "$prog 1024"
+ # Begin FreeBSD
+ if false; then
+ # End FreeBSD
+ h_fail "$prog 1025"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case sprintf
+ atf_add_test_case vsprintf
+ atf_add_test_case snprintf
+ atf_add_test_case vsnprintf
+ atf_add_test_case gets
+ atf_add_test_case fgets
+ atf_add_test_case memcpy
+ atf_add_test_case memmove
+ atf_add_test_case memset
+ atf_add_test_case stpcpy
+ atf_add_test_case stpncpy
+ atf_add_test_case strcat
+ atf_add_test_case strcpy
+ atf_add_test_case strncat
+ atf_add_test_case strncpy
+ atf_add_test_case raw
+ atf_add_test_case read
+ atf_add_test_case readlink
+ atf_add_test_case getcwd
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c b/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c
new file mode 100644
index 0000000..251804e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c
@@ -0,0 +1,93 @@
+/* $NetBSD: t_clearerr.c,v 1.1 2011/05/01 16:36:37 jruoho Exp $ */
+
+/*
+ * Copyright (c) 2009, Stathis Kamperis
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_clearerr.c,v 1.1 2011/05/01 16:36:37 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdio.h>
+
+static const char path[] = "/etc/passwd";
+
+ATF_TC(clearerr_basic);
+ATF_TC_HEAD(clearerr_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of clearerr(3)");
+}
+
+ATF_TC_BODY(clearerr_basic, tc)
+{
+ char buf[2048];
+ FILE *fp;
+
+ fp = fopen(path, "r");
+ ATF_REQUIRE(fp != NULL);
+
+ while (feof(fp) == 0)
+ (void)fread(buf, sizeof(buf), 1, fp);
+
+ ATF_REQUIRE(feof(fp) != 0);
+
+ errno = 0;
+ clearerr(fp);
+
+ ATF_REQUIRE(errno == 0);
+ ATF_REQUIRE(feof(fp) == 0);
+ ATF_REQUIRE(fclose(fp) != EOF);
+}
+
+ATF_TC(clearerr_err);
+ATF_TC_HEAD(clearerr_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that clearerr(3) does not fail");
+}
+
+ATF_TC_BODY(clearerr_err, tc)
+{
+ FILE *fp;
+
+ fp = fopen(path, "r");
+
+ ATF_REQUIRE(fp != NULL);
+ ATF_REQUIRE(fclose(fp) == 0);
+
+ errno = 0;
+ clearerr(fp);
+
+ ATF_REQUIRE(errno == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, clearerr_basic);
+ ATF_TP_ADD_TC(tp, clearerr_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c b/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c
new file mode 100644
index 0000000..70498c3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c
@@ -0,0 +1,175 @@
+/* $NetBSD: t_fflush.c,v 1.1 2011/09/11 05:15:55 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_fflush.c,v 1.1 2011/09/11 05:15:55 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static const char *path = "fflush";
+
+ATF_TC_WITH_CLEANUP(fflush_err);
+ATF_TC_HEAD(fflush_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from fflush(3)");
+}
+
+ATF_TC_BODY(fflush_err, tc)
+{
+ FILE *f;
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("the EOF invariant fails on FreeBSD; this is new");
+#endif
+
+ f = fopen(path, "w");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fflush(NULL) == 0);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "r");
+ ATF_REQUIRE(f != NULL);
+
+ /*
+ * In NetBSD the call should fail if the supplied
+ * parameteris not an open stream or the stream is
+ * not open for writing.
+ */
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fflush(f) == EOF);
+
+ ATF_REQUIRE(fclose(f) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fflush(f) == EOF);
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(fflush_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fflush_seek);
+ATF_TC_HEAD(fflush_seek, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test file offsets with fflush(3)");
+}
+
+ATF_TC_BODY(fflush_seek, tc)
+{
+ char buf[12];
+ int fd = -1;
+ FILE *f;
+
+ /*
+ * IEEE Std 1003.1-2008:
+ *
+ * "For a stream open for reading, if the file
+ * is not already at EOF, and the file is one
+ * capable of seeking, the file offset of the
+ * underlying open file description shall be
+ * adjusted so that the next operation on the
+ * open file description deals with the byte
+ * after the last one read from or written to
+ * the stream being flushed."
+ */
+ f = fopen(path, "w");
+ ATF_REQUIRE(f != NULL);
+
+ ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "r+");
+ ATF_REQUIRE(f != NULL);
+
+ fd = fileno(f);
+ ATF_REQUIRE(fd != -1);
+
+ ATF_REQUIRE(fread(buf, 1, 3, f) == 3);
+ ATF_REQUIRE(fflush(f) == 0);
+ ATF_REQUIRE(fseek(f, 0, SEEK_CUR) == 0);
+
+ /*
+ * Verify that the offsets are right and that
+ * a read operation resumes at the correct location.
+ */
+ ATF_REQUIRE(ftell(f) == 3);
+ ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == 3);
+ ATF_REQUIRE(fgetc(f) == 'b');
+
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(fflush_seek, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fpurge_err);
+ATF_TC_HEAD(fpurge_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from fpurge(3)");
+}
+
+ATF_TC_BODY(fpurge_err, tc)
+{
+ FILE *f;
+
+ f = fopen(path, "w");
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fpurge(f) == EOF);
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(fpurge_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fflush_err);
+ ATF_TP_ADD_TC(tp, fflush_seek);
+ ATF_TP_ADD_TC(tp, fpurge_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c b/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c
new file mode 100644
index 0000000..31b76d0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c
@@ -0,0 +1,1181 @@
+/* $NetBSD: t_fmemopen.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */
+
+/*-
+ * Copyright (c)2010 Takehiko NOZAKI,
+ * 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 AUTHOR 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 AUTHOR 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(__FreeBSD__) || defined(__NetBSD__)
+#include <atf-c.h>
+#else
+#if defined(__linux__)
+#define _GNU_SOURCE
+#include <features.h>
+#endif
+#include <assert.h>
+#include <stdio.h>
+#define ATF_TC(arg0) static void arg0##_head(void)
+#define ATF_TC_HEAD(arg0, arg1) static void arg0##_head()
+#define atf_tc_set_md_var(arg0, arg1, ...) do { \
+ printf(__VA_ARGS__); \
+ puts(""); \
+} while (/*CONSTCOND*/0)
+#define ATF_TC_BODY(arg0, arg1) static void arg0##_body()
+#define ATF_CHECK(arg0) assert(arg0)
+#define ATF_TP_ADD_TCS(arg0) int main(void)
+#define ATF_TP_ADD_TC(arg0, arg1) arg1##_head(); arg1##_body()
+#define atf_no_error() 0
+#endif
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+const char *mode_rwa[] = {
+ "r", "rb", "r+", "rb+", "r+b",
+ "w", "wb", "w+", "wb+", "w+b",
+ "a", "ab", "a+", "ab+", "a+b",
+ NULL
+};
+
+const char *mode_r[] = { "r", "rb", "r+", "rb+", "r+b", NULL };
+const char *mode_w[] = { "w", "wb", "w+", "wb+", "w+b", NULL };
+const char *mode_a[] = { "a", "ab", "a+", "ab+", "a+b", NULL };
+
+struct testcase {
+ const char *s;
+ off_t n;
+} testcases[] = {
+#define TESTSTR(s) { s, sizeof(s)-1 }
+ TESTSTR("\0he quick brown fox jumps over the lazy dog"),
+ TESTSTR("T\0e quick brown fox jumps over the lazy dog"),
+ TESTSTR("Th\0 quick brown fox jumps over the lazy dog"),
+ TESTSTR("The\0quick brown fox jumps over the lazy dog"),
+ TESTSTR("The \0uick brown fox jumps over the lazy dog"),
+ TESTSTR("The q\0ick brown fox jumps over the lazy dog"),
+ TESTSTR("The qu\0ck brown fox jumps over the lazy dog"),
+ TESTSTR("The qui\0k brown fox jumps over the lazy dog"),
+ TESTSTR("The quic\0 brown fox jumps over the lazy dog"),
+ TESTSTR("The quick\0brown fox jumps over the lazy dog"),
+ TESTSTR("The quick \0rown fox jumps over the lazy dog"),
+ TESTSTR("The quick b\0own fox jumps over the lazy dog"),
+ TESTSTR("The quick br\0wn fox jumps over the lazy dog"),
+ TESTSTR("The quick bro\0n fox jumps over the lazy dog"),
+ TESTSTR("The quick brow\0 fox jumps over the lazy dog"),
+ TESTSTR("The quick brown\0fox jumps over the lazy dog"),
+ TESTSTR("The quick brown \0ox jumps over the lazy dog"),
+ TESTSTR("The quick brown f\0x jumps over the lazy dog"),
+ TESTSTR("The quick brown fo\0 jumps over the lazy dog"),
+ TESTSTR("The quick brown fox\0jumps over the lazy dog"),
+ TESTSTR("The quick brown fox \0umps over the lazy dog"),
+ TESTSTR("The quick brown fox j\0mps over the lazy dog"),
+ TESTSTR("The quick brown fox ju\0ps over the lazy dog"),
+ TESTSTR("The quick brown fox jum\0s over the lazy dog"),
+ TESTSTR("The quick brown fox jump\0 over the lazy dog"),
+ TESTSTR("The quick brown fox jumps\0over the lazy dog"),
+ TESTSTR("The quick brown fox jumps \0ver the lazy dog"),
+ TESTSTR("The quick brown fox jumps o\0er the lazy dog"),
+ TESTSTR("The quick brown fox jumps ov\0r the lazy dog"),
+ TESTSTR("The quick brown fox jumps ove\0 the lazy dog"),
+ TESTSTR("The quick brown fox jumps over\0the lazy dog"),
+ TESTSTR("The quick brown fox jumps over \0he lazy dog"),
+ TESTSTR("The quick brown fox jumps over t\0e lazy dog"),
+ TESTSTR("The quick brown fox jumps over th\0 lazy dog"),
+ TESTSTR("The quick brown fox jumps over the\0lazy dog"),
+ TESTSTR("The quick brown fox jumps over the \0azy dog"),
+ TESTSTR("The quick brown fox jumps over the l\0zy dog"),
+ TESTSTR("The quick brown fox jumps over the la\0y dog"),
+ TESTSTR("The quick brown fox jumps over the laz\0 dog"),
+ TESTSTR("The quick brown fox jumps over the lazy\0dog"),
+ TESTSTR("The quick brown fox jumps over the lazy \0og"),
+ TESTSTR("The quick brown fox jumps over the lazy d\0g"),
+ TESTSTR("The quick brown fox jumps over the lazy do\0"),
+ TESTSTR("The quick brown fox jumps over the lazy dog"),
+ { NULL, 0 },
+};
+
+ATF_TC(test00);
+ATF_TC_HEAD(test00, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test00");
+}
+ATF_TC_BODY(test00, tc)
+{
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (p = &mode_rwa[0]; *p != NULL; ++p) {
+ fp = fmemopen(&buf[0], sizeof(buf), *p);
+/*
+ * Upon successful completion, fmemopen() shall return a pointer to the
+ * object controlling the stream.
+ */
+ ATF_CHECK(fp != NULL);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+}
+
+ATF_TC(test01);
+ATF_TC_HEAD(test01, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test01");
+}
+ATF_TC_BODY(test01, tc)
+{
+ const char **p;
+ const char *mode[] = {
+ "r+", "rb+", "r+b",
+ "w+", "wb+", "w+b",
+ "a+", "ab+", "a+b",
+ NULL
+ };
+ FILE *fp;
+
+ for (p = &mode[0]; *p != NULL; ++p) {
+/*
+ * If a null pointer is specified as the buf argument, fmemopen() shall
+ * allocate size bytes of memory as if by a call to malloc().
+ */
+ fp = fmemopen(NULL, BUFSIZ, *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * If buf is a null pointer, the initial position shall always be set
+ * to the beginning of the buffer.
+ */
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+}
+
+ATF_TC(test02);
+ATF_TC_HEAD(test02, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test02");
+}
+ATF_TC_BODY(test02, tc)
+{
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (p = &mode_r[0]; *p != NULL; ++p) {
+
+ memset(&buf[0], 0x1, sizeof(buf));
+ fp = fmemopen(&buf[0], sizeof(buf), *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * This position is initially set to either the beginning of the buffer
+ * (for r and w modes)
+ */
+ ATF_CHECK((unsigned char)buf[0] == 0x1);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+/*
+ * The stream also maintains the size of the current buffer contents.
+ * For modes r and r+ the size is set to the value given by the size argument.
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+}
+
+ATF_TC(test03);
+ATF_TC_HEAD(test03, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test03");
+}
+ATF_TC_BODY(test03, tc)
+{
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (p = &mode_w[0]; *p != NULL; ++p) {
+
+ memset(&buf[0], 0x1, sizeof(buf));
+ fp = fmemopen(&buf[0], sizeof(buf), *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * This position is initially set to either the beginning of the buffer
+ * (for r and w modes)
+ */
+ ATF_CHECK(buf[0] == '\0');
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+/*
+ * For modes w and w+ the initial size is zero
+ */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+}
+
+ATF_TC(test04);
+ATF_TC_HEAD(test04, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test04");
+}
+ATF_TC_BODY(test04, tc)
+{
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+/*
+ * or to the first null byte in the buffer (for a modes)
+ */
+ for (p = &mode_a[0]; *p != NULL; ++p) {
+
+ memset(&buf[0], 0x1, sizeof(buf));
+ fp = fmemopen(&buf[0], sizeof(buf), *p);
+ ATF_CHECK(fp != NULL);
+
+ ATF_CHECK((unsigned char)buf[0] == 0x1);
+
+/* If no null byte is found in append mode,
+ * the initial position is set to one byte after the end of the buffer.
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
+#endif
+
+/*
+ * and for modes a and a+ the initial size is either the position of the
+ * first null byte in the buffer or the value of the size argument
+ * if no null byte is found.
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
+#endif
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+}
+
+ATF_TC(test05);
+ATF_TC_HEAD(test05, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test05");
+}
+ATF_TC_BODY(test05, tc)
+{
+ const char **p;
+ FILE *fp;
+ char buf[BUFSIZ];
+
+ for (p = &mode_rwa[0]; *p != NULL; ++p) {
+/*
+ * Otherwise, a null pointer shall be returned, and errno shall be set
+ * to indicate the error.
+ */
+ errno = 0;
+ fp = fmemopen(NULL, (size_t)0, *p);
+ ATF_CHECK(fp == NULL);
+ ATF_CHECK(errno == EINVAL);
+
+ errno = 0;
+ fp = fmemopen((void *)&buf[0], 0, *p);
+ ATF_CHECK(fp == NULL);
+ ATF_CHECK(errno == EINVAL);
+ }
+}
+
+ATF_TC(test06);
+ATF_TC_HEAD(test06, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test06");
+}
+ATF_TC_BODY(test06, tc)
+{
+ const char **p;
+ const char *mode[] = { "", " ", "???", NULL };
+ FILE *fp;
+
+ for (p = &mode[0]; *p != NULL; ++p) {
+/*
+ * The value of the mode argument is not valid.
+ */
+ fp = fmemopen(NULL, 1, *p);
+ ATF_CHECK(fp == NULL);
+ ATF_CHECK(errno == EINVAL);
+ }
+}
+
+ATF_TC(test07);
+ATF_TC_HEAD(test07, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test07");
+}
+ATF_TC_BODY(test07, tc)
+{
+#if !defined(__GLIBC__)
+ const char **p;
+ const char *mode[] = {
+ "r", "rb",
+ "w", "wb",
+ "a", "ab",
+ NULL
+ };
+ FILE *fp;
+
+ for (p = &mode[0]; *p != NULL; ++p) {
+/*
+ * Because this feature is only useful when the stream is opened for updating
+ * (because there is no way to get a pointer to the buffer) the fmemopen()
+ * call may fail if the mode argument does not include a '+' .
+ */
+ errno = 0;
+ fp = fmemopen(NULL, 1, *p);
+ ATF_CHECK(fp == NULL);
+ ATF_CHECK(errno == EINVAL);
+ }
+#endif
+}
+
+ATF_TC(test08);
+ATF_TC_HEAD(test08, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test08");
+}
+ATF_TC_BODY(test08, tc)
+{
+#if !defined(__GLIBC__)
+ const char **p;
+ const char *mode[] = {
+ "r+", "rb+", "r+b",
+ "w+", "wb+", "w+b",
+ "a+", "ab+", "a+b",
+ NULL
+ };
+ FILE *fp;
+
+ for (p = &mode[0]; *p != NULL; ++p) {
+/*
+ * The buf argument is a null pointer and the allocation of a buffer of
+ * length size has failed.
+ */
+ fp = fmemopen(NULL, SIZE_MAX, *p);
+ ATF_CHECK(fp == NULL);
+ ATF_CHECK(errno == ENOMEM);
+ }
+#endif
+}
+
+/*
+ * test09 - test14:
+ * An attempt to seek a memory buffer stream to a negative position or to a
+ * position larger than the buffer size given in the size argument shall fail.
+ */
+
+ATF_TC(test09);
+ATF_TC_HEAD(test09, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test09");
+}
+ATF_TC_BODY(test09, tc)
+{
+ struct testcase *t;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+ off_t i;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rwa[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * test fmemopen_seek(SEEK_SET)
+ */
+ /* zero */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_SET) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* positive */
+ for (i = (off_t)1; i <= (off_t)t->n; ++i) {
+ ATF_CHECK(fseeko(fp, i, SEEK_SET) == 0);
+ ATF_CHECK(ftello(fp) == i);
+ }
+ /* positive + OOB */
+ ATF_CHECK(fseeko(fp, t->n + 1, SEEK_SET) == -1);
+ ATF_CHECK(ftello(fp) == t->n);
+
+ /* negative + OOB */
+ ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_SET) == -1);
+ ATF_CHECK(ftello(fp) == t->n);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+const char *mode_rw[] = {
+ "r", "rb", "r+", "rb+", "r+b",
+ "w", "wb", "w+", "wb+", "w+b",
+ NULL
+};
+
+ATF_TC(test10);
+ATF_TC_HEAD(test10, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test10");
+}
+ATF_TC_BODY(test10, tc)
+{
+ struct testcase *t;
+ off_t i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rw[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * test fmemopen_seek(SEEK_CUR)
+ */
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* zero */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* negative & OOB */
+ ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* positive */
+ for (i = 0; i < (off_t)t->n; ++i) {
+ ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0);
+ ATF_CHECK(ftello(fp) == i + 1);
+ }
+
+ /* positive & OOB */
+ ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test11);
+ATF_TC_HEAD(test11, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test11");
+}
+ATF_TC_BODY(test11, tc)
+{
+ struct testcase *t;
+ off_t len, rest, i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ /* test fmemopen_seek(SEEK_CUR) */
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = (off_t)strnlen(t->s, t->n);
+ rest = (off_t)t->n - len;
+ for (p = &mode_a[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_seek(SEEK_CUR)
+ */
+#if defined(__GLIBC__)
+ if (i < (off_t)t->n) {
+#endif
+ /* zero */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* posive */
+ for (i = (off_t)1; i <= rest; ++i) {
+ ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0);
+ ATF_CHECK(ftello(fp) == len + i);
+ }
+
+ /* positive + OOB */
+ ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+
+ /* negative */
+ for (i = (off_t)1; i <= (off_t)t->n; ++i) {
+ ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)t->n - i);
+ }
+
+ /* negative + OOB */
+ ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+#if defined(__GLIBC__)
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+#ifndef __FreeBSD__
+ATF_TC(test12);
+ATF_TC_HEAD(test12, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test12");
+}
+ATF_TC_BODY(test12, tc)
+{
+ struct testcase *t;
+ off_t len, rest, i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ /* test fmemopen_seek(SEEK_END) */
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = (off_t)strnlen(t->s, t->n);
+ rest = t->n - len;
+ for (p = &mode_r[0]; *p != NULL; ++p) {
+
+ memcpy(buf, t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * test fmemopen_seek(SEEK_END)
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* zero */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* positive + OOB */
+ ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* negative + OOB */
+ ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* positive */
+ for (i = 1; i <= rest; ++i) {
+ ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len + i);
+ }
+
+ /* negative */
+ for (i = 1; i < len; ++i) {
+ ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len - i);
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+#endif
+
+ATF_TC(test13);
+ATF_TC_HEAD(test13, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test13");
+}
+ATF_TC_BODY(test13, tc)
+{
+ struct testcase *t;
+#ifndef __FreeBSD__
+ off_t i;
+#endif
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ /* test fmemopen_seek(SEEK_END) */
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_w[0]; *p != NULL; ++p) {
+
+ memcpy(buf, t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_seek(SEEK_END)
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(ftello(fp) == (off_t)0);
+ ATF_CHECK(buf[0] == '\0');
+
+ /* zero */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* positive + OOB */
+ ATF_CHECK(fseeko(fp, (off_t)t->n + 1, SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* negative + OOB */
+ ATF_CHECK(fseeko(fp, -1, SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+#endif
+
+#ifndef __FreeBSD__
+ /* positive */
+ for (i = 1; i <= t->n; ++i) {
+ ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == i);
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test14);
+ATF_TC_HEAD(test14, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test14");
+}
+ATF_TC_BODY(test14, tc)
+{
+ struct testcase *t;
+ off_t len, rest, i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ /* test fmemopen_seek(SEEK_END) */
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = (off_t)strnlen(t->s, t->n);
+ rest = (off_t)t->n - len;
+ for (p = &mode_a[0]; *p != NULL; ++p) {
+
+ memcpy(buf, t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_seek(SEEK_END)
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(ftello(fp) == len);
+
+ /* zero */
+ ATF_CHECK(fseeko(fp, 0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* positive + OOB */
+ ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* negative + OOB */
+ ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == len);
+
+#ifndef __FreeBSD__
+ /* positive */
+ for (i = 1; i <= rest; ++i) {
+ ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len + i);
+ }
+#endif
+
+ /* negative */
+ for (i = 1; i < len; ++i) {
+ ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len - i);
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+const char *mode_rw1[] = {
+ "r", "rb", "r+", "rb+", "r+b",
+ "w+", "wb+",
+ NULL
+};
+
+#ifndef __FreeBSD__
+
+/* test15 - 18:
+ * When a stream open for writing is flushed or closed, a null byte is written
+ * at the current position or at the end of the buffer, depending on the size
+ * of the contents.
+ */
+
+ATF_TC(test15);
+ATF_TC_HEAD(test15, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test15");
+}
+ATF_TC_BODY(test15, tc)
+{
+ struct testcase *t;
+ const char **p;
+ char buf0[BUFSIZ];
+ FILE *fp;
+ int i;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rw1[0]; *p != NULL; ++p) {
+
+ memcpy(&buf0[0], t->s, t->n);
+ fp = fmemopen(&buf0[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_read + fgetc(3)
+ */
+ for (i = 0; i < t->n; ++i) {
+ ATF_CHECK(ftello(fp) == (off_t)i);
+ ATF_CHECK(fgetc(fp) == buf0[i]);
+ ATF_CHECK(feof(fp) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)i + 1);
+ }
+ ATF_CHECK(fgetc(fp) == EOF);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test16);
+ATF_TC_HEAD(test16, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test16");
+}
+ATF_TC_BODY(test16, tc)
+{
+ struct testcase *t;
+ const char **p;
+ char buf0[BUFSIZ], buf1[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rw1[0]; *p != NULL; ++p) {
+
+ memcpy(&buf0[0], t->s, t->n);
+ buf1[t->n] = 0x1;
+ fp = fmemopen(&buf0[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_read + fread(4)
+ */
+ ATF_CHECK(ftello(fp) == (off_t)0);
+ ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) == (size_t)t->n);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(memcmp(&buf0[0], &buf1[0], t->n) == 0);
+ ATF_CHECK((unsigned char)buf1[t->n] == 0x1);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+const char *mode_a1[] = { "a+", "ab+", NULL };
+
+ATF_TC(test17);
+ATF_TC_HEAD(test17, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test17");
+}
+ATF_TC_BODY(test17, tc)
+{
+ struct testcase *t;
+ size_t len;
+ int i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = strnlen(t->s, t->n);
+ for (p = &mode_a1[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_read + fgetc(3)
+ */
+#if defined(__GLIBC__)
+ if (i < t->n) {
+#endif
+ for (i = len; i < t->n; ++i) {
+ ATF_CHECK(ftello(fp) == (off_t)i);
+ ATF_CHECK(fgetc(fp) == buf[i]);
+ ATF_CHECK(feof(fp) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)i + 1);
+ }
+ ATF_CHECK(fgetc(fp) == EOF);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ rewind(fp);
+ for (i = 0; i < t->n; ++i) {
+ ATF_CHECK(ftello(fp) == (off_t)i);
+ ATF_CHECK(fgetc(fp) == buf[i]);
+ ATF_CHECK(feof(fp) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)i + 1);
+ }
+ ATF_CHECK(fgetc(fp) == EOF);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+#if defined(__GLIBC__)
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test18);
+ATF_TC_HEAD(test18, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test18");
+}
+ATF_TC_BODY(test18, tc)
+{
+ struct testcase *t;
+ size_t len;
+ const char **p;
+ char buf0[BUFSIZ], buf1[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = strnlen(t->s, t->n);
+ for (p = &mode_a1[0]; *p != NULL; ++p) {
+
+ memcpy(&buf0[0], t->s, t->n);
+ buf1[t->n - len] = 0x1;
+ fp = fmemopen(&buf0[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_read + fread(3)
+ */
+#if defined(__GLIBC__)
+ if (i < t->n) {
+#endif
+ ATF_CHECK(ftello(fp) == (off_t)len);
+ ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp)
+ == t->n - len);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(!memcmp(&buf0[len], &buf1[0], t->n - len));
+ ATF_CHECK((unsigned char)buf1[t->n - len] == 0x1);
+ rewind(fp);
+ buf1[t->n] = 0x1;
+ ATF_CHECK(ftello(fp) == (off_t)0);
+ ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp)
+ == (size_t)t->n);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(!memcmp(&buf0[0], &buf1[0], t->n));
+ ATF_CHECK((unsigned char)buf1[t->n] == 0x1);
+#if defined(__GLIBC__)
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+/*
+ * test19 - test22:
+ * If a stream open for update is flushed or closed and the last write has
+ * advanced the current buffer size, a null byte is written at the end of the
+ * buffer if it fits.
+ */
+
+const char *mode_rw2[] = {
+ "r+", "rb+", "r+b",
+ "w", "wb", "w+", "wb+", "w+b",
+ NULL
+};
+
+ATF_TC(test19);
+ATF_TC_HEAD(test19, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test19");
+}
+ATF_TC_BODY(test19, tc)
+{
+ struct testcase *t;
+ int i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rw2[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ buf[t->n] = 0x1;
+ fp = fmemopen(&buf[0], t->n + 1, *p);
+ ATF_CHECK(fp != NULL);
+ setbuf(fp, NULL);
+/*
+ * test fmemopen_write + fputc(3)
+ */
+ for (i = 0; i < t->n; ++i) {
+ ATF_CHECK(ftello(fp) == (off_t)i);
+ ATF_CHECK(fputc(t->s[i], fp) == t->s[i]);
+ ATF_CHECK(buf[i] == t->s[i]);
+ ATF_CHECK(ftello(fp) == (off_t)i + 1);
+ ATF_CHECK(buf[i] == t->s[i]);
+#if !defined(__GLIBC__)
+ ATF_CHECK(buf[i + 1] == '\0');
+#endif
+ }
+
+/* don't accept non nul character at end of buffer */
+ ATF_CHECK(fputc(0x1, fp) == EOF);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ ATF_CHECK(feof(fp) == 0);
+
+/* accept nul character at end of buffer */
+ ATF_CHECK(fputc('\0', fp) == '\0');
+ ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
+ ATF_CHECK(feof(fp) == 0);
+
+/* reach EOF */
+ ATF_CHECK(fputc('\0', fp) == EOF);
+ ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
+
+ /* compare */
+ ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0);
+ ATF_CHECK(buf[t->n] == '\0');
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test20);
+ATF_TC_HEAD(test20, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test20");
+}
+ATF_TC_BODY(test20, tc)
+{
+ struct testcase *t;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rw2[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ buf[t->n] = 0x1;
+ fp = fmemopen(&buf[0], t->n + 1, *p);
+ ATF_CHECK(fp != NULL);
+ setbuf(fp, NULL);
+ ATF_CHECK(fwrite(t->s, 1, t->n, fp) == (size_t)t->n);
+/*
+ * test fmemopen_write + fwrite(3)
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(buf[t->n] == '\0');
+
+/* don't accept non nul character at end of buffer */
+ ATF_CHECK(fwrite("\x1", 1, 1, fp) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ ATF_CHECK(feof(fp) == 0);
+#endif
+
+/* accept nul character at end of buffer */
+ ATF_CHECK(fwrite("\x0", 1, 1, fp) == 1);
+ ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
+ ATF_CHECK(feof(fp) == 0);
+
+/* reach EOF */
+ ATF_CHECK(fputc('\0', fp) == EOF);
+ ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
+
+/* compare */
+ ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0);
+ ATF_CHECK(buf[t->n] == '\0');
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test21);
+ATF_TC_HEAD(test21, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test21");
+}
+ATF_TC_BODY(test21, tc)
+{
+ struct testcase *t;
+ int len, i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = strnlen(t->s, t->n);
+ for (p = &mode_a[0]; *p != NULL; ++p) {
+ memcpy(&buf[0], t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+ setbuf(fp, NULL);
+/*
+ * test fmemopen_write + fputc(3)
+ */
+ if (len < t->n) {
+ for (i = len; i < t->n - 1; ++i) {
+ ATF_CHECK(ftello(fp) == (off_t)i);
+ ATF_CHECK(fputc(t->s[i - len], fp)
+ == t->s[i - len]);
+ ATF_CHECK(buf[i] == t->s[i - len]);
+ ATF_CHECK(ftello(fp) == (off_t)i + 1);
+#if !defined(__GLIBC__)
+ ATF_CHECK(buf[i + 1] == '\0');
+#endif
+ }
+
+/* don't accept non nul character at end of buffer */
+ ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
+ ATF_CHECK(fputc(0x1, fp) == EOF);
+ ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
+
+/* accept nul character at end of buffer */
+ ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
+ ATF_CHECK(fputc('\0', fp) == '\0');
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ }
+
+/* reach EOF */
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ ATF_CHECK(fputc('\0', fp) == EOF);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test22);
+ATF_TC_HEAD(test22, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test22");
+}
+ATF_TC_BODY(test22, tc)
+{
+ struct testcase *t0, *t1;
+ size_t len0, len1, nleft;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t0 = &testcases[0]; t0->s != NULL; ++t0) {
+ len0 = strnlen(t0->s, t0->n);
+ for (t1 = &testcases[0]; t1->s != NULL; ++t1) {
+ len1 = strnlen(t1->s, t1->n);
+ for (p = &mode_a[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t0->s, t0->n);
+ fp = fmemopen(&buf[0], t0->n, *p);
+ ATF_CHECK(fp != NULL);
+ setbuf(fp, NULL);
+/*
+ * test fmemopen_write + fwrite(3)
+ */
+ nleft = t0->n - len0;
+#if !defined(__GLIBC__)
+ if (nleft == 0 || len1 == nleft - 1) {
+ ATF_CHECK(fwrite(t1->s, 1, t1->n, fp)
+ == nleft);
+ ATF_CHECK(ftell(fp) == t1->n);
+ } else {
+ ATF_CHECK(fwrite(t1->s, 1, t1->n, fp)
+ == nleft - 1);
+ ATF_CHECK(ftell(fp) == t1->n - 1);
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+ }
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, test00);
+ ATF_TP_ADD_TC(tp, test01);
+ ATF_TP_ADD_TC(tp, test02);
+ ATF_TP_ADD_TC(tp, test03);
+ ATF_TP_ADD_TC(tp, test04);
+ ATF_TP_ADD_TC(tp, test05);
+ ATF_TP_ADD_TC(tp, test06);
+ ATF_TP_ADD_TC(tp, test07);
+ ATF_TP_ADD_TC(tp, test08);
+ ATF_TP_ADD_TC(tp, test09);
+ ATF_TP_ADD_TC(tp, test10);
+ ATF_TP_ADD_TC(tp, test11);
+#ifndef __FreeBSD__
+ ATF_TP_ADD_TC(tp, test12);
+#endif
+ ATF_TP_ADD_TC(tp, test13);
+ ATF_TP_ADD_TC(tp, test14);
+#ifndef __FreeBSD__
+ ATF_TP_ADD_TC(tp, test15);
+ ATF_TP_ADD_TC(tp, test16);
+ ATF_TP_ADD_TC(tp, test17);
+ ATF_TP_ADD_TC(tp, test18);
+ ATF_TP_ADD_TC(tp, test19);
+ ATF_TP_ADD_TC(tp, test20);
+ ATF_TP_ADD_TC(tp, test21);
+ ATF_TP_ADD_TC(tp, test22);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c b/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c
new file mode 100644
index 0000000..d9e2dd6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c
@@ -0,0 +1,444 @@
+/* $NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char *path = "fopen";
+
+ATF_TC_WITH_CLEANUP(fdopen_close);
+ATF_TC_HEAD(fdopen_close, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that descriptors are closed");
+}
+
+ATF_TC_BODY(fdopen_close, tc)
+{
+ FILE *f;
+ int fd;
+
+ /*
+ * Check that the file descriptor
+ * used to fdopen(3) a stream is
+ * closed once the stream is closed.
+ */
+ fd = open(path, O_RDWR | O_CREAT);
+
+ ATF_REQUIRE(fd >= 0);
+
+ f = fdopen(fd, "w+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(close(fd) == -1);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(fdopen_close, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fdopen_err);
+ATF_TC_HEAD(fdopen_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from fdopen(3)");
+}
+
+ATF_TC_BODY(fdopen_err, tc)
+{
+ int fd;
+
+ fd = open(path, O_RDONLY | O_CREAT);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "w") == NULL);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "a") == NULL);
+
+ ATF_REQUIRE(close(fd) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fdopen(fd, "r") == NULL);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fdopen(-1, "w+") == NULL);
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(fdopen_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fdopen_seek);
+ATF_TC_HEAD(fdopen_seek, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test stream position with fdopen(3)");
+}
+
+ATF_TC_BODY(fdopen_seek, tc)
+{
+ FILE *f;
+ int fd;
+
+ /*
+ * Verify that the file position associated
+ * with the stream corresponds with the offset
+ * set earlier for the file descriptor.
+ */
+ fd = open(path, O_RDWR | O_CREAT);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(write(fd, "garbage", 7) == 7);
+ ATF_REQUIRE(lseek(fd, 3, SEEK_SET) == 3);
+
+ f = fdopen(fd, "r+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(ftell(f) == 3);
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(fdopen_seek, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fopen_err);
+ATF_TC_HEAD(fopen_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from fopen(3)");
+}
+
+ATF_TC_BODY(fopen_err, tc)
+{
+ static const char *mode[] = {
+ "x", "xr", "xr", "+r+", "R", "W+", " aXX", "Xr", " r+", "" };
+
+ char buf[PATH_MAX + 1];
+ size_t i;
+ FILE *f;
+
+ f = fopen(path, "w+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ /*
+ * Note that also "invalid" characters
+ * may follow the mode-string whenever
+ * the first character is valid.
+ */
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ errno = 0;
+ f = fopen(path, mode[i]);
+
+ if (f == NULL && errno == EINVAL)
+ continue;
+
+ if (f != NULL)
+ (void)fclose(f);
+
+ atf_tc_fail_nonfatal("opened file as '%s'", mode[i]);
+ }
+
+ (void)unlink(path);
+ (void)memset(buf, 'x', sizeof(buf));
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EISDIR, fopen("/usr/bin", "w") == NULL);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, fopen("/a/b/c/d/e/f", "r") == NULL);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, fopen(buf, "r+") == NULL);
+}
+
+ATF_TC_CLEANUP(fopen_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fopen_append);
+ATF_TC_HEAD(fopen_append, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that append-mode works");
+}
+
+ATF_TC_BODY(fopen_append, tc)
+{
+ char buf[15];
+ FILE *f;
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ f = fopen(path, "w+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "a");
+
+ ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "r");
+
+ ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14);
+ ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0);
+
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(fopen_append, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fopen_mode);
+ATF_TC_HEAD(fopen_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test fopen(3) modes");
+}
+
+ATF_TC_BODY(fopen_mode, tc)
+{
+ size_t i;
+ FILE *f;
+
+ static const char *mode[] = {
+ "r", "r+", "w", "w+", "a", "a+",
+ "rb", "r+b", "wb", "w+b", "ab", "a+b"
+ "re", "r+e", "we", "w+e", "ae", "a+e"
+ "rf", "r+f", "wf", "w+f", "af", "a+f"
+ };
+
+ f = fopen(path, "w+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ /*
+ * Verify that various modes work.
+ */
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ f = fopen(path, mode[i]);
+
+ if (f != NULL) {
+ ATF_REQUIRE(fclose(f) == 0);
+ continue;
+ }
+
+ atf_tc_fail_nonfatal("failed to open file as %s", mode[i]);
+ }
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(fopen_mode, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(fopen_perm);
+ATF_TC_HEAD(fopen_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with fopen(3)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(fopen_perm, tc)
+{
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "a+") == NULL);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "w+") == NULL);
+}
+
+ATF_TC(fopen_regular);
+ATF_TC_HEAD(fopen_regular, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test fopen(3) with 'f' mode");
+}
+
+ATF_TC_BODY(fopen_regular, tc)
+{
+ static const char *mode[] = { "rf", "r+f", "wf", "w+f", "af", "a+f" };
+ static const char *devs[] = { _PATH_DEVNULL };
+
+ size_t i, j;
+ FILE *f;
+
+ for (i = 0; i < __arraycount(devs); i++) {
+
+ for (j = 0; j < __arraycount(mode); j++) {
+
+ errno = 0;
+ f = fopen(devs[i], mode[j]);
+
+ if (f == NULL && errno == EFTYPE)
+ continue;
+
+ if (f != NULL)
+ (void)fclose(f);
+
+ atf_tc_fail_nonfatal("opened %s as %s",
+ devs[i], mode[j]);
+ }
+ }
+}
+
+ATF_TC_WITH_CLEANUP(fopen_seek);
+ATF_TC_HEAD(fopen_seek, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test initial stream position");
+}
+
+ATF_TC_BODY(fopen_seek, tc)
+{
+ FILE *f;
+
+ f = fopen(path, "w+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ /*
+ * The position of the stream should be
+ * at the start, except for append-mode.
+ */
+ f = fopen(path, "r");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(ftello(f) == 0);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "a");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(ftello(f) == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(fopen_seek, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(freopen_std);
+ATF_TC_HEAD(freopen_std, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of freopen(3)");
+}
+
+ATF_TC_BODY(freopen_std, tc)
+{
+ FILE *std[2] = { stdin, stdout };
+ char buf[15];
+ size_t i;
+ FILE *f;
+
+ /*
+ * Associate a standard stream with a custom stream.
+ * Then write to the standard stream and verify that
+ * the result now appears in the custom stream.
+ */
+ for (i = 0; i < __arraycount(std); i++) {
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ f = fopen(path, "w+");
+ ATF_REQUIRE(f != NULL);
+
+ f = freopen(path, "w+", std[i]);
+ ATF_REQUIRE(f != NULL);
+
+ ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7);
+ ATF_REQUIRE(fprintf(std[i], "garbage") == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "r");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14);
+ ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0);
+
+ ATF_REQUIRE(fclose(f) == 0);
+ }
+
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(freopen_std, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fdopen_close);
+ ATF_TP_ADD_TC(tp, fdopen_err);
+ ATF_TP_ADD_TC(tp, fdopen_seek);
+ ATF_TP_ADD_TC(tp, fopen_append);
+ ATF_TP_ADD_TC(tp, fopen_err);
+ ATF_TP_ADD_TC(tp, fopen_mode);
+ ATF_TP_ADD_TC(tp, fopen_perm);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, fopen_regular);
+#endif
+ ATF_TP_ADD_TC(tp, fopen_seek);
+ ATF_TP_ADD_TC(tp, freopen_std);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c b/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c
new file mode 100644
index 0000000..ed7c0dc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c
@@ -0,0 +1,194 @@
+/* $NetBSD: t_fputc.c,v 1.1 2011/09/11 09:02:46 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_fputc.c,v 1.1 2011/09/11 09:02:46 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char *path = "fputc";
+static void puterr(int (*)(int, FILE *));
+static void putstr(int (*)(int, FILE *));
+
+static void
+puterr(int (*func)(int, FILE *))
+{
+ FILE *f;
+
+ f = fopen(path, "w+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+ ATF_REQUIRE(func('x', f) == EOF);
+}
+
+static void
+putstr(int (*func)(int, FILE *))
+{
+ const char *str = "1234567890x";
+ unsigned short i = 0;
+ char buf[10];
+ FILE *f;
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ f = fopen(path, "w+");
+ ATF_REQUIRE(f != NULL);
+
+ while (str[i] != 'x') {
+ ATF_REQUIRE(func(str[i], f) == str[i]);
+ i++;
+ }
+
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "r");
+ ATF_REQUIRE(f != NULL);
+
+ ATF_REQUIRE(fread(buf, 1, 10, f) == 10);
+ ATF_REQUIRE(strncmp(buf, str, 10) == 0);
+
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_WITH_CLEANUP(fputc_basic);
+ATF_TC_HEAD(fputc_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of fputc(3)");
+}
+
+ATF_TC_BODY(fputc_basic, tc)
+{
+ putstr(fputc);
+}
+
+ATF_TC_CLEANUP(fputc_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fputc_err);
+ATF_TC_HEAD(fputc_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from fputc(3)");
+}
+
+ATF_TC_BODY(fputc_err, tc)
+{
+ puterr(fputc);
+}
+
+ATF_TC_CLEANUP(fputc_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(putc_basic);
+ATF_TC_HEAD(putc_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of putc(3)");
+}
+
+ATF_TC_BODY(putc_basic, tc)
+{
+ putstr(putc);
+}
+
+ATF_TC_CLEANUP(putc_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(putc_err);
+ATF_TC_HEAD(putc_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from putc(3)");
+}
+
+ATF_TC_BODY(putc_err, tc)
+{
+ puterr(putc);
+}
+
+ATF_TC_CLEANUP(putc_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(putc_unlocked_basic);
+ATF_TC_HEAD(putc_unlocked_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of putc_unlocked(3)");
+}
+
+ATF_TC_BODY(putc_unlocked_basic, tc)
+{
+ putstr(putc_unlocked);
+}
+
+ATF_TC_CLEANUP(putc_unlocked_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(putc_unlocked_err);
+ATF_TC_HEAD(putc_unlocked_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from putc_unlocked(3)");
+}
+
+ATF_TC_BODY(putc_unlocked_err, tc)
+{
+ puterr(putc_unlocked);
+}
+
+ATF_TC_CLEANUP(putc_unlocked_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fputc_basic);
+ ATF_TP_ADD_TC(tp, fputc_err);
+ ATF_TP_ADD_TC(tp, putc_basic);
+ ATF_TP_ADD_TC(tp, putc_err);
+ ATF_TP_ADD_TC(tp, putc_unlocked_basic);
+ ATF_TP_ADD_TC(tp, putc_unlocked_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c b/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c
new file mode 100644
index 0000000..e423060
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c
@@ -0,0 +1,54 @@
+/* $NetBSD: t_mktemp.c,v 1.1 2013/04/22 21:05:12 christos Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_mktemp.c,v 1.1 2013/04/22 21:05:12 christos Exp $");
+
+#include <atf-c.h>
+#include <stdlib.h>
+
+ATF_TC(mktemp_not_exist);
+ATF_TC_HEAD(mktemp_not_exist, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that mktemp does not fail on"
+ " a path that does not exist");
+}
+
+ATF_TC_BODY(mktemp_not_exist, tc)
+{
+ char template[] = "I will barf/XXXXXX";
+ ATF_REQUIRE(mktemp(template) != NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, mktemp_not_exist);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_popen.c b/contrib/netbsd-tests/lib/libc/stdio/t_popen.c
new file mode 100644
index 0000000..699498c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_popen.c
@@ -0,0 +1,135 @@
+/* $NetBSD: t_popen.c,v 1.4 2013/02/15 23:27:19 christos Exp $ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matthias Scheler.
+ *
+ * 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/cdefs.h>
+#ifndef lint
+__COPYRIGHT("@(#) Copyright (c) 1999\
+ The NetBSD Foundation, Inc. All rights reserved.");
+#endif /* not lint */
+
+#ifndef lint
+__RCSID("$NetBSD: t_popen.c,v 1.4 2013/02/15 23:27:19 christos Exp $");
+#endif /* not lint */
+
+#include <atf-c.h>
+
+#include <sys/param.h>
+
+#include <errno.h>
+#include <err.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#define _PATH_CAT "/bin/cat"
+#define BUFSIZE (640*1024)
+ /* 640KB ought to be enough for everyone. */
+#define DATAFILE "popen.data"
+
+#define TEST_ERROR(a) \
+ do \
+ { \
+ warn(a); \
+ atf_tc_fail("Check stderr for error details."); \
+ } while ( /*CONSTCOND*/ 0 )
+
+ATF_TC_WITH_CLEANUP(popen_zeropad);
+ATF_TC_HEAD(popen_zeropad, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "output format zero padding");
+}
+
+ATF_TC_BODY(popen_zeropad, tc)
+{
+ char *buffer, command[MAXPATHLEN];
+ int idx, in;
+ FILE *my_pipe;
+
+ if ((buffer = malloc(BUFSIZE)) == NULL)
+ atf_tc_skip("Unable to allocate buffer.");
+
+ srand ((unsigned int)time(NULL));
+
+ for (idx = 0; idx < BUFSIZE; idx++)
+ buffer[idx]=(char)rand();
+
+ (void)snprintf(command, sizeof(command), "%s >%s",
+ _PATH_CAT, DATAFILE);
+
+ if ((my_pipe = popen(command, "w")) == NULL)
+ TEST_ERROR("popen write");
+
+ if (fwrite(buffer, sizeof(char), BUFSIZE, my_pipe) != BUFSIZE)
+ TEST_ERROR("fwrite");
+
+ if (pclose(my_pipe) == -1)
+ TEST_ERROR("pclose");
+
+ (void)snprintf(command, sizeof(command), "%s %s", _PATH_CAT, DATAFILE);
+
+ if ((my_pipe = popen(command, "r")) == NULL)
+ TEST_ERROR("popen read");
+
+ idx = 0;
+ while ((in = fgetc(my_pipe)) != EOF)
+ if (idx == BUFSIZE) {
+ errno = EFBIG;
+ TEST_ERROR("read");
+ }
+ else if ((char)in != buffer[idx++]) {
+ errno = EINVAL;
+ TEST_ERROR("read");
+ }
+
+ if (idx < BUFSIZE) {
+ errno = EIO;
+ TEST_ERROR("read");
+ }
+
+ if (pclose(my_pipe) == -1)
+ TEST_ERROR("pclose");
+}
+
+ATF_TC_CLEANUP(popen_zeropad, tc)
+{
+ (void)unlink(DATAFILE);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, popen_zeropad);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_printf.c b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c
new file mode 100644
index 0000000..5ef58f2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c
@@ -0,0 +1,204 @@
+/* $NetBSD: t_printf.c,v 1.8 2012/04/11 16:21:42 jruoho Exp $ */
+
+/*-
+ * 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 <sys/types.h>
+#include <sys/resource.h>
+#include <atf-c.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+
+#ifndef __NetBSD__
+#include <signal.h>
+#endif
+
+ATF_TC(snprintf_c99);
+ATF_TC_HEAD(snprintf_c99, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Test printf(3) C99 conformance (PR lib/22019)");
+}
+
+ATF_TC_BODY(snprintf_c99, tc)
+{
+ char s[4];
+
+ (void)memset(s, '\0', sizeof(s));
+ (void)snprintf(s, sizeof(s), "%#.o", 0);
+ (void)printf("printf = %#.o\n", 0);
+ (void)fprintf(stderr, "snprintf = %s", s);
+
+ ATF_REQUIRE(strlen(s) == 1);
+ ATF_REQUIRE(s[0] == '0');
+}
+
+ATF_TC(snprintf_dotzero);
+ATF_TC_HEAD(snprintf_dotzero, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "PR lib/32951: %%.0f formats (0.0,0.5] to \"0.\"");
+}
+
+ATF_TC_BODY(snprintf_dotzero, tc)
+{
+ char s[4];
+
+ ATF_CHECK(snprintf(s, sizeof(s), "%.0f", 0.1) == 1);
+ ATF_REQUIRE_STREQ(s, "0");
+}
+
+ATF_TC(snprintf_posarg);
+ATF_TC_HEAD(snprintf_posarg, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "test for positional arguments");
+}
+
+ATF_TC_BODY(snprintf_posarg, tc)
+{
+ char s[16];
+
+ ATF_CHECK(snprintf(s, sizeof(s), "%1$d", -23) == 3);
+ ATF_REQUIRE_STREQ(s, "-23");
+}
+
+ATF_TC(snprintf_posarg_width);
+ATF_TC_HEAD(snprintf_posarg_width, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "test for positional arguments with "
+ "field width");
+}
+
+ATF_TC_BODY(snprintf_posarg_width, tc)
+{
+ char s[16];
+
+ ATF_CHECK(snprintf(s, sizeof(s), "%1$*2$d", -23, 4) == 4);
+ ATF_REQUIRE_STREQ(s, " -23");
+}
+
+ATF_TC(snprintf_posarg_error);
+ATF_TC_HEAD(snprintf_posarg_error, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "test for positional arguments out "
+ "of bounds");
+}
+
+ATF_TC_BODY(snprintf_posarg_error, tc)
+{
+ char s[16], fmt[32];
+
+#ifndef __NetBSD__
+ atf_tc_expect_signal(SIGSEGV,
+ "some non-NetBSD platforms including FreeBSD don't validate "
+ "negative size; testcase blows up with SIGSEGV");
+#endif
+
+ snprintf(fmt, sizeof(fmt), "%%%zu$d", SIZE_MAX / sizeof(size_t));
+
+ ATF_CHECK(snprintf(s, sizeof(s), fmt, -23) == -1);
+}
+
+ATF_TC(snprintf_float);
+ATF_TC_HEAD(snprintf_float, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "test that floating conversions don't"
+ " leak memory");
+}
+
+ATF_TC_BODY(snprintf_float, tc)
+{
+ union {
+ double d;
+ uint64_t bits;
+ } u;
+ uint32_t ul, uh;
+ time_t now;
+ char buf[1000];
+ struct rlimit rl;
+
+ rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024;
+ ATF_CHECK(setrlimit(RLIMIT_AS, &rl) != -1);
+ rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024;
+ ATF_CHECK(setrlimit(RLIMIT_DATA, &rl) != -1);
+
+ time(&now);
+ srand(now);
+ for (size_t i = 0; i < 10000; i++) {
+ ul = rand();
+ uh = rand();
+ u.bits = (uint64_t)uh << 32 | ul;
+ ATF_CHECK(snprintf(buf, sizeof buf, " %.2f", u.d) != -1);
+ }
+}
+
+ATF_TC(sprintf_zeropad);
+ATF_TC_HEAD(sprintf_zeropad, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test output format zero padding (PR lib/44113)");
+}
+
+ATF_TC_BODY(sprintf_zeropad, tc)
+{
+ char str[1024];
+
+ ATF_CHECK(sprintf(str, "%010f", 0.0) == 10);
+ ATF_REQUIRE_STREQ(str, "000.000000");
+
+ /* ieeefp */
+#ifndef __vax__
+ /* printf(3) should ignore zero padding for nan/inf */
+ ATF_CHECK(sprintf(str, "%010f", NAN) == 10);
+ ATF_REQUIRE_STREQ(str, " nan");
+ ATF_CHECK(sprintf(str, "%010f", INFINITY) == 10);
+ ATF_REQUIRE_STREQ(str, " inf");
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, snprintf_c99);
+ ATF_TP_ADD_TC(tp, snprintf_dotzero);
+ ATF_TP_ADD_TC(tp, snprintf_posarg);
+ ATF_TP_ADD_TC(tp, snprintf_posarg_width);
+ ATF_TP_ADD_TC(tp, snprintf_posarg_error);
+ ATF_TP_ADD_TC(tp, snprintf_float);
+ ATF_TP_ADD_TC(tp, sprintf_zeropad);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c b/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c
new file mode 100644
index 0000000..194cd17
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c
@@ -0,0 +1,85 @@
+/* $NetBSD: t_scanf.c,v 1.3 2012/03/18 07:00:51 jruoho Exp $ */
+
+/*-
+ * 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.h>
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#define NUM -0x1234
+#define STRNUM ___STRING(NUM)
+
+ATF_TC(sscanf_neghex);
+ATF_TC_HEAD(sscanf_neghex, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "PR lib/21691: %%i and %%x fail with negative hex numbers");
+}
+
+ATF_TC_BODY(sscanf_neghex, tc)
+{
+ int i;
+
+ sscanf(STRNUM, "%i", &i);
+ ATF_REQUIRE(i == NUM);
+
+ sscanf(STRNUM, "%x", &i);
+ ATF_REQUIRE(i == NUM);
+}
+
+ATF_TC(sscanf_whitespace);
+ATF_TC_HEAD(sscanf_whitespace, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "verify sscanf skips all whitespace");
+}
+
+ATF_TC_BODY(sscanf_whitespace, tc)
+{
+ const char str[] = "\f\n\r\t\v%z";
+ char c;
+
+#ifndef __NetBSD__
+ atf_tc_expect_fail("fails on FreeBSD and some variants of Linux");
+#endif
+
+ /* set of "white space" symbols from isspace(3) */
+ c = 0;
+ (void)sscanf(str, "%%%c", &c);
+ ATF_REQUIRE(c == 'z');
+}
+
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sscanf_neghex);
+ ATF_TP_ADD_TC(tp, sscanf_whitespace);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c
new file mode 100644
index 0000000..c0641db
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c
@@ -0,0 +1,212 @@
+/* $NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Jason R. Thorpe.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+extern int __cxa_atexit(void (*func)(void *), void *, void *);
+extern void __cxa_finalize(void *);
+
+#ifdef __FreeBSD__
+/*
+ * On shared object unload, in __cxa_finalize, call and clear all installed
+ * atexit and __cxa_atexit handlers that are either installed by unloaded
+ * dso, or points to the functions provided by the dso.
+ *
+ * The reason of the change is to ensure that there is no lingering pointers
+ * to the unloaded code after the dlclose(3). It is known reason for infinite
+ * stream of the crash reports for many programs which use loadable modules
+ * and fail to properly clean on module unload. Examples are apache, php,
+ * perl etc.
+ *
+ * You pass the &dso_handle_1 and &dso_handle_2, which points inside the
+ * main binary, to the registration function. The code from r211706,
+ * correctly detects that they are for the main binary, and on the first
+ * call to __cxa_finalize(), which also pass pointer to main binary, all
+ * registered functions from the main binary are executed.
+ */
+
+static void *dso_handle_1 = (void *)1;
+static void *dso_handle_2 = (void *)2;
+static void *dso_handle_3 = (void *)3;
+#else
+static int dso_handle_1;
+static int dso_handle_2;
+static int dso_handle_3;
+#endif
+
+static int arg_1;
+static int arg_2;
+static int arg_3;
+
+static int exiting_state;
+
+#define ASSERT(expr) \
+do { \
+ if ((expr) == 0) { \
+ write(STDERR_FILENO, __func__, strlen(__func__)); \
+ write(STDERR_FILENO, ": ", 2); \
+ write(STDERR_FILENO, __STRING(expr), \
+ strlen(__STRING(expr))); \
+ write(STDERR_FILENO, "\n", 1); \
+ my_abort(); \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SUCCESS() \
+do { \
+ write(STDOUT_FILENO, __func__, strlen(__func__)); \
+ write(STDOUT_FILENO, "\n", 1); \
+} while (/*CONSTCOND*/0)
+
+static void
+my_abort(void)
+{
+
+ kill(getpid(), SIGABRT);
+ /* NOTREACHED */
+}
+
+static void
+cxa_handler_5(void *arg)
+{
+ static int cxa_handler_5_called;
+
+ ASSERT(arg == (void *)&arg_1);
+ ASSERT(cxa_handler_5_called == 0);
+ ASSERT(exiting_state == 5);
+
+ exiting_state--;
+ cxa_handler_5_called = 1;
+ SUCCESS();
+}
+
+static void
+cxa_handler_4(void *arg)
+{
+ static int cxa_handler_4_called;
+
+ ASSERT(arg == (void *)&arg_1);
+ ASSERT(cxa_handler_4_called == 0);
+ ASSERT(exiting_state == 4);
+
+ exiting_state--;
+ cxa_handler_4_called = 1;
+ SUCCESS();
+}
+
+static void
+cxa_handler_3(void *arg)
+{
+ static int cxa_handler_3_called;
+
+ ASSERT(arg == (void *)&arg_2);
+ ASSERT(cxa_handler_3_called == 0);
+ ASSERT(exiting_state == 3);
+
+ exiting_state--;
+ cxa_handler_3_called = 1;
+ SUCCESS();
+}
+
+static void
+cxa_handler_2(void *arg)
+{
+ static int cxa_handler_2_called;
+
+ ASSERT(arg == (void *)&arg_3);
+ ASSERT(cxa_handler_2_called == 0);
+ ASSERT(exiting_state == 2);
+
+ exiting_state--;
+ cxa_handler_2_called = 1;
+ SUCCESS();
+}
+
+static void
+normal_handler_1(void)
+{
+ static int normal_handler_1_called;
+
+ ASSERT(normal_handler_1_called == 0);
+ ASSERT(exiting_state == 1);
+
+ exiting_state--;
+ normal_handler_1_called = 1;
+ SUCCESS();
+}
+
+static void
+normal_handler_0(void)
+{
+ static int normal_handler_0_called;
+
+ ASSERT(normal_handler_0_called == 0);
+ ASSERT(exiting_state == 0);
+
+ normal_handler_0_called = 1;
+ SUCCESS();
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ exiting_state = 5;
+
+ ASSERT(0 == atexit(normal_handler_0));
+ ASSERT(0 == atexit(normal_handler_1));
+#ifdef __FreeBSD__
+ ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, dso_handle_2));
+ ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, dso_handle_3));
+
+ __cxa_finalize(dso_handle_1);
+ __cxa_finalize(dso_handle_2);
+#else
+ ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2));
+ ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, &dso_handle_3));
+
+ __cxa_finalize(&dso_handle_1);
+ __cxa_finalize(&dso_handle_2);
+#endif
+ exit(0);
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c
new file mode 100644
index 0000000..ec2b9bb
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c
@@ -0,0 +1,130 @@
+/* $NetBSD: h_getopt.c,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#ifdef __FreeBSD__
+#include <libutil.h>
+#endif
+
+#define WS "\t\n "
+#define debug 0
+
+int
+main(int argc, char *argv[])
+{
+ size_t len, lineno = 0;
+ char *line, *ptr, *optstring = NULL, *result = NULL;
+ char buf[1024];
+ char *args[100];
+ char arg[100];
+ int nargs = -1;
+ int c;
+
+ while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) {
+ if (strncmp(line, "load:", 5) == 0) {
+ if (optstring)
+ free(optstring);
+ optstring = strtok(&line[6], WS);
+ if (optstring == NULL)
+ errx(1, "missing optstring at line %ld",
+ (unsigned long)lineno);
+ optstring = strdup(optstring);
+ if (debug)
+ fprintf(stderr, "optstring = %s\n", optstring);
+ } else if (strncmp(line, "args:", 5) == 0) {
+ for (; nargs >= 0; nargs--) {
+ if (args[nargs] != NULL)
+ free(args[nargs]);
+ }
+ args[nargs = 0] = strtok(&line[6], WS);
+ if (args[nargs] == NULL)
+ errx(1, "missing args at line %ld",
+ (unsigned long)lineno);
+
+ args[nargs] = strdup(args[nargs]);
+ while ((args[++nargs] = strtok(NULL, WS)) != NULL)
+ args[nargs] = strdup(args[nargs]);
+ if (debug) {
+ int i = 0;
+ for (i = 0; i < nargs; i++)
+ fprintf(stderr, "argv[%d] = %s\n", i,
+ args[i]);
+ }
+ } else if (strncmp(line, "result:", 7) == 0) {
+ buf[0] = '\0';
+ optind = optreset = 1;
+ if (result)
+ free(result);
+ result = strtok(&line[8], WS);
+ if (result == NULL)
+ errx(1, "missing result at line %ld",
+ (unsigned long)lineno);
+ result = strdup(result);
+ if (nargs == -1)
+ errx(1, "result: without args:");
+ if (debug)
+ fprintf(stderr, "result = %s\n", result);
+ while ((c = getopt(nargs, args, optstring)) != -1) {
+ if (c == ':')
+ err(1, "`:' found as argument char");
+ if ((ptr = strchr(optstring, c)) == NULL) {
+ snprintf(arg, sizeof(arg), "!%c,", c);
+ strcat(buf, arg);
+ continue;
+ }
+ if (ptr[1] != ':')
+ snprintf(arg, sizeof(arg), "%c,", c);
+ else
+ snprintf(arg, sizeof(arg), "%c=%s,",
+ c, optarg);
+ strcat(buf, arg);
+ }
+ len = strlen(buf);
+ if (len > 0) {
+ buf[len - 1] = '|';
+ buf[len] = '\0';
+ } else {
+ buf[0] = '|';
+ buf[1] = '\0';
+ }
+ snprintf(arg, sizeof(arg), "%d", nargs - optind);
+ strcat(buf, arg);
+ if (strcmp(buf, result) != 0)
+ errx(1, "`%s' != `%s'", buf, result);
+ }
+ free(line);
+ }
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c
new file mode 100644
index 0000000..2293e2c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c
@@ -0,0 +1,242 @@
+/* $NetBSD: h_getopt_long.c,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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 <ctype.h>
+#include <err.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef __FreeBSD__
+#include <libutil.h>
+#endif
+
+#define SKIPWS(p) while (isspace((int)(*p))) p++
+#define WS "\t\n "
+
+int
+main(int argc, char *argv[])
+{
+ size_t len, lineno = 0;
+ char *line, *eptr, *longopt, *ptr, *optstring = NULL, *result = NULL;
+ char buf[1024];
+ char *args[128];
+ char arg[256];
+ int nargs = -1;
+ int c;
+ int nlongopts = 0;
+ int maxnlongopts = 0;
+ int *longopt_flags = NULL;
+ struct option *longopts = NULL;
+
+ while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) {
+ if (strncmp(line, "optstring:", 10) == 0) {
+ if (optstring)
+ free(optstring);
+ optstring = strtok(&line[11], WS);
+ if (optstring == NULL)
+ errx(1, "missing optstring at line %ld",
+ (unsigned long)lineno);
+ optstring = strdup(optstring);
+ } else if (strncmp(line, "longopts:", 9) == 0) {
+ if (longopts) {
+ int i;
+ for (i = 0; i < nlongopts; i++)
+ if (longopts[i].name != NULL)
+ free(__UNCONST(longopts[i].name));
+ free(longopts);
+ }
+ if (longopt_flags)
+ free(longopt_flags);
+ nlongopts = 0;
+ ptr = strtok(&line[10], WS);
+ if (ptr == NULL)
+ errx(1, "missing longopts at line %ld",
+ (unsigned long)lineno);
+ maxnlongopts = strtoul(ptr, &eptr, 10);
+ if (*eptr != '\0')
+ warnx("garbage in longopts at line %ld",
+ (unsigned long)lineno);
+ maxnlongopts++; /* space for trailer */
+ longopts =
+ (struct option *)calloc(sizeof(struct option),
+ maxnlongopts);
+ if (longopts == NULL)
+ err(1, "calloc");
+ longopt_flags = (int *)calloc(sizeof(int), maxnlongopts);
+ if (longopt_flags == NULL)
+ err(1, "calloc");
+ } else if (strncmp(line, "longopt:", 8) == 0) {
+ if (longopts == NULL)
+ errx(1, "longopt: without longopts at line %ld",
+ (unsigned long)lineno);
+ if (nlongopts >= maxnlongopts)
+ errx(1, "longopt: too many options at line %ld",
+ (unsigned long)lineno);
+ /* name */
+ ptr = &line[9];
+ SKIPWS(ptr);
+ longopt = strsep(&ptr, ",");
+ if (longopt == NULL)
+ errx(1, "missing longopt at line %ld",
+ (unsigned long)lineno);
+ longopts[nlongopts].name = strdup(longopt);
+ /* has_arg */
+ SKIPWS(ptr);
+ longopt = strsep(&ptr, ",");
+ if (*longopt != '\0') {
+ if (strncmp(longopt, "0", 1) == 0 ||
+ strncmp(longopt, "no_argument", 2) == 0)
+ longopts[nlongopts].has_arg = no_argument;
+ else if (strncmp(longopt, "1", 1) == 0 ||
+ strncmp(longopt, "required_argument", 8) == 0)
+ longopts[nlongopts].has_arg = required_argument;
+ else if (strncmp(longopt, "2", 1) == 0 ||
+ strncmp(longopt, "optional_argument", 8) == 0)
+ longopts[nlongopts].has_arg = optional_argument;
+ else
+ errx(1, "unknown has_arg %s at line %ld",
+ longopt, (unsigned long)lineno);
+ }
+ /* flag */
+ SKIPWS(ptr);
+ longopt = strsep(&ptr, ",");
+ if (*longopt != '\0' &&
+ strncmp(longopt, "NULL", 4) != 0)
+ longopts[nlongopts].flag = &longopt_flags[nlongopts];
+ /* val */
+ SKIPWS(ptr);
+ longopt = strsep(&ptr, ",");
+ if (*longopt == '\0')
+ errx(1, "missing val at line %ld",
+ (unsigned long)lineno);
+ if (*longopt != '\'') {
+ longopts[nlongopts].val =
+ (int)strtoul(longopt, &eptr, 10);
+ if (*eptr != '\0')
+ errx(1, "invalid val at line %ld",
+ (unsigned long)lineno);
+ } else
+ longopts[nlongopts].val = (int)longopt[1];
+ nlongopts++;
+ } else if (strncmp(line, "args:", 5) == 0) {
+ for (; nargs >= 0; nargs--) {
+ if (args[nargs] != NULL)
+ free(args[nargs]);
+ }
+ args[nargs = 0] = strtok(&line[6], WS);
+ if (args[nargs] == NULL)
+ errx(1, "Missing args");
+
+ args[nargs] = strdup(args[nargs]);
+ while ((args[++nargs] = strtok(NULL, WS)) != NULL)
+ args[nargs] = strdup(args[nargs]);
+ } else if (strncmp(line, "result:", 7) == 0) {
+ int li;
+ buf[0] = '\0';
+ optind = optreset = 1;
+ if (result)
+ free(result);
+ result = strtok(&line[8], WS);
+ if (result == NULL)
+ errx(1, "missing result at line %ld",
+ (unsigned long)lineno);
+ if (optstring == NULL)
+ errx(1, "result: without optstring");
+ if (longopts == NULL || nlongopts == 0)
+ errx(1, "result: without longopts");
+ result = strdup(result);
+ if (nargs == -1)
+ errx(1, "result: without args");
+ li = -2;
+ while ((c = getopt_long(nargs, args, optstring,
+ longopts, &li)) != -1) {
+ if (c == ':')
+ errx(1, "`:' found as argument char");
+ if (li == -2) {
+ ptr = strchr(optstring, c);
+ if (ptr == NULL) {
+ snprintf(arg, sizeof(arg),
+ "!%c,", c);
+ strcat(buf, arg);
+ continue;
+ }
+ if (ptr[1] != ':')
+ snprintf(arg, sizeof(arg),
+ "%c,", c);
+ else
+ snprintf(arg, sizeof(arg),
+ "%c=%s,", c, optarg);
+ } else {
+ switch (longopts[li].has_arg) {
+ case no_argument:
+ snprintf(arg, sizeof(arg), "-%s,",
+ longopts[li].name);
+ break;
+ case required_argument:
+ snprintf(arg, sizeof(arg),
+ "-%s=%s,",
+ longopts[li].name, optarg);
+ break;
+ case optional_argument:
+ snprintf(arg, sizeof(arg),
+ "-%s%s%s,",
+ longopts[li].name,
+ (optarg)? "=" : "",
+ (optarg)? optarg : "");
+ break;
+ default:
+ errx(1, "internal error");
+ }
+ }
+ strcat(buf, arg);
+ li = -2;
+ }
+ len = strlen(buf);
+ if (len > 0) {
+ buf[len - 1] = '|';
+ buf[len] = '\0';
+ } else {
+ buf[0] = '|';
+ buf[1] = '\0';
+ }
+ snprintf(arg, sizeof(arg), "%d", nargs - optind);
+ strcat(buf, arg);
+ if (strcmp(buf, result) != 0)
+ errx(1, "`%s' != `%s'", buf, result);
+ } else
+ errx(1, "unknown directive at line %ld",
+ (unsigned long)lineno);
+ free(line);
+ }
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c b/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c
new file mode 100644
index 0000000..282a125
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c
@@ -0,0 +1,154 @@
+/* $NetBSD: t_abs.c,v 1.3 2014/03/01 22:38:13 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_abs.c,v 1.3 2014/03/01 22:38:13 joerg Exp $");
+
+#include <atf-c.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdlib.h>
+
+ATF_TC(abs_basic);
+ATF_TC_HEAD(abs_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that abs(3) works");
+}
+
+ATF_TC_BODY(abs_basic, tc)
+{
+ static const struct {
+ int val;
+ int res;
+ } table[] = {
+ { 0, 0 },
+ { +0, 0 },
+ { -0, 0 },
+ { -0x1010, 0x1010 },
+ { INT_MAX, INT_MAX },
+ { -INT_MAX, INT_MAX },
+ };
+
+ for (size_t i = 0; i < __arraycount(table); i++)
+ ATF_CHECK(abs(table[i].val) == table[i].res);
+}
+
+ATF_TC(imaxabs_basic);
+ATF_TC_HEAD(imaxabs_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that imaxabs(3) works");
+}
+
+ATF_TC_BODY(imaxabs_basic, tc)
+{
+ static const struct {
+ intmax_t val;
+ intmax_t res;
+ } table[] = {
+ { 0, 0 },
+ { INT_MAX, INT_MAX },
+ { -INT_MAX, INT_MAX },
+ { LONG_MAX, LONG_MAX },
+ { -LONG_MAX, LONG_MAX },
+ { LLONG_MAX, LLONG_MAX },
+ { -LLONG_MAX, LLONG_MAX },
+ { INT_MAX, INT_MAX },
+ { -INT_MAX, INT_MAX },
+ };
+
+ for (size_t i = 0; i < __arraycount(table); i++)
+ ATF_CHECK(imaxabs(table[i].val) == table[i].res);
+}
+
+ATF_TC(labs_basic);
+ATF_TC_HEAD(labs_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that labs(3) works");
+}
+
+ATF_TC_BODY(labs_basic, tc)
+{
+ static const struct {
+ long val;
+ long res;
+ } table[] = {
+ { 0, 0 },
+ { +0, 0 },
+ { -0, 0 },
+ { -1, 1 },
+ { LONG_MAX, LONG_MAX },
+ { -LONG_MAX, LONG_MAX },
+ { INT_MAX, INT_MAX },
+ { -INT_MAX, INT_MAX },
+ };
+
+ for (size_t i = 0; i < __arraycount(table); i++)
+ ATF_CHECK(labs(table[i].val) == table[i].res);
+}
+
+ATF_TC(llabs_basic);
+ATF_TC_HEAD(llabs_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that llabs(3) works");
+}
+
+ATF_TC_BODY(llabs_basic, tc)
+{
+ static const struct {
+ long long val;
+ long long res;
+ } table[] = {
+ { 0, 0 },
+ { +0, 0 },
+ { -0, 0 },
+ { -1, 1 },
+ { INT_MAX, INT_MAX },
+ { -INT_MAX, INT_MAX },
+ { LONG_MAX, LONG_MAX },
+ { -LONG_MAX, LONG_MAX },
+ { LLONG_MAX, LLONG_MAX },
+ { -LLONG_MAX, LLONG_MAX },
+ { -0x100000000LL, 0x100000000LL },
+ };
+
+ for (size_t i = 0; i < __arraycount(table); i++)
+ ATF_CHECK(llabs(table[i].val) == table[i].res);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, abs_basic);
+ ATF_TP_ADD_TC(tp, imaxabs_basic);
+ ATF_TP_ADD_TC(tp, labs_basic);
+ ATF_TP_ADD_TC(tp, llabs_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh b/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh
new file mode 100755
index 0000000..d11268b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh
@@ -0,0 +1,54 @@
+# $NetBSD: t_atexit.sh,v 1.1 2011/01/12 19:44:08 pgoyette Exp $
+#
+# Copyright (c) 2011 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 atexit
+atexit_head()
+{
+ atf_set "descr" "Checks atexit(3) and __cxa_atexit()/__cxa_finalize()"
+}
+atexit_body()
+{
+ $(atf_get_srcdir)/h_atexit >out \
+ || atf_fail "h_exit failed, see output of the test for details"
+
+ cat >exp <<EOF
+cxa_handler_5
+cxa_handler_4
+cxa_handler_3
+cxa_handler_2
+normal_handler_1
+normal_handler_0
+EOF
+
+ diff -Nru exp out \
+ || atf_fail "h_exit failed, see output of the test for details"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case atexit
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_atoi.c b/contrib/netbsd-tests/lib/libc/stdlib/t_atoi.c
new file mode 100644
index 0000000..3e0c35f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_atoi.c
@@ -0,0 +1,121 @@
+/* $NetBSD: t_atoi.c,v 1.2 2012/03/29 05:56:36 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_atoi.c,v 1.2 2012/03/29 05:56:36 jruoho Exp $");
+
+#include <atf-c.h>
+#include <float.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+ATF_TC(atof_strtod);
+ATF_TC_HEAD(atof_strtod, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that atof(3) matches the corresponding strtod(3) call");
+}
+
+ATF_TC_BODY(atof_strtod, tc)
+{
+ char buf[128];
+
+ (void)snprintf(buf, sizeof(buf), "%f\n", DBL_MAX);
+
+ ATF_REQUIRE(atof("0") == strtod("0", NULL));
+ ATF_REQUIRE(atof("-1") == strtod("-1", NULL));
+ ATF_REQUIRE(atof(buf) == strtod(buf, NULL));
+}
+
+ATF_TC(atoi_strtol);
+ATF_TC_HEAD(atoi_strtol, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that atoi(3) matches the corresponding strtol(3) call");
+}
+
+ATF_TC_BODY(atoi_strtol, tc)
+{
+ char buf[64];
+
+ (void)snprintf(buf, sizeof(buf), "%d\n", INT_MAX);
+
+ ATF_REQUIRE(atoi("0") == strtol("0", NULL, 10));
+ ATF_REQUIRE(atoi("-1") == strtol("-1", NULL, 10));
+ ATF_REQUIRE(atoi(buf) == strtol(buf, NULL, 10));
+}
+
+ATF_TC(atol_strtol);
+ATF_TC_HEAD(atol_strtol, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that atol(3) matches the corresponding strtol(3) call");
+}
+
+ATF_TC_BODY(atol_strtol, tc)
+{
+ char buf[64];
+
+ (void)snprintf(buf, sizeof(buf), "%ld\n", LONG_MAX);
+
+ ATF_REQUIRE(atol("0") == strtol("0", NULL, 10));
+ ATF_REQUIRE(atol("-1") == strtol("-1", NULL, 10));
+ ATF_REQUIRE(atol(buf) == strtol(buf, NULL, 10));
+}
+
+ATF_TC(atoll_strtoll);
+ATF_TC_HEAD(atoll_strtoll, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that atoll(3) matches the corresponding strtoll(3) call");
+}
+
+ATF_TC_BODY(atoll_strtoll, tc)
+{
+ char buf[128];
+
+ (void)snprintf(buf, sizeof(buf), "%lld\n", LLONG_MAX);
+
+ ATF_REQUIRE(atoll("0") == strtoll("0", NULL, 10));
+ ATF_REQUIRE(atoll("-1") == strtoll("-1", NULL, 10));
+ ATF_REQUIRE(atoll(buf) == strtoll(buf, NULL, 10));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, atof_strtod);
+ ATF_TP_ADD_TC(tp, atoi_strtol);
+ ATF_TP_ADD_TC(tp, atol_strtol);
+ ATF_TP_ADD_TC(tp, atoll_strtoll);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_div.c b/contrib/netbsd-tests/lib/libc/stdlib/t_div.c
new file mode 100644
index 0000000..376f357
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_div.c
@@ -0,0 +1,98 @@
+/* $NetBSD: t_div.c,v 1.2 2011/07/07 11:12:18 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2001 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 <stdio.h>
+#include <stdlib.h>
+
+#define NUM 1999236
+#define DENOM 1000000
+#define QUOT 1
+#define REM 999236
+
+ATF_TC(div_basic);
+ATF_TC_HEAD(div_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test div(3) for correctness");
+}
+
+ATF_TC_BODY(div_basic, tc)
+{
+ div_t d;
+
+ d = div(NUM, DENOM);
+
+ ATF_CHECK(d.quot == QUOT);
+ ATF_CHECK(d.rem == REM);
+}
+
+ATF_TC(ldiv_basic);
+ATF_TC_HEAD(ldiv_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test ldiv(3) for correctness");
+}
+
+ATF_TC_BODY(ldiv_basic, tc)
+{
+ ldiv_t ld;
+
+ ld = ldiv(NUM, DENOM);
+
+ ATF_CHECK(ld.quot == QUOT);
+ ATF_CHECK(ld.rem == REM);
+}
+
+ATF_TC(lldiv_basic);
+ATF_TC_HEAD(lldiv_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test lllldiv(3) for correctness");
+}
+
+ATF_TC_BODY(lldiv_basic, tc)
+{
+ lldiv_t lld;
+
+ lld = lldiv(NUM, DENOM);
+
+ ATF_CHECK(lld.quot == QUOT);
+ ATF_CHECK(lld.rem == REM);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, div_basic);
+ ATF_TP_ADD_TC(tp, ldiv_basic);
+ ATF_TP_ADD_TC(tp, lldiv_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c b/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c
new file mode 100644
index 0000000..067cb51
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_exit.c
@@ -0,0 +1,186 @@
+/* $NetBSD: t_exit.c,v 1.1 2011/05/09 07:31:51 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_exit.c,v 1.1 2011/05/09 07:31:51 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static bool fail;
+static void func(void);
+
+static void
+func(void)
+{
+ fail = false;
+}
+
+ATF_TC(exit_atexit);
+ATF_TC_HEAD(exit_atexit, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of atexit(3)");
+}
+
+ATF_TC_BODY(exit_atexit, tc)
+{
+ pid_t pid;
+ int sta;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (atexit(func) != 0)
+ _exit(EXIT_FAILURE);
+
+ fail = true;
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("atexit(3) failed");
+
+ if (fail != false)
+ atf_tc_fail("atexit(3) was not called");
+}
+
+ATF_TC(exit_basic);
+ATF_TC_HEAD(exit_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of exit(3)");
+}
+
+ATF_TC_BODY(exit_basic, tc)
+{
+ pid_t pid;
+ int sta;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ exit(EXIT_SUCCESS);
+ exit(EXIT_FAILURE);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("exit(3) did not exit successfully");
+}
+
+ATF_TC(exit_status);
+ATF_TC_HEAD(exit_status, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test exit(3) status");
+}
+
+ATF_TC_BODY(exit_status, tc)
+{
+ const int n = 10;
+ int i, sta;
+ pid_t pid;
+
+ for (i = 0; i < n; i++) {
+
+ pid = fork();
+
+ if (pid < 0)
+ exit(EXIT_FAILURE);
+
+ if (pid == 0)
+ exit(i);
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != i)
+ atf_tc_fail("invalid exit(3) status");
+ }
+}
+
+ATF_TC(exit_tmpfile);
+ATF_TC_HEAD(exit_tmpfile, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Temporary files are unlinked?");
+}
+
+ATF_TC_BODY(exit_tmpfile, tc)
+{
+ int sta, fd = -1;
+ char buf[12];
+ pid_t pid;
+ FILE *f;
+
+ (void)strlcpy(buf, "exit.XXXXXX", sizeof(buf));
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ fd = mkstemp(buf);
+
+ if (fd < 0)
+ exit(EXIT_FAILURE);
+
+ exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("failed to create temporary file");
+
+ f = fdopen(fd, "r");
+
+ if (f != NULL)
+ atf_tc_fail("exit(3) did not clear temporary file");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, exit_atexit);
+ ATF_TP_ADD_TC(tp, exit_basic);
+ ATF_TP_ADD_TC(tp, exit_status);
+ ATF_TP_ADD_TC(tp, exit_tmpfile);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c
new file mode 100644
index 0000000..5a8fa28
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c
@@ -0,0 +1,211 @@
+/* $NetBSD: t_getenv.c,v 1.2 2011/07/15 13:54:31 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_getenv.c,v 1.2 2011/07/15 13:54:31 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef __FreeBSD__
+#include <signal.h>
+#endif
+
+extern char **environ;
+
+ATF_TC(clearenv_basic);
+ATF_TC_HEAD(clearenv_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test user clearing environment directly");
+}
+
+ATF_TC_BODY(clearenv_basic, tc)
+{
+ char name[1024], value[1024];
+
+ for (size_t i = 0; i < 1024; i++) {
+ snprintf(name, sizeof(name), "crap%zu", i);
+ snprintf(value, sizeof(value), "%zu", i);
+ ATF_CHECK(setenv(name, value, 1) != -1);
+ }
+
+ *environ = NULL;
+
+ for (size_t i = 0; i < 1; i++) {
+ snprintf(name, sizeof(name), "crap%zu", i);
+ snprintf(value, sizeof(value), "%zu", i);
+ ATF_CHECK(setenv(name, value, 1) != -1);
+ }
+
+ ATF_CHECK_STREQ(getenv("crap0"), "0");
+ ATF_CHECK(getenv("crap1") == NULL);
+ ATF_CHECK(getenv("crap2") == NULL);
+}
+
+ATF_TC(getenv_basic);
+ATF_TC_HEAD(getenv_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test setenv(3), getenv(3)");
+}
+
+ATF_TC_BODY(getenv_basic, tc)
+{
+ ATF_CHECK(setenv("EVIL", "very=bad", 1) != -1);
+ ATF_CHECK_STREQ(getenv("EVIL"), "very=bad");
+ ATF_CHECK(getenv("EVIL=very") == NULL);
+ ATF_CHECK(unsetenv("EVIL") != -1);
+}
+
+ATF_TC(putenv_basic);
+ATF_TC_HEAD(putenv_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test putenv(3), getenv(3), unsetenv(3)");
+}
+
+
+ATF_TC_BODY(putenv_basic, tc)
+{
+ char string[1024];
+
+ snprintf(string, sizeof(string), "crap=true");
+ ATF_CHECK(putenv(string) != -1);
+ ATF_CHECK_STREQ(getenv("crap"), "true");
+ string[1] = 'l';
+ ATF_CHECK_STREQ(getenv("clap"), "true");
+ ATF_CHECK(getenv("crap") == NULL);
+ string[1] = 'r';
+ ATF_CHECK(unsetenv("crap") != -1);
+ ATF_CHECK(getenv("crap") == NULL);
+
+ ATF_CHECK_ERRNO(EINVAL, putenv(NULL) == -1);
+ ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("val")) == -1);
+ ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("=val")) == -1);
+}
+
+ATF_TC(setenv_basic);
+ATF_TC_HEAD(setenv_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test setenv(3), getenv(3), unsetenv(3)");
+ atf_tc_set_md_var(tc, "timeout", "300");
+}
+
+ATF_TC_BODY(setenv_basic, tc)
+{
+ const size_t numvars = 8192;
+ size_t i, offset;
+ char name[1024];
+ char value[1024];
+
+ offset = lrand48();
+ for (i = 0; i < numvars; i++) {
+ (void)snprintf(name, sizeof(name), "var%zu",
+ (i * 7 + offset) % numvars);
+ (void)snprintf(value, sizeof(value), "value%ld", lrand48());
+ ATF_CHECK(setenv(name, value, 1) != -1);
+ ATF_CHECK(setenv(name, "foo", 0) != -1);
+ ATF_CHECK_STREQ(getenv(name), value);
+ }
+
+ offset = lrand48();
+ for (i = 0; i < numvars; i++) {
+ (void)snprintf(name, sizeof(name), "var%zu",
+ (i * 11 + offset) % numvars);
+ ATF_CHECK(unsetenv(name) != -1);
+ ATF_CHECK(getenv(name) == NULL);
+ ATF_CHECK(unsetenv(name) != -1);
+ }
+
+ ATF_CHECK_ERRNO(EINVAL, setenv(NULL, "val", 1) == -1);
+ ATF_CHECK_ERRNO(EINVAL, setenv("", "val", 1) == -1);
+ ATF_CHECK_ERRNO(EINVAL, setenv("v=r", "val", 1) == -1);
+#ifdef __FreeBSD__
+ /*
+ Both FreeBSD and OS/X does not validate the second
+ argument to setenv(3)
+ */
+ atf_tc_expect_signal(SIGSEGV, "FreeBSD does not validate the second "
+ "argument to setenv(3); see bin/189805");
+#endif
+
+ ATF_CHECK_ERRNO(EINVAL, setenv("var", NULL, 1) == -1);
+
+ ATF_CHECK(setenv("var", "=val", 1) == 0);
+ ATF_CHECK_STREQ(getenv("var"), "=val");
+}
+
+ATF_TC(setenv_mixed);
+ATF_TC_HEAD(setenv_mixed, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test mixing setenv(3), unsetenv(3) and putenv(3)");
+}
+
+ATF_TC_BODY(setenv_mixed, tc)
+{
+ char string[32];
+
+ (void)strcpy(string, "mixedcrap=putenv");
+
+ ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1);
+ ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv");
+ ATF_CHECK(putenv(string) != -1);
+ ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv");
+ ATF_CHECK(unsetenv("mixedcrap") != -1);
+ ATF_CHECK(getenv("mixedcrap") == NULL);
+
+ ATF_CHECK(putenv(string) != -1);
+ ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv");
+ ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1);
+ ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv");
+ ATF_CHECK(unsetenv("mixedcrap") != -1);
+ ATF_CHECK(getenv("mixedcrap") == NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, clearenv_basic);
+ ATF_TP_ADD_TC(tp, getenv_basic);
+ ATF_TP_ADD_TC(tp, putenv_basic);
+ ATF_TP_ADD_TC(tp, setenv_basic);
+ ATF_TP_ADD_TC(tp, setenv_mixed);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c
new file mode 100644
index 0000000..d935629
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c
@@ -0,0 +1,250 @@
+/* $NetBSD: t_getenv_thread.c,v 1.2 2012/03/15 02:02:23 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matthias Scheler.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_getenv_thread.c,v 1.2 2012/03/15 02:02:23 joerg Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#define THREADED_NUM_THREADS 8
+#define THREADED_NUM_VARS 16
+#define THREADED_VAR_NAME "THREADED%zu"
+#define THREADED_RUN_TIME 10
+
+static void *thread_getenv_r(void *);
+static void *thread_putenv(void *);
+static void *thread_setenv(void *);
+static void *thread_unsetenv(void *);
+
+static void *
+thread_getenv_r(void *arg)
+{
+ time_t endtime;
+
+ endtime = *(time_t *)arg;
+ do {
+ size_t i;
+ char name[32], value[128];
+
+ i = lrand48() % THREADED_NUM_VARS;
+ (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i);
+
+ if (getenv_r(name, value, sizeof(value)) == -1) {
+ ATF_CHECK(errno == ENOENT);
+ }
+ } while (time(NULL) < endtime);
+
+ return NULL;
+}
+
+
+static void *
+thread_putenv(void *arg)
+{
+ time_t endtime;
+ size_t i;
+ static char vars[THREADED_NUM_VARS][128];
+
+ for (i = 0; i < THREADED_NUM_VARS; i++) {
+ (void)snprintf(vars[i], sizeof(vars[i]),
+ THREADED_VAR_NAME "=putenv %ld", i, lrand48());
+ }
+
+ endtime = *(time_t *)arg;
+ do {
+ char name[128];
+
+ i = lrand48() % THREADED_NUM_VARS;
+ (void)strlcpy(name, vars[i], sizeof(name));
+ *strchr(name, '=') = '\0';
+
+ ATF_CHECK(unsetenv(name) != -1);
+ ATF_CHECK(putenv(vars[i]) != -1);
+ } while (time(NULL) < endtime);
+
+ return NULL;
+}
+
+static void *
+thread_setenv(void *arg)
+{
+ time_t endtime;
+
+ endtime = *(time_t *)arg;
+ do {
+ size_t i;
+ char name[32], value[64];
+
+ i = lrand48() % THREADED_NUM_VARS;
+ (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i);
+ (void)snprintf(value, sizeof(value), "setenv %ld", lrand48());
+
+ ATF_CHECK(setenv(name, value, 1) != -1);
+ } while (time(NULL) < endtime);
+
+ return NULL;
+}
+
+static void *
+thread_unsetenv(void *arg)
+{
+ time_t endtime;
+
+ endtime = *(time_t *)arg;
+ do {
+ size_t i;
+ char name[32];
+
+ i = lrand48() % THREADED_NUM_VARS;
+ (void)snprintf(name, sizeof(name), THREADED_VAR_NAME, i);
+
+ ATF_CHECK(unsetenv(name) != -1);
+ } while (time(NULL) < endtime);
+
+ return NULL;
+}
+
+ATF_TC(getenv_r_thread);
+ATF_TC_HEAD(getenv_r_thread, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test getenv_r(3) with threads");
+ atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5);
+}
+
+ATF_TC_BODY(getenv_r_thread, tc)
+{
+ pthread_t threads[THREADED_NUM_THREADS];
+ time_t endtime;
+ size_t i, j;
+
+ endtime = time(NULL) + THREADED_RUN_TIME;
+
+ for (i = j = 0; j < 2; j++) {
+
+ ATF_CHECK(pthread_create(&threads[i++], NULL, thread_getenv_r,
+ &endtime) == 0);
+ }
+
+ for (j = 0; j < i; j++)
+ ATF_CHECK(pthread_join(threads[j], NULL) == 0);
+}
+
+ATF_TC(putenv_thread);
+ATF_TC_HEAD(putenv_thread, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test concurrent access by putenv(3)");
+ atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5);
+}
+
+ATF_TC_BODY(putenv_thread, tc)
+{
+ pthread_t threads[THREADED_NUM_THREADS];
+ time_t endtime;
+ size_t i, j;
+
+ endtime = time(NULL) + THREADED_RUN_TIME;
+
+ for (i = j = 0; j < 2; j++) {
+
+ ATF_CHECK(pthread_create(&threads[i++], NULL, thread_putenv,
+ &endtime) == 0);
+ }
+
+ for (j = 0; j < i; j++)
+ ATF_CHECK(pthread_join(threads[j], NULL) == 0);
+}
+
+ATF_TC(setenv_thread);
+ATF_TC_HEAD(setenv_thread, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test concurrent access by setenv(3)");
+ atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5);
+}
+
+ATF_TC_BODY(setenv_thread, tc)
+{
+ pthread_t threads[THREADED_NUM_THREADS];
+ time_t endtime;
+ size_t i, j;
+
+ endtime = time(NULL) + THREADED_RUN_TIME;
+
+ for (i = j = 0; j < 2; j++) {
+
+ ATF_CHECK(pthread_create(&threads[i++], NULL, thread_setenv,
+ &endtime) == 0);
+ }
+
+ for (j = 0; j < i; j++)
+ ATF_CHECK(pthread_join(threads[j], NULL) == 0);
+}
+
+ATF_TC(unsetenv_thread);
+ATF_TC_HEAD(unsetenv_thread, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test unsetenv(3) with threads");
+ atf_tc_set_md_var(tc, "timeout", "%d", THREADED_RUN_TIME + 5);
+}
+
+ATF_TC_BODY(unsetenv_thread, tc)
+{
+ pthread_t threads[THREADED_NUM_THREADS];
+ time_t endtime;
+ size_t i, j;
+
+ endtime = time(NULL) + THREADED_RUN_TIME;
+
+ for (i = j = 0; j < 2; j++) {
+
+ ATF_CHECK(pthread_create(&threads[i++], NULL, thread_unsetenv,
+ &endtime) == 0);
+ }
+
+ for (j = 0; j < i; j++)
+ ATF_CHECK(pthread_join(threads[j], NULL) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getenv_r_thread);
+ ATF_TP_ADD_TC(tp, putenv_thread);
+ ATF_TP_ADD_TC(tp, setenv_thread);
+ ATF_TP_ADD_TC(tp, unsetenv_thread);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh b/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh
new file mode 100755
index 0000000..cc10f65
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh
@@ -0,0 +1,123 @@
+# $NetBSD: t_getopt.sh,v 1.1 2011/01/01 23:56:49 pgoyette Exp $
+#
+# 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.
+#
+
+h_getopt()
+{
+ atf_check -e save:stderr -x "$(atf_get_srcdir)/h_getopt" <<EOF
+load: $1
+args: $2
+result: $3
+EOF
+ cat stderr
+ rm -f stderr
+}
+
+h_getopt_long()
+{
+ atf_check -e save:stderr -x "$(atf_get_srcdir)/h_getopt_long" <<EOF
+$1
+args: $2
+result: $3
+EOF
+ cat stderr
+ rm -f stderr
+}
+
+atf_test_case getopt
+getopt_head()
+{
+ atf_set "descr" "Checks getopt(3)"
+}
+getopt_body()
+{
+ load="c:d"
+
+ h_getopt "${load}" "foo -c 1 -d foo" "c=1,d|1"
+ h_getopt "${load}" "foo -d foo bar" "d|2"
+ h_getopt "${load}" "foo -c 2 foo bar" "c=2|2"
+ h_getopt "${load}" "foo -e 1 foo bar" "!?|3"
+ h_getopt "${load}" "foo -d -- -c 1" "d|2"
+ h_getopt "${load}" "foo -c- 1" "c=-|1"
+ h_getopt "${load}" "foo -d - 1" "d|2"
+}
+
+atf_test_case getopt_long
+getopt_long_head()
+{
+ atf_set "descr" "Checks getopt_long(3)"
+}
+getopt_long_body()
+{
+ # GNU libc tests with these
+ load="optstring: abc:
+longopts: 5
+longopt: required, required_argument, , 'r'
+longopt: optional, optional_argument, , 'o'
+longopt: none, no_argument, , 'n'
+longopt: color, no_argument, , 'C'
+longopt: colour, no_argument, , 'C'"
+
+ h_getopt_long "${load}" "foo --req foobar" "-required=foobar|0"
+ h_getopt_long "${load}" "foo --opt=bazbug" "-optional=bazbug|0"
+
+ # This is problematic
+ #
+ # GNU libc 2.1.3 this fails with ambiguous result
+ # h_getopt_long "${load}" "foo --col" "!?|0"
+ #
+ # GNU libc 2.2 >= this works
+ h_getopt_long "${load}" "foo --col" "-color|0"
+
+ h_getopt_long "${load}" "foo --colour" "-colour|0"
+
+ # This is the real GNU libc test!
+ args="foo -a -b -cfoobar --required foobar --optional=bazbug --none random --col --color --colour"
+ # GNU libc 2.1.3 this fails with ambiguous
+ #result="a,b,c=foobar,-required=foobar,-optional=bazbug,-none,!?,-color,-colour|1"
+ #
+ # GNU libc 2.2 >= this works
+ result="a,b,c=foobar,-required=foobar,-optional=bazbug,-none,-color,-color,-colour|1"
+ h_getopt_long "${load}" "${args}" "${result}"
+
+ #
+ # The order of long options in the long option array should not matter.
+ # An exact match should never be treated as ambiguous.
+ #
+ load="optstring: fgl
+longopts: 3
+longopt: list-foobar, no_argument, lopt, 'f'
+longopt: list-goobar, no_argument, lopt, 'g'
+longopt: list, no_argument, lopt, 'l'"
+ h_getopt_long "${load}" "foo --list" "-list|0"
+}
+
+
+atf_init_test_cases()
+{
+ atf_add_test_case getopt
+ atf_add_test_case getopt_long
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c
new file mode 100644
index 0000000..a0e77d3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c
@@ -0,0 +1,411 @@
+/* $NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $ */
+
+/*-
+ * 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.
+ */
+
+/*
+ * Copyright (c) 2001 Christopher G. Demetriou
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the
+ * NetBSD Project. See http://www.NetBSD.org/ for
+ * information about NetBSD.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $");
+
+#include <errno.h>
+#include <search.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <atf-c.h>
+
+#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno))
+
+#ifdef __NetBSD__
+ATF_TC(hsearch_basic);
+ATF_TC_HEAD(hsearch_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching");
+}
+
+ATF_TC_BODY(hsearch_basic, tc)
+{
+ ENTRY e, *ep;
+ char ch[2];
+ int i;
+
+ REQUIRE_ERRNO(hcreate(16) != 0);
+
+ /* ch[1] should be constant from here on down. */
+ ch[1] = '\0';
+
+ /* Basic insertions. Check enough that there'll be collisions. */
+ for (i = 0; i < 26; i++) {
+ ch[0] = 'a' + i;
+ e.key = strdup(ch); /* ptr to provided key is kept! */
+ ATF_REQUIRE(e.key != NULL);
+ e.data = (void *)(intptr_t)i;
+
+ ep = hsearch(e, ENTER);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, ch);
+ ATF_REQUIRE_EQ((intptr_t)ep->data, i);
+ }
+
+ /* e.key should be constant from here on down. */
+ e.key = ch;
+
+ /* Basic lookups. */
+ for (i = 0; i < 26; i++) {
+ ch[0] = 'a' + i;
+
+ ep = hsearch(e, FIND);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, ch);
+ ATF_REQUIRE_EQ((intptr_t)ep->data, i);
+ }
+
+ hdestroy1(free, NULL);
+}
+#endif
+
+ATF_TC(hsearch_duplicate);
+ATF_TC_HEAD(hsearch_duplicate, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate "
+ "doesn't overwrite existing data");
+}
+
+ATF_TC_BODY(hsearch_duplicate, tc)
+{
+ ENTRY e, *ep;
+
+ REQUIRE_ERRNO(hcreate(16));
+
+ e.key = __UNCONST("a");
+ e.data = (void *)(intptr_t) 0;
+
+ ep = hsearch(e, ENTER);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ e.data = (void *)(intptr_t)12345;
+
+ ep = hsearch(e, ENTER);
+ ep = hsearch(e, FIND);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ hdestroy();
+}
+
+ATF_TC(hsearch_nonexistent);
+ATF_TC_HEAD(hsearch_nonexistent, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks searching for non-existent entry");
+}
+
+ATF_TC_BODY(hsearch_nonexistent, tc)
+{
+ ENTRY e, *ep;
+
+ REQUIRE_ERRNO(hcreate(16));
+
+ e.key = __UNCONST("A");
+ ep = hsearch(e, FIND);
+ ATF_REQUIRE_EQ(ep, NULL);
+
+ hdestroy();
+}
+
+ATF_TC(hsearch_two);
+ATF_TC_HEAD(hsearch_two, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that searching doesn't overwrite previous search results");
+}
+
+ATF_TC_BODY(hsearch_two, tc)
+{
+ ENTRY e, *ep, *ep2;
+
+ REQUIRE_ERRNO(hcreate(16));
+
+ e.key = __UNCONST("a");
+ e.data = (void*)(intptr_t)0;
+
+ ep = hsearch(e, ENTER);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ e.key = __UNCONST("b");
+ e.data = (void*)(intptr_t)1;
+
+ ep = hsearch(e, ENTER);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "b");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 1);
+
+ e.key = __UNCONST("a");
+ ep = hsearch(e, FIND);
+
+ e.key = __UNCONST("b");
+ ep2 = hsearch(e, FIND);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ ATF_REQUIRE(ep2 != NULL);
+ ATF_REQUIRE_STREQ(ep2->key, "b");
+ ATF_REQUIRE_EQ((intptr_t)ep2->data, 1);
+
+ hdestroy();
+}
+
+#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version
+#ifdef __NetBSD__
+ATF_TC(hsearch_r_basic);
+ATF_TC_HEAD(hsearch_r_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching");
+}
+
+ATF_TC_BODY(hsearch_r_basic, tc)
+{
+ ENTRY e, *ep;
+ char ch[2];
+ int i;
+ struct hsearch_data t;
+
+ REQUIRE_ERRNO(hcreate_r(16, &t) != 0);
+
+ /* ch[1] should be constant from here on down. */
+ ch[1] = '\0';
+
+ /* Basic insertions. Check enough that there'll be collisions. */
+ for (i = 0; i < 26; i++) {
+ ch[0] = 'a' + i;
+ e.key = strdup(ch); /* ptr to provided key is kept! */
+ ATF_REQUIRE(e.key != NULL);
+ e.data = (void *)(intptr_t)i;
+
+ ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, ch);
+ ATF_REQUIRE_EQ((intptr_t)ep->data, i);
+ }
+
+ /* e.key should be constant from here on down. */
+ e.key = ch;
+
+ /* Basic lookups. */
+ for (i = 0; i < 26; i++) {
+ ch[0] = 'a' + i;
+
+ ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, ch);
+ ATF_REQUIRE_EQ((intptr_t)ep->data, i);
+ }
+
+ hdestroy1_r(&t, free, NULL);
+}
+#endif
+
+ATF_TC(hsearch_r_duplicate);
+ATF_TC_HEAD(hsearch_r_duplicate, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate "
+ "doesn't overwrite existing data");
+}
+
+ATF_TC_BODY(hsearch_r_duplicate, tc)
+{
+ ENTRY e, *ep;
+ struct hsearch_data t;
+
+ REQUIRE_ERRNO(hcreate_r(16, &t));
+
+ e.key = __UNCONST("a");
+ e.data = (void *)(intptr_t) 0;
+
+ ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ e.data = (void *)(intptr_t)12345;
+
+ ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
+ ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ hdestroy_r(&t);
+}
+
+ATF_TC(hsearch_r_nonexistent);
+ATF_TC_HEAD(hsearch_r_nonexistent, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks searching for non-existent entry");
+}
+
+ATF_TC_BODY(hsearch_r_nonexistent, tc)
+{
+ ENTRY e, *ep;
+ struct hsearch_data t;
+
+ REQUIRE_ERRNO(hcreate_r(16, &t));
+
+ e.key = __UNCONST("A");
+ ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
+ ATF_REQUIRE_EQ(ep, NULL);
+
+ hdestroy_r(&t);
+}
+
+ATF_TC(hsearch_r_two);
+ATF_TC_HEAD(hsearch_r_two, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that searching doesn't overwrite previous search results");
+}
+
+ATF_TC_BODY(hsearch_r_two, tc)
+{
+ ENTRY e, *ep, *ep2;
+ struct hsearch_data t;
+
+ REQUIRE_ERRNO(hcreate_r(16, &t));
+
+ e.key = __UNCONST("a");
+ e.data = (void*)(intptr_t)0;
+
+ ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ e.key = __UNCONST("b");
+ e.data = (void*)(intptr_t)1;
+
+ ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "b");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 1);
+
+ e.key = __UNCONST("a");
+ ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
+
+ e.key = __UNCONST("b");
+ ATF_REQUIRE(hsearch_r(e, FIND, &ep2, &t) == 1);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ ATF_REQUIRE(ep2 != NULL);
+ ATF_REQUIRE_STREQ(ep2->key, "b");
+ ATF_REQUIRE_EQ((intptr_t)ep2->data, 1);
+
+ hdestroy_r(&t);
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, hsearch_basic);
+#endif
+ ATF_TP_ADD_TC(tp, hsearch_duplicate);
+ ATF_TP_ADD_TC(tp, hsearch_nonexistent);
+ ATF_TP_ADD_TC(tp, hsearch_two);
+
+#if defined(__FreeBSD__) && 1100027 <= __FreeBSD_version
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, hsearch_r_basic);
+#endif
+ ATF_TP_ADD_TC(tp, hsearch_r_duplicate);
+ ATF_TP_ADD_TC(tp, hsearch_r_nonexistent);
+ ATF_TP_ADD_TC(tp, hsearch_r_two);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c b/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c
new file mode 100644
index 0000000..77d6443
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c
@@ -0,0 +1,95 @@
+/* $NetBSD: t_mi_vector_hash.c,v 1.3 2011/07/07 11:12:18 jruoho Exp $ */
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_mi_vector_hash.c,v 1.3 2011/07/07 11:12:18 jruoho Exp $");
+
+#include <atf-c.h>
+#include <stdlib.h>
+#include <string.h>
+
+ATF_TC(mi_vector_hash_basic);
+ATF_TC_HEAD(mi_vector_hash_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test mi_vector_hash_vector_hash for consistent results");
+}
+
+static const struct testvector {
+ const char *vector;
+ uint32_t hashes[3];
+} testv[] = {
+ { "hello, world", { 0xd38f7f21, 0xbf6be9ab, 0x37a0e989 } },
+ { "", { 0x9b2ec03d, 0xdb2b69ae, 0xbd49d10d } },
+ { "a", { 0x9454baa3, 0xb711c708, 0x29eec818 } },
+ { "ab", { 0x9a5dca90, 0xdd212644, 0x9879ac41 } },
+ { "abc", { 0x0b91c470, 0x4770cdf5, 0x251e4793 } },
+ { "abcd", { 0x5f128df3, 0xf5a667a6, 0x5ae61fa5 } },
+ { "abcde", { 0x4cbae281, 0x799c0ed5, 0x03a96866 } },
+ { "abcdef", { 0x507a54c8, 0xb6bd06f4, 0xde922732 } },
+ { "abcdefg", { 0xae2bca5d, 0x61e960ef, 0xb9e6762c } },
+ { "abcdefgh", { 0xd1021264, 0x87f6988f, 0x053f775e } },
+ { "abcdefghi", { 0xe380defc, 0xfc35a811, 0x3a7b0a5f } },
+ { "abcdefghij", { 0x9a504408, 0x70d2e89d, 0xc9cac242 } },
+ { "abcdefghijk", { 0x376117d0, 0x89f434d4, 0xe52b8e4c } },
+ { "abcdefghijkl", { 0x92253599, 0x7b6ff99e, 0x0b1b3ea5 } },
+ { "abcdefghijklm", { 0x92ee6a52, 0x55587d47, 0x3122b031 } },
+ { "abcdefghijklmn", { 0x827baf08, 0x1d0ada73, 0xfec330e0 } },
+ { "abcdefghijklmno", { 0x06ab787d, 0xc1ad17c2, 0x11dccf31 } },
+ { "abcdefghijklmnop", { 0x2cf18103, 0x638c9268, 0xfa1ecf51 } },
+};
+
+ATF_TC_BODY(mi_vector_hash_basic, tc)
+{
+ size_t i, j, len;
+ uint32_t hashes[3];
+ char buf[256];
+
+ for (j = 0; j < 8; ++j) {
+ for (i = 0; i < sizeof(testv) / sizeof(testv[0]); ++i) {
+ len = strlen(testv[i].vector);
+ strcpy(buf + j, testv[i].vector);
+ mi_vector_hash(buf + j, len, 0, hashes);
+ ATF_CHECK_EQ(hashes[0], testv[i].hashes[0]);
+ ATF_CHECK_EQ(hashes[1], testv[i].hashes[1]);
+ ATF_CHECK_EQ(hashes[2], testv[i].hashes[2]);
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, mi_vector_hash_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c b/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c
new file mode 100644
index 0000000..47afb84
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c
@@ -0,0 +1,88 @@
+/* $NetBSD: t_posix_memalign.c,v 1.2 2011/07/07 11:12:18 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_posix_memalign.c,v 1.2 2011/07/07 11:12:18 jruoho Exp $");
+
+#include <atf-c.h>
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+ATF_TC(posix_memalign_basic);
+ATF_TC_HEAD(posix_memalign_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks posix_memalign(3)");
+}
+ATF_TC_BODY(posix_memalign_basic, tc)
+{
+ size_t size[] = {
+ 1, 2, 3, 4, 10, 100, 16384, 32768, 65536
+ };
+ size_t align[] = {
+ 512, 1024, 16, 32, 64, 4, 2048, 16, 2
+ };
+
+ size_t i;
+ void *p;
+
+ for (i = 0; i < __arraycount(size); i++) {
+ int ret;
+ p = (void*)0x1;
+
+ (void)printf("Checking posix_memalign(&p, %zd, %zd)...\n",
+ align[i], size[i]);
+ ret = posix_memalign(&p, align[i], size[i]);
+
+ if ( align[i] < sizeof(void *))
+ ATF_REQUIRE_EQ_MSG(ret, EINVAL,
+ "posix_memalign: %s", strerror(ret));
+ else {
+ ATF_REQUIRE_EQ_MSG(ret, 0,
+ "posix_memalign: %s", strerror(ret));
+ ATF_REQUIRE_EQ_MSG(((intptr_t)p) & (align[i] - 1), 0,
+ "p = %p", p);
+ free(p);
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, posix_memalign_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_random.c b/contrib/netbsd-tests/lib/libc/stdlib/t_random.c
new file mode 100644
index 0000000..9a6d21e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_random.c
@@ -0,0 +1,82 @@
+/* $NetBSD: t_random.c,v 1.3 2012/03/29 08:56:06 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_random.c,v 1.3 2012/03/29 08:56:06 jruoho Exp $");
+
+#include <atf-c.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * TODO: Add some general RNG tests (cf. the famous "diehard" tests?).
+ */
+
+ATF_TC(random_same);
+ATF_TC_HEAD(random_same, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that random(3) does not always return the same "
+ "value when the seed is initialized to zero");
+}
+
+#define MAX_ITER 10
+
+ATF_TC_BODY(random_same, tc)
+{
+ long buf[MAX_ITER];
+ size_t i, j;
+
+ /*
+ * See CVE-2012-1577.
+ */
+ srandom(0);
+
+ for (i = 0; i < __arraycount(buf); i++) {
+
+ buf[i] = random();
+
+ for (j = 0; j < i; j++) {
+
+ (void)fprintf(stderr, "i = %zu, j = %zu: "
+ "%ld vs. %ld\n", i, j, buf[i], buf[j]);
+
+ ATF_CHECK(buf[i] != buf[j]);
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, random_same);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c b/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c
new file mode 100644
index 0000000..8f0f899
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c
@@ -0,0 +1,342 @@
+/* $NetBSD: t_strtod.c,v 1.32 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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.
+ */
+
+/* Public domain, Otto Moerbeek <otto@drijf.net>, 2006. */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_strtod.c,v 1.32 2014/11/04 00:20:19 justin Exp $");
+
+#include <errno.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#if defined(__i386__) || defined(__amd64__) || defined(__sparc__)
+#include <fenv.h>
+#endif
+
+#if !defined(__vax__)
+static const char * const inf_strings[] =
+ { "Inf", "INF", "-Inf", "-INF", "Infinity", "+Infinity",
+ "INFINITY", "-INFINITY", "InFiNiTy", "+InFiNiTy" };
+const char *nan_string = "NaN(x)y";
+#endif
+
+#ifdef __FreeBSD__
+#define __HAVE_LONG_DOUBLE
+#endif
+
+ATF_TC(strtod_basic);
+ATF_TC_HEAD(strtod_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of strtod(3)");
+}
+
+ATF_TC_BODY(strtod_basic, tc)
+{
+ static const size_t n = 1024 * 1000;
+
+ for (size_t i = 1; i < n; i = i + 1024) {
+ char buf[512];
+ (void)snprintf(buf, sizeof(buf), "%zu.%zu", i, i + 1);
+
+ errno = 0;
+ double d = strtod(buf, NULL);
+
+ ATF_REQUIRE(d > 0.0);
+ ATF_REQUIRE(errno == 0);
+ }
+}
+
+ATF_TC(strtod_hex);
+ATF_TC_HEAD(strtod_hex, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtod(3) with hexadecimals");
+}
+
+#ifdef __vax__
+#define SMALL_NUM 1.0e-38
+#else
+#define SMALL_NUM 1.0e-40
+#endif
+
+ATF_TC_BODY(strtod_hex, tc)
+{
+ const char *str;
+ char *end;
+ volatile double d;
+
+ str = "-0x0";
+ d = strtod(str, &end); /* -0.0 */
+
+ ATF_REQUIRE(end == str + 4);
+ ATF_REQUIRE(signbit(d) != 0);
+ ATF_REQUIRE(fabs(d) < SMALL_NUM);
+
+ str = "-0x";
+ d = strtod(str, &end); /* -0.0 */
+
+ ATF_REQUIRE(end == str + 2);
+ ATF_REQUIRE(signbit(d) != 0);
+ ATF_REQUIRE(fabs(d) < SMALL_NUM);
+}
+
+ATF_TC(strtod_inf);
+ATF_TC_HEAD(strtod_inf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtod(3) with INF (PR lib/33262)");
+}
+
+ATF_TC_BODY(strtod_inf, tc)
+{
+#ifndef __vax__
+ for (size_t i = 0; i < __arraycount(inf_strings); i++) {
+ volatile double d = strtod(inf_strings[i], NULL);
+ ATF_REQUIRE(isinf(d) != 0);
+ }
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtof_inf);
+ATF_TC_HEAD(strtof_inf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtof(3) with INF (PR lib/33262)");
+}
+
+ATF_TC_BODY(strtof_inf, tc)
+{
+#ifndef __vax__
+ for (size_t i = 0; i < __arraycount(inf_strings); i++) {
+ volatile float f = strtof(inf_strings[i], NULL);
+ ATF_REQUIRE(isinf(f) != 0);
+ }
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtold_inf);
+ATF_TC_HEAD(strtold_inf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtold(3) with INF (PR lib/33262)");
+}
+
+ATF_TC_BODY(strtold_inf, tc)
+{
+#ifndef __vax__
+# ifdef __HAVE_LONG_DOUBLE
+
+ for (size_t i = 0; i < __arraycount(inf_strings); i++) {
+ volatile long double ld = strtold(inf_strings[i], NULL);
+ ATF_REQUIRE(isinf(ld) != 0);
+ }
+# else
+ atf_tc_skip("Requires long double support");
+# endif
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtod_nan);
+ATF_TC_HEAD(strtod_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtod(3) with NaN");
+}
+
+ATF_TC_BODY(strtod_nan, tc)
+{
+#ifndef __vax__
+ char *end;
+
+ volatile double d = strtod(nan_string, &end);
+ ATF_REQUIRE(isnan(d) != 0);
+ ATF_REQUIRE(strcmp(end, "y") == 0);
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtof_nan);
+ATF_TC_HEAD(strtof_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtof(3) with NaN");
+}
+
+ATF_TC_BODY(strtof_nan, tc)
+{
+#ifndef __vax__
+ char *end;
+
+ volatile float f = strtof(nan_string, &end);
+ ATF_REQUIRE(isnanf(f) != 0);
+ ATF_REQUIRE(strcmp(end, "y") == 0);
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtold_nan);
+ATF_TC_HEAD(strtold_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtold(3) with NaN (PR lib/45020)");
+}
+
+ATF_TC_BODY(strtold_nan, tc)
+{
+#ifndef __vax__
+# ifdef __HAVE_LONG_DOUBLE
+
+ char *end;
+
+ volatile long double ld = strtold(nan_string, &end);
+ ATF_REQUIRE(isnan(ld) != 0);
+#ifdef __FreeBSD__
+ ATF_REQUIRE(strcmp(end, "y") == 0);
+#else
+ ATF_REQUIRE(__isnanl(ld) != 0);
+#endif
+ ATF_REQUIRE(strcmp(end, "y") == 0);
+# else
+ atf_tc_skip("Requires long double support");
+# endif
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtod_round);
+ATF_TC_HEAD(strtod_round, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test rouding in strtod(3)");
+}
+
+ATF_TC_BODY(strtod_round, tc)
+{
+#if defined(__i386__) || defined(__amd64__) || defined(__sparc__)
+
+ /*
+ * Test that strtod(3) honors the current rounding mode.
+ * The used value is somewhere near 1 + DBL_EPSILON + FLT_EPSILON.
+ */
+ const char *val =
+ "1.00000011920928977282585492503130808472633361816406";
+
+ (void)fesetround(FE_UPWARD);
+
+ volatile double d1 = strtod(val, NULL);
+
+ (void)fesetround(FE_DOWNWARD);
+
+ volatile double d2 = strtod(val, NULL);
+
+ if (fabs(d1 - d2) > 0.0)
+ return;
+ else {
+ atf_tc_expect_fail("PR misc/44767");
+ atf_tc_fail("strtod(3) did not honor fesetround(3)");
+ }
+#else
+ atf_tc_skip("Requires one of i386, amd64 or sparc");
+#endif
+}
+
+ATF_TC(strtod_underflow);
+ATF_TC_HEAD(strtod_underflow, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test underflow in strtod(3)");
+}
+
+ATF_TC_BODY(strtod_underflow, tc)
+{
+
+ const char *tmp =
+ "0.0000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000002";
+
+ errno = 0;
+ volatile double d = strtod(tmp, NULL);
+
+ if (d != 0 || errno != ERANGE)
+ atf_tc_fail("strtod(3) did not detect underflow");
+}
+
+/*
+ * Bug found by Geza Herman.
+ * See
+ * http://www.exploringbinary.com/a-bug-in-the-bigcomp-function-of-david-gays-strtod/
+ */
+ATF_TC(strtod_gherman_bug);
+ATF_TC_HEAD(strtod_gherman_bug, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test a bug found by Geza Herman");
+}
+
+ATF_TC_BODY(strtod_gherman_bug, tc)
+{
+
+ const char *str =
+ "1.8254370818746402660437411213933955878019332885742187";
+
+ errno = 0;
+ volatile double d = strtod(str, NULL);
+
+ ATF_CHECK(d == 0x1.d34fd8378ea83p+0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strtod_basic);
+ ATF_TP_ADD_TC(tp, strtod_hex);
+ ATF_TP_ADD_TC(tp, strtod_inf);
+ ATF_TP_ADD_TC(tp, strtof_inf);
+ ATF_TP_ADD_TC(tp, strtold_inf);
+ ATF_TP_ADD_TC(tp, strtod_nan);
+ ATF_TP_ADD_TC(tp, strtof_nan);
+ ATF_TP_ADD_TC(tp, strtold_nan);
+ ATF_TP_ADD_TC(tp, strtod_round);
+ ATF_TP_ADD_TC(tp, strtod_underflow);
+ ATF_TP_ADD_TC(tp, strtod_gherman_bug);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c b/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c
new file mode 100644
index 0000000..5a0c6d0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c
@@ -0,0 +1,234 @@
+/* $NetBSD: t_strtol.c,v 1.5 2011/06/14 02:45:58 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_strtol.c,v 1.5 2011/06/14 02:45:58 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+struct test {
+ const char *str;
+ int64_t res;
+ int base;
+ const char *end;
+};
+
+static void check(struct test *, long int, long long int, char *);
+
+static void
+check(struct test *t, long int li, long long int lli, char *end)
+{
+
+ if (li != -1 && li != t->res)
+ atf_tc_fail_nonfatal("strtol(%s, &end, %d) failed "
+ "(rv = %ld)", t->str, t->base, li);
+
+ if (lli != -1 && lli != t->res)
+ atf_tc_fail_nonfatal("strtoll(%s, NULL, %d) failed "
+ "(rv = %lld)", t->str, t->base, lli);
+
+ if (t->end != NULL && strcmp(t->end, end) != 0)
+ atf_tc_fail_nonfatal("invalid end pointer ('%s') from "
+ "strtol(%s, &end, %d)", end, t->str, t->base);
+}
+
+ATF_TC(strtol_base);
+ATF_TC_HEAD(strtol_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strtol(3) with different bases");
+}
+
+ATF_TC_BODY(strtol_base, tc)
+{
+ struct test t[] = {
+ { "123456789", 123456789, 0, NULL },
+ { "111010110111100110100010101", 123456789, 2, NULL },
+ { "22121022020212200", 123456789, 3, NULL },
+ { "13112330310111", 123456789, 4, NULL },
+ { "223101104124", 123456789, 5, NULL },
+ { "20130035113", 123456789, 6, NULL },
+ { "3026236221", 123456789, 7, NULL },
+ { "726746425", 123456789, 8, NULL },
+ { "277266780", 123456789, 9, NULL },
+ { "123456789", 123456789, 10, NULL },
+ { "63762A05", 123456789, 11, NULL },
+ { "35418A99", 123456789, 12, NULL },
+ { "1C767471", 123456789, 13, NULL },
+ { "12579781", 123456789, 14, NULL },
+ { "AC89BC9", 123456789, 15, NULL },
+ { "75BCD15", 123456789, 16, NULL },
+ { "123456789", 342391, 8, NULL },
+ { "0123456789", 342391, 0, NULL },
+ { "0123456789", 123456789, 10, NULL },
+ { "0x75bcd15", 123456789, 0, NULL },
+ };
+
+ long long int lli;
+ long int li;
+ char *end;
+ size_t i;
+
+ for (i = 0; i < __arraycount(t); i++) {
+
+ li = strtol(t[i].str, &end, t[i].base);
+ lli = strtoll(t[i].str, NULL, t[i].base);
+
+ check(&t[i], li, lli, end);
+ }
+}
+
+ATF_TC(strtol_case);
+ATF_TC_HEAD(strtol_case, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Case insensitivity with strtol(3)");
+}
+
+ATF_TC_BODY(strtol_case, tc)
+{
+ struct test t[] = {
+ { "abcd", 0xabcd, 16, NULL },
+ { " dcba", 0xdcba, 16, NULL },
+ { "abcd dcba", 0xabcd, 16, " dcba" },
+ { "abc0x123", 0xabc0, 16, NULL },
+ { "abcd\0x123", 0xabcd, 16, "\0x123" },
+ { "ABCD", 0xabcd, 16, NULL },
+ { "aBcD", 0xabcd, 16, NULL },
+ { "0xABCD", 0xabcd, 16, NULL },
+ { "0xABCDX", 0xabcd, 16, "X" },
+ };
+
+ long long int lli;
+ long int li;
+ char *end;
+ size_t i;
+
+ for (i = 0; i < __arraycount(t); i++) {
+
+ li = strtol(t[i].str, &end, t[i].base);
+ lli = strtoll(t[i].str, NULL, t[i].base);
+
+ check(&t[i], li, lli, end);
+ }
+}
+
+ATF_TC(strtol_range);
+ATF_TC_HEAD(strtol_range, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ERANGE from strtol(3)");
+}
+
+ATF_TC_BODY(strtol_range, tc)
+{
+
+#if LONG_MAX == 0x7fffffff /* XXX: Is this portable? */
+
+ struct test t[] = {
+ { "20000000000", 2147483647, 8, NULL },
+ { "2147483648", 2147483647, 10, NULL },
+ { "80000000", 2147483647, 16, NULL },
+ };
+#else
+ struct test t[] = {
+ { "1000000000000000000000", 9223372036854775807, 8, NULL },
+ { "9223372036854775808", 9223372036854775807, 10, NULL },
+ { "8000000000000000", 9223372036854775807, 16, NULL },
+ };
+#endif
+
+ long int li;
+ char *end;
+ size_t i;
+
+ for (i = 0; i < __arraycount(t); i++) {
+
+ errno = 0;
+ li = strtol(t[i].str, &end, t[i].base);
+
+ if (errno != ERANGE)
+ atf_tc_fail("strtol(3) did not catch ERANGE");
+
+ check(&t[i], li, -1, end);
+ }
+}
+
+ATF_TC(strtol_signed);
+ATF_TC_HEAD(strtol_signed, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of strtol(3)");
+}
+
+ATF_TC_BODY(strtol_signed, tc)
+{
+ struct test t[] = {
+ { "1", 1, 0, NULL },
+ { " 2", 2, 0, NULL },
+ { " 3", 3, 0, NULL },
+ { " -3", -3, 0, NULL },
+ { "--1", 0, 0, "--1" },
+ { "+-2", 0, 0, "+-2" },
+ { "++3", 0, 0, "++3" },
+ { "+9", 9, 0, NULL },
+ { "+123", 123, 0, NULL },
+ { "-1 3", -1, 0, " 3" },
+ { "-1.3", -1, 0, ".3" },
+ { "- 3", 0, 0, "- 3" },
+ { "+33.", 33, 0, "." },
+ { "30x0", 30, 0, "x0" },
+ };
+
+ long long int lli;
+ long int li;
+ char *end;
+ size_t i;
+
+ for (i = 0; i < __arraycount(t); i++) {
+
+ li = strtol(t[i].str, &end, t[i].base);
+ lli = strtoll(t[i].str, NULL, t[i].base);
+
+ check(&t[i], li, lli, end);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strtol_base);
+ ATF_TP_ADD_TC(tp, strtol_case);
+ ATF_TP_ADD_TC(tp, strtol_range);
+ ATF_TP_ADD_TC(tp, strtol_signed);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_system.c b/contrib/netbsd-tests/lib/libc/stdlib/t_system.c
new file mode 100644
index 0000000..235005b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_system.c
@@ -0,0 +1,83 @@
+/* $NetBSD: t_system.c,v 1.1 2011/09/11 10:32:23 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_system.c,v 1.1 2011/09/11 10:32:23 jruoho Exp $");
+
+#include <atf-c.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char *path = "system";
+
+ATF_TC_WITH_CLEANUP(system_basic);
+ATF_TC_HEAD(system_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of system(3)");
+}
+
+ATF_TC_BODY(system_basic, tc)
+{
+ char buf[23];
+ int fd, i = 2;
+
+ ATF_REQUIRE(system("/bin/echo -n > system") == 0);
+
+ while (i >= 0) {
+ ATF_REQUIRE(system("/bin/echo -n garbage >> system") == 0);
+ i--;
+ }
+
+ fd = open(path, O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ (void)memset(buf, '\0', sizeof(buf));
+
+ ATF_REQUIRE(read(fd, buf, 21) == 21);
+ ATF_REQUIRE(strcmp(buf, "garbagegarbagegarbage") == 0);
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(system_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, system_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_bm.c b/contrib/netbsd-tests/lib/libc/string/t_bm.c
new file mode 100644
index 0000000..5ec4022
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_bm.c
@@ -0,0 +1,102 @@
+/* $Id: t_bm.c,v 1.1 2014/06/23 10:53:20 shm Exp $ */
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mateusz Kocielski.
+ *
+ * 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/cdefs.h>
+__RCSID("$Id: t_bm.c,v 1.1 2014/06/23 10:53:20 shm Exp $");
+
+#include <atf-c.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <bm.h>
+#include <string.h>
+#include <stdlib.h>
+
+ATF_TC(bm);
+ATF_TC_HEAD(bm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test bm(3)");
+}
+
+typedef struct {
+ const char *pattern;
+ const char *text;
+ const char *freq;
+ ssize_t match;
+} t_testcase;
+
+const t_testcase testcases[] = {
+ {"test", "test", NULL, 0},
+ {"test", "ttest", NULL, 1},
+ {"test", "tes", NULL, -1},
+ {"test", "testtesttest", NULL, 0},
+ {"test", "testtesttesttesttesttest", NULL, 0},
+ {"test", "------------------------", NULL, -1},
+ {"a", "a", NULL, 0},
+ {"a", "ba", NULL, 1},
+ {"a", "bba", NULL, 2},
+ {"bla", "bl", NULL, -1},
+ {"a", "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", NULL, -1},
+ {"test", "qfwiofjqeiwofjioqewfjeiqwjfiqewjfioqewfjioewqjfioewqjfioewqjoi",
+ NULL, -1},
+ {"needle", "haystack", NULL, -1},
+ {"netbsd", "freebsd netbsd openbsd", NULL, 8},
+};
+
+ATF_TC_BODY(bm, tc)
+{
+ size_t ts;
+ u_char *off;
+ char *text;
+ bm_pat *pattern;
+
+ for (ts = 0; ts < sizeof(testcases)/sizeof(t_testcase); ts++) {
+ ATF_CHECK(pattern = bm_comp((const u_char *)testcases[ts].pattern,
+ strlen(testcases[ts].pattern), (const u_char *)testcases[ts].freq));
+
+ ATF_REQUIRE(text = strdup(testcases[ts].text));
+ off = bm_exec(pattern, (u_char *)text, strlen(text));
+
+ if (testcases[ts].match == -1)
+ ATF_CHECK_EQ(off, NULL);
+ else
+ ATF_CHECK_EQ(testcases[ts].match,
+ (off-(u_char *)text));
+
+ bm_free(pattern);
+ free(text);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, bm);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_memchr.c b/contrib/netbsd-tests/lib/libc/string/t_memchr.c
new file mode 100644
index 0000000..296f1f8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_memchr.c
@@ -0,0 +1,194 @@
+/* $NetBSD: t_memchr.c,v 1.3 2012/04/06 07:53:10 jruoho Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@acorntoolworks.com>
+ * Public domain.
+ */
+
+#include <atf-c.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+ATF_TC(memchr_basic);
+ATF_TC_HEAD(memchr_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #1");
+}
+
+ATF_TC_BODY(memchr_basic, tc)
+{
+ /* try to trick the compiler */
+ void * (*f)(const void *, int, size_t) = memchr;
+
+ unsigned int a, t;
+ void *off, *off2;
+ char buf[32];
+
+ struct tab {
+ const char *val;
+ size_t len;
+ char match;
+ ssize_t off;
+ };
+
+ const struct tab tab[] = {
+ { "", 0, 0, 0 },
+
+ { "/", 0, 0, 0 },
+ { "/", 1, 1, 0 },
+ { "/a", 2, 1, 0 },
+ { "/ab", 3, 1, 0 },
+ { "/abc", 4, 1, 0 },
+ { "/abcd", 5, 1, 0 },
+ { "/abcde", 6, 1, 0 },
+ { "/abcdef", 7, 1, 0 },
+ { "/abcdefg", 8, 1, 0 },
+
+ { "a/", 1, 0, 0 },
+ { "a/", 2, 1, 1 },
+ { "a/b", 3, 1, 1 },
+ { "a/bc", 4, 1, 1 },
+ { "a/bcd", 5, 1, 1 },
+ { "a/bcde", 6, 1, 1 },
+ { "a/bcdef", 7, 1, 1 },
+ { "a/bcdefg", 8, 1, 1 },
+
+ { "ab/", 2, 0, 0 },
+ { "ab/", 3, 1, 2 },
+ { "ab/c", 4, 1, 2 },
+ { "ab/cd", 5, 1, 2 },
+ { "ab/cde", 6, 1, 2 },
+ { "ab/cdef", 7, 1, 2 },
+ { "ab/cdefg", 8, 1, 2 },
+
+ { "abc/", 3, 0, 0 },
+ { "abc/", 4, 1, 3 },
+ { "abc/d", 5, 1, 3 },
+ { "abc/de", 6, 1, 3 },
+ { "abc/def", 7, 1, 3 },
+ { "abc/defg", 8, 1, 3 },
+
+ { "abcd/", 4, 0, 0 },
+ { "abcd/", 5, 1, 4 },
+ { "abcd/e", 6, 1, 4 },
+ { "abcd/ef", 7, 1, 4 },
+ { "abcd/efg", 8, 1, 4 },
+
+ { "abcde/", 5, 0, 0 },
+ { "abcde/", 6, 1, 5 },
+ { "abcde/f", 7, 1, 5 },
+ { "abcde/fg", 8, 1, 5 },
+
+ { "abcdef/", 6, 0, 0 },
+ { "abcdef/", 7, 1, 6 },
+ { "abcdef/g", 8, 1, 6 },
+
+ { "abcdefg/", 7, 0, 0 },
+ { "abcdefg/", 8, 1, 7 },
+
+ { "\xff\xff\xff\xff" "efg/", 8, 1, 7 },
+ { "a" "\xff\xff\xff\xff" "fg/", 8, 1, 7 },
+ { "ab" "\xff\xff\xff\xff" "g/", 8, 1, 7 },
+ { "abc" "\xff\xff\xff\xff" "/", 8, 1, 7 },
+ };
+
+ for (a = 1; a < 1 + sizeof(long); ++a) {
+ for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
+ buf[a-1] = '/';
+ strcpy(&buf[a], tab[t].val);
+
+ off = f(&buf[a], '/', tab[t].len);
+ if (tab[t].match == 0) {
+ if (off != 0) {
+ fprintf(stderr, "a = %d, t = %d\n",
+ a, t);
+ atf_tc_fail("should not have found "
+ " char past len");
+ }
+ } else if (tab[t].match == 1) {
+ if (tab[t].off != ((char*)off - &buf[a])) {
+ fprintf(stderr, "a = %d, t = %d\n",
+ a, t);
+ atf_tc_fail("char not found at "
+ "correct offset");
+ }
+ } else {
+ fprintf(stderr, "a = %d, t = %d\n", a, t);
+ atf_tc_fail("Corrupt test case data");
+ }
+
+ /* check zero extension of char arg */
+ off2 = f(&buf[a], 0xffffff00 | '/', tab[t].len);
+ if (off2 != off)
+ atf_tc_fail("zero extension of char arg "
+ "failed");
+ }
+ }
+}
+
+ATF_TC(memchr_simple);
+ATF_TC_HEAD(memchr_simple, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memchr(3) results, #2");
+}
+
+ATF_TC_BODY(memchr_simple, tc)
+{
+ char buf[] = "abcdefg";
+ short i = 7;
+
+ ATF_CHECK(memchr(buf, 'a', 0) == NULL);
+ ATF_CHECK(memchr(buf, 'g', 0) == NULL);
+ ATF_CHECK(memchr(buf, 'x', 7) == NULL);
+
+ ATF_CHECK(memchr("\0", 'x', 0) == NULL);
+ ATF_CHECK(memchr("\0", 'x', 1) == NULL);
+
+ while (i <= 14) {
+
+ ATF_CHECK(memchr(buf, 'a', i) == buf + 0);
+ ATF_CHECK(memchr(buf, 'b', i) == buf + 1);
+ ATF_CHECK(memchr(buf, 'c', i) == buf + 2);
+ ATF_CHECK(memchr(buf, 'd', i) == buf + 3);
+ ATF_CHECK(memchr(buf, 'e', i) == buf + 4);
+ ATF_CHECK(memchr(buf, 'f', i) == buf + 5);
+ ATF_CHECK(memchr(buf, 'g', i) == buf + 6);
+
+ i *= 2;
+ }
+}
+
+ATF_TC(memrchr_simple);
+ATF_TC_HEAD(memrchr_simple, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memrchr(3) results");
+}
+
+ATF_TC_BODY(memrchr_simple, tc)
+{
+ char buf[] = "abcdabcd";
+
+ ATF_CHECK(memrchr(buf, 'a', 0) == NULL);
+ ATF_CHECK(memrchr(buf, 'g', 0) == NULL);
+ ATF_CHECK(memrchr(buf, 'x', 8) == NULL);
+
+ ATF_CHECK(memrchr("\0", 'x', 0) == NULL);
+ ATF_CHECK(memrchr("\0", 'x', 1) == NULL);
+
+ ATF_CHECK(memrchr(buf, 'a', 8) == buf + 4);
+ ATF_CHECK(memrchr(buf, 'b', 8) == buf + 5);
+ ATF_CHECK(memrchr(buf, 'c', 8) == buf + 6);
+ ATF_CHECK(memrchr(buf, 'd', 8) == buf + 7);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, memchr_basic);
+ ATF_TP_ADD_TC(tp, memchr_simple);
+ ATF_TP_ADD_TC(tp, memrchr_simple);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_memcpy.c b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c
new file mode 100644
index 0000000..192a4e8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c
@@ -0,0 +1,162 @@
+/* $NetBSD: t_memcpy.c,v 1.5 2013/03/17 02:23:31 christos Exp $ */
+
+/*-
+ * 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.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <md5.h>
+
+#include <sys/types.h>
+
+#define ALIGNMENTS 16
+#define LENGTHS 4
+#define BLOCKTYPES 4
+
+MD5_CTX mc[1];
+
+typedef unsigned char testBlock_t[ALIGNMENTS * LENGTHS];
+
+testBlock_t bss1, bss2;
+
+unsigned char *start[BLOCKTYPES] = {
+ bss1, bss2
+};
+
+char result[100];
+#ifdef __NetBSD__
+const char goodResult[] = "7b405d24bc03195474c70ddae9e1f8fb";
+#else
+const char goodResult[] = "217b4fbe456916bf62a2f85df752e4ab";
+#endif
+
+static void
+runTest(unsigned char *b1, unsigned char *b2)
+{
+ int i, j, k, m;
+ size_t n;
+
+ for (i = 0; i < ALIGNMENTS; ++i) {
+ for (j = 0; j < ALIGNMENTS; ++j) {
+ k = sizeof(testBlock_t) - (i > j ? i : j);
+ for (m = 0; m < k; ++m) {
+ for (n = 0; n < sizeof(testBlock_t); ++n) {
+ b1[n] = (unsigned char)random();
+ b2[n] = (unsigned char)random();
+ }
+ memcpy(b1 + i, b2 + j, m);
+ MD5Update(mc, b1, sizeof(testBlock_t));
+ MD5Update(mc, b2, sizeof(testBlock_t));
+ }
+ }
+ }
+}
+
+ATF_TC(memcpy_basic);
+ATF_TC_HEAD(memcpy_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memcpy results");
+}
+
+ATF_TC_BODY(memcpy_basic, tc)
+{
+ int i, j;
+ testBlock_t auto1, auto2;
+
+ start[2] = auto1;
+ start[3] = auto2;
+
+#ifdef __NetBSD__
+ srandom(0L);
+#else
+ /*
+ * random() shall produce by default a sequence of numbers that can be
+ * duplicated by calling srandom() with 1 as the seed.
+ */
+ srandom(1);
+#endif
+ MD5Init(mc);
+ for (i = 0; i < BLOCKTYPES; ++i)
+ for (j = 0; j < BLOCKTYPES; ++j)
+ if (i != j)
+ runTest(start[i], start[j]);
+ MD5End(mc, result);
+ ATF_REQUIRE_EQ(strcmp(result, goodResult), 0);
+}
+
+ATF_TC(memccpy_simple);
+ATF_TC_HEAD(memccpy_simple, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memccpy(3) results");
+}
+
+ATF_TC_BODY(memccpy_simple, tc)
+{
+ char buf[100];
+ char c = ' ';
+
+ (void)memset(buf, c, sizeof(buf));
+
+ ATF_CHECK(memccpy(buf, "foo bar", c, sizeof(buf)) != NULL);
+ ATF_CHECK(buf[4] == c);
+
+ ATF_CHECK(memccpy(buf, "foo bar", '\0', sizeof(buf) - 1) != NULL);
+ ATF_CHECK(buf[8] == c);
+
+ ATF_CHECK(memccpy(buf, "foo bar", 'x', 7) == NULL);
+ ATF_CHECK(strncmp(buf, "foo bar", 7) == 0);
+
+ ATF_CHECK(memccpy(buf, "xxxxxxx", 'r', 7) == NULL);
+ ATF_CHECK(strncmp(buf, "xxxxxxx", 7) == 0);
+}
+
+ATF_TC(memcpy_return);
+ATF_TC_HEAD(memcpy_return, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memcpy(3) return value");
+}
+
+ATF_TC_BODY(memcpy_return, tc)
+{
+ char *b = (char *)0x1;
+ char c[2];
+ ATF_REQUIRE_EQ(memcpy(b, b, 0), b);
+ ATF_REQUIRE_EQ(memcpy(c, "ab", sizeof(c)), c);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, memcpy_basic);
+ ATF_TP_ADD_TC(tp, memcpy_return);
+ ATF_TP_ADD_TC(tp, memccpy_simple);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_memmem.c b/contrib/netbsd-tests/lib/libc/string/t_memmem.c
new file mode 100644
index 0000000..8734bc3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_memmem.c
@@ -0,0 +1,105 @@
+/* $NetBSD: t_memmem.c,v 1.2 2011/07/07 08:27:36 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Perry E. Metzger of Metzger, Dowdeswell & Co. LLC.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char p0[] = "";
+int lp0 = 0;
+char p1[] = "0123";
+int lp1 = 4;
+char p2[] = "456";
+int lp2 = 3;
+char p3[] = "789";
+int lp3 = 3;
+char p4[] = "abc";
+int lp4 = 3;
+char p5[] = "0";
+int lp5 = 1;
+char p6[] = "9";
+int lp6 = 1;
+char p7[] = "654";
+int lp7 = 3;
+
+char b0[] = "";
+int lb0 = 0;
+char b1[] = "0";
+int lb1 = 1;
+char b2[] = "0123456789";
+int lb2 = 10;
+
+#define expect(b) \
+ if (!(b)) { \
+ fprintf(stderr, "failed on line %d\n", __LINE__); \
+ atf_tc_fail("Check stderr for test id/line"); \
+ }
+
+ATF_TC(memmem_basic);
+ATF_TC_HEAD(memmem_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test memmem results");
+}
+
+ATF_TC_BODY(memmem_basic, tc)
+{
+
+#if defined(__darwin__) || defined(__FreeBSD__)
+ expect(memmem(b2, lb2, p0, lp0) == NULL);
+ expect(memmem(b0, lb0, p0, lp0) == NULL);
+#else
+ expect(memmem(b2, lb2, p0, lp0) == b2);
+ expect(memmem(b0, lb0, p0, lp0) == b0);
+#endif
+ expect(memmem(b0, lb0, p1, lp1) == NULL);
+ expect(memmem(b1, lb1, p1, lp1) == NULL);
+
+ expect(memmem(b2, lb2, p1, lp1) == b2);
+ expect(memmem(b2, lb2, p2, lp2) == (b2 + 4));
+ expect(memmem(b2, lb2, p3, lp3) == (b2 + 7));
+
+ expect(memmem(b2, lb2, p5, lp5) == b2);
+ expect(memmem(b2, lb2, p6, lp6) == (b2 + 9));
+
+ expect(memmem(b2, lb2, p4, lp4) == NULL);
+ expect(memmem(b2, lb2, p7, lp7) == NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, memmem_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_memset.c b/contrib/netbsd-tests/lib/libc/string/t_memset.c
new file mode 100644
index 0000000..c1fb385
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_memset.c
@@ -0,0 +1,207 @@
+/* $NetBSD: t_memset.c,v 1.3 2013/03/17 02:23:31 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_memset.c,v 1.3 2013/03/17 02:23:31 christos Exp $");
+
+#include <sys/stat.h>
+
+#include <atf-c.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static long page = 0;
+static void fill(char *, size_t, char);
+static bool check(char *, size_t, char);
+
+ATF_TC(memset_array);
+ATF_TC_HEAD(memset_array, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memset(3) with arrays");
+}
+
+ATF_TC_BODY(memset_array, tc)
+{
+ char buf[1024];
+
+ (void)memset(buf, 0, sizeof(buf));
+
+ if (check(buf, sizeof(buf), 0) != true)
+ atf_tc_fail("memset(3) did not fill a static buffer");
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ if (check(buf, sizeof(buf), 'x') != true)
+ atf_tc_fail("memset(3) did not fill a static buffer");
+}
+
+ATF_TC(memset_return);
+ATF_TC_HEAD(memset_return, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memset(3) return value");
+}
+
+ATF_TC_BODY(memset_return, tc)
+{
+ char *b = (char *)0x1;
+ char c[2];
+ ATF_REQUIRE_EQ(memset(b, 0, 0), b);
+ ATF_REQUIRE_EQ(memset(c, 2, sizeof(c)), c);
+}
+
+ATF_TC(memset_basic);
+ATF_TC_HEAD(memset_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of memset(3)");
+}
+
+ATF_TC_BODY(memset_basic, tc)
+{
+ char *buf, *ret;
+
+ buf = malloc(page);
+ ret = malloc(page);
+
+ ATF_REQUIRE(buf != NULL);
+ ATF_REQUIRE(ret != NULL);
+
+ fill(ret, page, 0);
+ memset(buf, 0, page);
+
+ ATF_REQUIRE(memcmp(ret, buf, page) == 0);
+
+ fill(ret, page, 'x');
+ memset(buf, 'x', page);
+
+ ATF_REQUIRE(memcmp(ret, buf, page) == 0);
+
+ free(buf);
+ free(ret);
+}
+
+ATF_TC(memset_nonzero);
+ATF_TC_HEAD(memset_nonzero, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memset(3) with non-zero params");
+}
+
+ATF_TC_BODY(memset_nonzero, tc)
+{
+ const size_t n = 0x7f;
+ char *buf;
+ size_t i;
+
+ buf = malloc(page);
+ ATF_REQUIRE(buf != NULL);
+
+ for (i = 0x21; i < n; i++) {
+
+ (void)memset(buf, i, page);
+
+ if (check(buf, page, i) != true)
+ atf_tc_fail("memset(3) did not fill properly");
+ }
+
+ free(buf);
+}
+
+ATF_TC(memset_struct);
+ATF_TC_HEAD(memset_struct, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memset(3) with a structure");
+}
+
+ATF_TC_BODY(memset_struct, tc)
+{
+ struct stat st;
+
+ st.st_dev = 0;
+ st.st_ino = 1;
+ st.st_mode = 2;
+ st.st_nlink = 3;
+ st.st_uid = 4;
+ st.st_gid = 5;
+ st.st_rdev = 6;
+ st.st_size = 7;
+ st.st_atime = 8;
+ st.st_mtime = 9;
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ ATF_CHECK(st.st_dev == 0);
+ ATF_CHECK(st.st_ino == 0);
+ ATF_CHECK(st.st_mode == 0);
+ ATF_CHECK(st.st_nlink == 0);
+ ATF_CHECK(st.st_uid == 0);
+ ATF_CHECK(st.st_gid == 0);
+ ATF_CHECK(st.st_rdev == 0);
+ ATF_CHECK(st.st_size == 0);
+ ATF_CHECK(st.st_atime == 0);
+ ATF_CHECK(st.st_mtime == 0);
+}
+
+static void
+fill(char *buf, size_t len, char x)
+{
+ size_t i;
+
+ for (i = 0; i < len; i++)
+ buf[i] = x;
+}
+
+static bool
+check(char *buf, size_t len, char x)
+{
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+
+ if (buf[i] != x)
+ return false;
+ }
+
+ return true;
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+ ATF_TP_ADD_TC(tp, memset_array);
+ ATF_TP_ADD_TC(tp, memset_basic);
+ ATF_TP_ADD_TC(tp, memset_nonzero);
+ ATF_TP_ADD_TC(tp, memset_struct);
+ ATF_TP_ADD_TC(tp, memset_return);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_popcount.c b/contrib/netbsd-tests/lib/libc/string/t_popcount.c
new file mode 100644
index 0000000..2bae52f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_popcount.c
@@ -0,0 +1,198 @@
+/* $NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $ */
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $");
+
+#include <atf-c.h>
+#include <strings.h>
+
+static unsigned int byte_count[256];
+
+static void
+popcount_init(const char *cfg_var)
+{
+ unsigned int i, j;
+
+ if (strcasecmp(cfg_var, "YES") == 0 ||
+ strcasecmp(cfg_var, "Y") == 0 ||
+ strcasecmp(cfg_var, "1") == 0 ||
+ strcasecmp(cfg_var, "T") == 0 ||
+ strcasecmp(cfg_var, "TRUE") == 0) {
+ for (i = 0; i < 256; ++i) {
+ byte_count[i] = 0;
+ for (j = i; j != 0; j >>= 1) {
+ if (j & 1)
+ ++byte_count[i];
+ }
+ }
+ return;
+ }
+
+ atf_tc_skip("config variable \"run_popcount\" not set to YES/TRUE");
+}
+
+unsigned int test_parts[256] = {
+ 0x318e53e6U, 0x11710316U, 0x62608ffaU, 0x67e0f562U,
+ 0xe432e82cU, 0x9862e8b2U, 0x7d96a627U, 0x3f74ad31U,
+ 0x3cecf906U, 0xcdc0dcb4U, 0x241dab64U, 0x31e6133eU,
+ 0x23086ad4U, 0x721d5a91U, 0xc483da53U, 0x6a62af52U,
+ 0xf3f5c386U, 0xe0de3f77U, 0x65afe528U, 0xf4816485U,
+ 0x40ccbf08U, 0x25df49c1U, 0xae5a6ee0U, 0xab36ccadU,
+ 0x87e1ec29U, 0x60ca2407U, 0x49d62e47U, 0xa09f2df5U,
+ 0xaf4c1c68U, 0x8ef08d50U, 0x624cfd2fU, 0xa6a36f20U,
+ 0x68aaf879U, 0x0fe9deabU, 0x5c9a4060U, 0x215d8f08U,
+ 0x55e84712U, 0xea1f1681U, 0x3a10b8a1U, 0x08e06632U,
+ 0xcbc875e2U, 0x31e53258U, 0xcd3807a4U, 0xb9d17516U,
+ 0x8fbfd9abU, 0x6651b555U, 0x550fb381U, 0x05061b9dU,
+ 0x35aef3f2U, 0x9175078cU, 0xae0f14daU, 0x92a2d5f8U,
+ 0x70d968feU, 0xe86f41c5U, 0x5cfaf39fU, 0x8499b18dU,
+ 0xb33f879aU, 0x0a68ad3dU, 0x9323ecc1U, 0x060037ddU,
+ 0xb91a5051U, 0xa0dbebf6U, 0x3e6aa6f1U, 0x7b422b5bU,
+ 0x599e811eU, 0x199f7594U, 0xca453365U, 0x1cda6f48U,
+ 0xe9c75d2cU, 0x6a873217U, 0x79c45d72U, 0x143b8e37U,
+ 0xa11df26eU, 0xaf31f80aU, 0x311bf759U, 0x2378563cU,
+ 0x9ab95fa5U, 0xfcf4d47cU, 0x1f7db268U, 0xd64b09e1U,
+ 0xad7936daU, 0x7a59005cU, 0x45b173d3U, 0xc1a71b32U,
+ 0x7d9f0de2U, 0xa9ac3792U, 0x9e7f9966U, 0x7f0b8080U,
+ 0xece6c06fU, 0x78d92a3cU, 0x6d5f8f6cU, 0xc50ca544U,
+ 0x5d8ded27U, 0xd27a8462U, 0x4bcd13ccU, 0xd49075f2U,
+ 0xa8d52acfU, 0x41915d97U, 0x564f7062U, 0xefb046e2U,
+ 0xe296277aU, 0x605b0ea3U, 0x10b2c3a1U, 0x4e8e5c66U,
+ 0x4bd8ec04U, 0x29935be9U, 0x381839f3U, 0x555d8824U,
+ 0xd6befddbU, 0x5d8d6d6eU, 0xb2fdb7b4U, 0xb471c8fcU,
+ 0xc2fd325bU, 0x932d2487U, 0xbdbbadefU, 0x66c8895dU,
+ 0x5d77857aU, 0x259f1cc0U, 0x302037faU, 0xda9aa7a8U,
+ 0xb112c6aaU, 0x78f74192U, 0xfd4da741U, 0xfa5765c1U,
+ 0x6ea1bc5cU, 0xd283f39cU, 0x268ae67dU, 0xdedcd134U,
+ 0xbbf92410U, 0x6b45fb55U, 0x2f75ac71U, 0x64bf2ca5U,
+ 0x8b99675aU, 0x3f4923b6U, 0x7e610550U, 0x04b1c06dU,
+ 0x8f92e7c6U, 0x45cb608bU, 0x2d06d1f2U, 0x79cf387aU,
+ 0xfd3ed225U, 0x243eee20U, 0x2cbefc6fU, 0x8286cbaaU,
+ 0x70d4c182U, 0x054e3cc6U, 0xb66c5362U, 0x0c73fa5dU,
+ 0x539948feU, 0xec638563U, 0x0cf04ab6U, 0xec7b52f4U,
+ 0x58eeffceU, 0x6fe8049aU, 0xb3b33332U, 0x2e33bfdbU,
+ 0xcc817567U, 0x71ac57c8U, 0x4bab3ac7U, 0x327c558bU,
+ 0x82a6d279U, 0x5adf71daU, 0x1074a656U, 0x3c533c1fU,
+ 0x82fdbe69U, 0x21b4f6afU, 0xd59580e8U, 0x0de824ebU,
+ 0xa510941bU, 0x7cd91144U, 0xa8c10631U, 0x4c839267U,
+ 0x5d503c2fU, 0xe1567d55U, 0x23910cc7U, 0xdb1bdc34U,
+ 0x2a866704U, 0x33e21f0cU, 0x5c7681b4U, 0x818651caU,
+ 0xb1d18162U, 0x225ad014U, 0xadf7d6baU, 0xac548d9bU,
+ 0xe94736e5U, 0x2279c5f1U, 0x33215d2cU, 0xdc8ab90eU,
+ 0xf5e3d7f2U, 0xedcb15cfU, 0xc9a43c4cU, 0xfc678fc6U,
+ 0x43796b95U, 0x3f8b700cU, 0x867bbc72U, 0x81f71fecU,
+ 0xd00cad7dU, 0x302c458fU, 0x8ae21accU, 0x05850ce8U,
+ 0x7764d8e8U, 0x8a36cd68U, 0x40b44bd7U, 0x1cffaeb7U,
+ 0x2b248f34U, 0x1eefdbafU, 0x574d7437U, 0xe86cd935U,
+ 0xf53dd1c8U, 0x1b022513U, 0xef2d249bU, 0x94fb2b08U,
+ 0x15d3eff8U, 0x14245e1bU, 0x82aa8425U, 0x53959028U,
+ 0x9c5f9b80U, 0x325e0c82U, 0x3e236c24U, 0x74e1dd36U,
+ 0x9890df3fU, 0xaf9701a2U, 0x023b3413U, 0x7634c67eU,
+ 0x55cf5e45U, 0x56d2a95bU, 0xb6db869bU, 0xac19e260U,
+ 0xdd310740U, 0x26d68f84U, 0x45bebf17U, 0xe4a7728fU,
+ 0xf082e66eU, 0xb2fe3c10U, 0x2db1fa2cU, 0x4b3dfcfaU,
+ 0xc7b3a672U, 0xaeadc67bU, 0x6cce6f2bU, 0x8263dbbfU,
+ 0xd9724d5bU, 0xbcc767b5U, 0x8d563798U, 0x2db764b4U,
+ 0x76e0cee7U, 0xd34f9a67U, 0x035c810aU, 0x3f56bdc1U,
+ 0x5b3f2c84U, 0x0baca8c0U, 0xfe979a77U, 0x484ca775U,
+ 0xbdc7f104U, 0xc06c3efbU, 0xdbc5f32cU, 0x44b017e7U,
+};
+
+ATF_TC(popcount_basic);
+ATF_TC_HEAD(popcount_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test popcount results");
+ atf_tc_set_md_var(tc, "timeout", "0");
+}
+
+ATF_TC_BODY(popcount_basic, tc)
+{
+ unsigned int i, r;
+
+ popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO"));
+
+ for (i = 0; i < 0xffffffff; ++i) {
+ r = byte_count[i & 255] + byte_count[(i >> 8) & 255]
+ + byte_count[(i >> 16) & 255]
+ + byte_count[(i >> 24) & 255];
+
+ ATF_CHECK_EQ(r, popcount(i));
+ }
+ ATF_CHECK_EQ(popcount(0xffffffff), 32);
+}
+
+ATF_TC(popcountll_basic);
+ATF_TC_HEAD(popcountll_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test popcountll results");
+ atf_tc_set_md_var(tc, "timeout", "0");
+}
+
+ATF_TC_BODY(popcountll_basic, tc)
+{
+ unsigned int i, j, r, r2, p;
+ unsigned long long v;
+
+ popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO"));
+
+ for (j = 0; j < 256; ++j) {
+ p = test_parts[j];
+ r2 = byte_count[p & 255] + byte_count[(p >> 8) & 255]
+ + byte_count[(p >> 16) & 255]
+ + byte_count[(p >> 24) & 255];
+
+ for (i = 0; i < 0xffffffff; ++i) {
+ r = byte_count[i & 255] + byte_count[(i >> 8) & 255]
+ + byte_count[(i >> 16) & 255]
+ + byte_count[(i >> 24) & 255] + r2;
+
+ v = (((unsigned long long)i) << 32) + p;
+ ATF_CHECK_EQ(r, popcountll(v));
+ v = (((unsigned long long)p) << 32) + i;
+ ATF_CHECK_EQ(r, popcountll(v));
+ }
+ }
+
+ ATF_CHECK_EQ(popcountll(0xffffffffffffffffULL), 64);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, popcount_basic);
+ ATF_TP_ADD_TC(tp, popcountll_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcat.c b/contrib/netbsd-tests/lib/libc/string/t_strcat.c
new file mode 100644
index 0000000..bd98691
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strcat.c
@@ -0,0 +1,153 @@
+/* $NetBSD: t_strcat.c,v 1.2 2011/07/14 05:46:04 jruoho Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@acorntoolworks.com>
+ * Public domain.
+ */
+
+#include <atf-c.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+ATF_TC(strcat_basic);
+ATF_TC_HEAD(strcat_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strcat(3) results");
+}
+
+ATF_TC_BODY(strcat_basic, tc)
+{
+ /* try to trick the compiler */
+ char * (*f)(char *, const char *s) = strcat;
+
+ unsigned int a0, a1, t0, t1;
+ char buf0[64];
+ char buf1[64];
+ char *ret;
+
+ struct tab {
+ const char* val;
+ size_t len;
+ };
+
+ const struct tab tab[] = {
+ /*
+ * patterns that check for all combinations of leading and
+ * trailing unaligned characters (on a 64 bit processor)
+ */
+
+ { "", 0 },
+ { "a", 1 },
+ { "ab", 2 },
+ { "abc", 3 },
+ { "abcd", 4 },
+ { "abcde", 5 },
+ { "abcdef", 6 },
+ { "abcdefg", 7 },
+ { "abcdefgh", 8 },
+ { "abcdefghi", 9 },
+ { "abcdefghij", 10 },
+ { "abcdefghijk", 11 },
+ { "abcdefghijkl", 12 },
+ { "abcdefghijklm", 13 },
+ { "abcdefghijklmn", 14 },
+ { "abcdefghijklmno", 15 },
+ { "abcdefghijklmnop", 16 },
+ { "abcdefghijklmnopq", 17 },
+ { "abcdefghijklmnopqr", 18 },
+ { "abcdefghijklmnopqrs", 19 },
+ { "abcdefghijklmnopqrst", 20 },
+ { "abcdefghijklmnopqrstu", 21 },
+ { "abcdefghijklmnopqrstuv", 22 },
+ { "abcdefghijklmnopqrstuvw", 23 },
+
+ /*
+ * patterns that check for the cases where the expression:
+ *
+ * ((word - 0x7f7f..7f) & 0x8080..80)
+ *
+ * returns non-zero even though there are no zero bytes in
+ * the word.
+ */
+
+ { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 },
+ { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 },
+ { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 },
+ { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 },
+ { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 },
+ { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 },
+ { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 },
+ { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 },
+ { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 },
+ };
+
+ for (a0 = 0; a0 < sizeof(long); ++a0) {
+ for (a1 = 0; a1 < sizeof(long); ++a1) {
+ for (t0 = 0; t0 < __arraycount(tab); ++t0) {
+ for (t1 = 0; t1 < __arraycount(tab); ++t1) {
+
+ memcpy(&buf0[a0], tab[t0].val,
+ tab[t0].len + 1);
+ memcpy(&buf1[a1], tab[t1].val,
+ tab[t1].len + 1);
+
+ ret = f(&buf0[a0], &buf1[a1]);
+
+ /*
+ * verify strcat returns address
+ * of first parameter
+ */
+ if (&buf0[a0] != ret) {
+ fprintf(stderr, "a0 %d, a1 %d, "
+ "t0 %d, t1 %d\n",
+ a0, a1, t0, t1);
+ atf_tc_fail("strcat did not "
+ "return its first arg");
+ }
+
+ /* verify string copied correctly */
+ if (memcmp(&buf0[a0] + tab[t0].len,
+ &buf1[a1],
+ tab[t1].len + 1) != 0) {
+ fprintf(stderr, "a0 %d, a1 %d, "
+ "t0 %d, t1 %d\n",
+ a0, a1, t0, t1);
+ atf_tc_fail("string not copied "
+ "correctly");
+ }
+ }
+ }
+ }
+ }
+}
+
+ATF_TC(strncat_simple);
+ATF_TC_HEAD(strncat_simple, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strncat(3) results");
+}
+
+ATF_TC_BODY(strncat_simple, tc)
+{
+ char buf[100] = "abcdefg";
+
+ ATF_CHECK(strncat(buf, "xxx", 0) == buf);
+ ATF_CHECK(strcmp(buf, "abcdefg") == 0);
+ ATF_CHECK(strncat(buf, "xxx", 1) == buf);
+ ATF_CHECK(strcmp(buf, "abcdefgx") == 0);
+ ATF_CHECK(strncat(buf, "xxx", 2) == buf);
+ ATF_CHECK(strcmp(buf, "abcdefgxxx") == 0);
+ ATF_CHECK(strncat(buf, "\0", 1) == buf);
+ ATF_CHECK(strcmp(buf, "abcdefgxxx") == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strcat_basic);
+ ATF_TP_ADD_TC(tp, strncat_simple);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_strchr.c b/contrib/netbsd-tests/lib/libc/string/t_strchr.c
new file mode 100644
index 0000000..958b186
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strchr.c
@@ -0,0 +1,292 @@
+/* $NetBSD: t_strchr.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@acorntoolworks.com>
+ * Public domain.
+ */
+
+#include <atf-c.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+
+static char *slow_strchr(char *, int);
+static void verify_strchr(char *, int, unsigned int, unsigned int);
+
+char * (*volatile strchr_fn)(const char *, int);
+
+static char *
+slow_strchr(char *buf, int ch)
+{
+ unsigned char c = 1;
+
+ ch &= 0xff;
+
+ for (; c != 0; buf++) {
+ c = *buf;
+ if (c == ch)
+ return buf;
+ }
+ return 0;
+}
+
+static void
+verify_strchr(char *buf, int ch, unsigned int t, unsigned int a)
+{
+ const char *off, *ok_off;
+
+ off = strchr_fn(buf, ch);
+ ok_off = slow_strchr(buf, ch);
+ if (off == ok_off)
+ return;
+
+ fprintf(stderr, "test_strchr(\"%s\", %#x) gave %zd not %zd (test %d, "
+ "alignment %d)\n",
+ buf, ch, off ? off - buf : -1, ok_off ? ok_off - buf : -1, t, a);
+
+ atf_tc_fail("Check stderr for details");
+}
+
+ATF_TC(strchr_basic);
+ATF_TC_HEAD(strchr_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test strchr(3) results");
+}
+
+ATF_TC_BODY(strchr_basic, tc)
+{
+ unsigned int t, a;
+ char *off;
+ char buf[32];
+
+ const char *tab[] = {
+ "",
+ "a",
+ "aa",
+ "abc",
+ "abcd",
+ "abcde",
+ "abcdef",
+ "abcdefg",
+ "abcdefgh",
+
+ "/",
+ "//",
+ "/a",
+ "/a/",
+ "/ab",
+ "/ab/",
+ "/abc",
+ "/abc/",
+ "/abcd",
+ "/abcd/",
+ "/abcde",
+ "/abcde/",
+ "/abcdef",
+ "/abcdef/",
+ "/abcdefg",
+ "/abcdefg/",
+ "/abcdefgh",
+ "/abcdefgh/",
+
+ "a/",
+ "a//",
+ "a/a",
+ "a/a/",
+ "a/ab",
+ "a/ab/",
+ "a/abc",
+ "a/abc/",
+ "a/abcd",
+ "a/abcd/",
+ "a/abcde",
+ "a/abcde/",
+ "a/abcdef",
+ "a/abcdef/",
+ "a/abcdefg",
+ "a/abcdefg/",
+ "a/abcdefgh",
+ "a/abcdefgh/",
+
+ "ab/",
+ "ab//",
+ "ab/a",
+ "ab/a/",
+ "ab/ab",
+ "ab/ab/",
+ "ab/abc",
+ "ab/abc/",
+ "ab/abcd",
+ "ab/abcd/",
+ "ab/abcde",
+ "ab/abcde/",
+ "ab/abcdef",
+ "ab/abcdef/",
+ "ab/abcdefg",
+ "ab/abcdefg/",
+ "ab/abcdefgh",
+ "ab/abcdefgh/",
+
+ "abc/",
+ "abc//",
+ "abc/a",
+ "abc/a/",
+ "abc/ab",
+ "abc/ab/",
+ "abc/abc",
+ "abc/abc/",
+ "abc/abcd",
+ "abc/abcd/",
+ "abc/abcde",
+ "abc/abcde/",
+ "abc/abcdef",
+ "abc/abcdef/",
+ "abc/abcdefg",
+ "abc/abcdefg/",
+ "abc/abcdefgh",
+ "abc/abcdefgh/",
+
+ "abcd/",
+ "abcd//",
+ "abcd/a",
+ "abcd/a/",
+ "abcd/ab",
+ "abcd/ab/",
+ "abcd/abc",
+ "abcd/abc/",
+ "abcd/abcd",
+ "abcd/abcd/",
+ "abcd/abcde",
+ "abcd/abcde/",
+ "abcd/abcdef",
+ "abcd/abcdef/",
+ "abcd/abcdefg",
+ "abcd/abcdefg/",
+ "abcd/abcdefgh",
+ "abcd/abcdefgh/",
+
+ "abcde/",
+ "abcde//",
+ "abcde/a",
+ "abcde/a/",
+ "abcde/ab",
+ "abcde/ab/",
+ "abcde/abc",
+ "abcde/abc/",
+ "abcde/abcd",
+ "abcde/abcd/",
+ "abcde/abcde",
+ "abcde/abcde/",
+ "abcde/abcdef",
+ "abcde/abcdef/",
+ "abcde/abcdefg",
+ "abcde/abcdefg/",
+ "abcde/abcdefgh",
+ "abcde/abcdefgh/",
+
+ "abcdef/",
+ "abcdef//",
+ "abcdef/a",
+ "abcdef/a/",
+ "abcdef/ab",
+ "abcdef/ab/",
+ "abcdef/abc",
+ "abcdef/abc/",
+ "abcdef/abcd",
+ "abcdef/abcd/",
+ "abcdef/abcde",
+ "abcdef/abcde/",
+ "abcdef/abcdef",
+ "abcdef/abcdef/",
+ "abcdef/abcdefg",
+ "abcdef/abcdefg/",
+ "abcdef/abcdefgh",
+ "abcdef/abcdefgh/",
+
+ "abcdefg/",
+ "abcdefg//",
+ "abcdefg/a",
+ "abcdefg/a/",
+ "abcdefg/ab",
+ "abcdefg/ab/",
+ "abcdefg/abc",
+ "abcdefg/abc/",
+ "abcdefg/abcd",
+ "abcdefg/abcd/",
+ "abcdefg/abcde",
+ "abcdefg/abcde/",
+ "abcdefg/abcdef",
+ "abcdefg/abcdef/",
+ "abcdefg/abcdefg",
+ "abcdefg/abcdefg/",
+ "abcdefg/abcdefgh",
+ "abcdefg/abcdefgh/",
+
+ "abcdefgh/",
+ "abcdefgh//",
+ "abcdefgh/a",
+ "abcdefgh/a/",
+ "abcdefgh/ab",
+ "abcdefgh/ab/",
+ "abcdefgh/abc",
+ "abcdefgh/abc/",
+ "abcdefgh/abcd",
+ "abcdefgh/abcd/",
+ "abcdefgh/abcde",
+ "abcdefgh/abcde/",
+ "abcdefgh/abcdef",
+ "abcdefgh/abcdef/",
+ "abcdefgh/abcdefg",
+ "abcdefgh/abcdefg/",
+ "abcdefgh/abcdefgh",
+ "abcdefgh/abcdefgh/",
+ };
+
+
+ strchr_fn = dlsym(dlopen(0, RTLD_LAZY), "test_strchr");
+ if (!strchr_fn)
+ strchr_fn = strchr;
+
+ for (a = 3; a < 3 + sizeof(long); ++a) {
+ /* Put char and a \0 before the buffer */
+ buf[a-1] = '/';
+ buf[a-2] = '0';
+ buf[a-3] = 0xff;
+ for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
+ int len = strlen(tab[t]) + 1;
+ memcpy(&buf[a], tab[t], len);
+
+ /* Put the char we are looking for after the \0 */
+ buf[a + len] = '/';
+
+ /* Check search for NUL at end of string */
+ verify_strchr(buf + a, 0, t, a);
+
+ /* Then for the '/' in the strings */
+ verify_strchr(buf + a, '/', t, a);
+
+ /* check zero extension of char arg */
+ verify_strchr(buf + a, 0xffffff00 | '/', t, a);
+
+ /* Replace all the '/' with 0xff */
+ while ((off = slow_strchr(buf + a, '/')) != NULL)
+ *off = 0xff;
+
+ buf[a + len] = 0xff;
+
+ /* Check we can search for 0xff as well as '/' */
+ verify_strchr(buf + a, 0xff, t, a);
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strchr_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcmp.c b/contrib/netbsd-tests/lib/libc/string/t_strcmp.c
new file mode 100644
index 0000000..14e2e9c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strcmp.c
@@ -0,0 +1,136 @@
+/* $NetBSD: t_strcmp.c,v 1.4 2012/03/25 08:17:54 joerg Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@acorntoolworks.com>
+ * Public domain.
+ */
+
+#include <atf-c.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+ATF_TC(strcmp_basic);
+ATF_TC_HEAD(strcmp_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strcmp(3) results, #1");
+}
+
+ATF_TC_BODY(strcmp_basic, tc)
+{
+ /* try to trick the compiler */
+ int (*f)(const char *, const char *s) = strcmp;
+
+ unsigned int a0, a1, t;
+ char buf0[64];
+ char buf1[64];
+ int ret;
+
+ struct tab {
+ const char* val0;
+ const char* val1;
+ int ret;
+ };
+
+ const struct tab tab[] = {
+ { "", "", 0 },
+
+ { "a", "a", 0 },
+ { "a", "b", -1 },
+ { "b", "a", +1 },
+ { "", "a", -1 },
+ { "a", "", +1 },
+
+ { "aa", "aa", 0 },
+ { "aa", "ab", -1 },
+ { "ab", "aa", +1 },
+ { "a", "aa", -1 },
+ { "aa", "a", +1 },
+
+ { "aaa", "aaa", 0 },
+ { "aaa", "aab", -1 },
+ { "aab", "aaa", +1 },
+ { "aa", "aaa", -1 },
+ { "aaa", "aa", +1 },
+
+ { "aaaa", "aaaa", 0 },
+ { "aaaa", "aaab", -1 },
+ { "aaab", "aaaa", +1 },
+ { "aaa", "aaaa", -1 },
+ { "aaaa", "aaa", +1 },
+
+ { "aaaaa", "aaaaa", 0 },
+ { "aaaaa", "aaaab", -1 },
+ { "aaaab", "aaaaa", +1 },
+ { "aaaa", "aaaaa", -1 },
+ { "aaaaa", "aaaa", +1 },
+
+ { "aaaaaa", "aaaaaa", 0 },
+ { "aaaaaa", "aaaaab", -1 },
+ { "aaaaab", "aaaaaa", +1 },
+ { "aaaaa", "aaaaaa", -1 },
+ { "aaaaaa", "aaaaa", +1 },
+ };
+
+ for (a0 = 0; a0 < sizeof(long); ++a0) {
+ for (a1 = 0; a1 < sizeof(long); ++a1) {
+ for (t = 0; t < __arraycount(tab); ++t) {
+ memcpy(&buf0[a0], tab[t].val0,
+ strlen(tab[t].val0) + 1);
+ memcpy(&buf1[a1], tab[t].val1,
+ strlen(tab[t].val1) + 1);
+
+ ret = f(&buf0[a0], &buf1[a1]);
+
+ if ((ret == 0 && tab[t].ret != 0) ||
+ (ret < 0 && tab[t].ret >= 0) ||
+ (ret > 0 && tab[t].ret <= 0)) {
+ fprintf(stderr, "a0 %d, a1 %d, t %d\n",
+ a0, a1, t);
+ fprintf(stderr, "\"%s\" \"%s\" %d\n",
+ &buf0[a0], &buf1[a1], ret);
+ atf_tc_fail("Check stderr for details");
+ }
+ }
+ }
+ }
+}
+
+ATF_TC(strcmp_simple);
+ATF_TC_HEAD(strcmp_simple, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strcmp(3) results, #2");
+}
+
+ATF_TC_BODY(strcmp_simple, tc)
+{
+ char buf1[10] = "xxx";
+ char buf2[10] = "xxy";
+
+ ATF_CHECK(strcmp(buf1, buf1) == 0);
+ ATF_CHECK(strcmp(buf2, buf2) == 0);
+
+ ATF_CHECK(strcmp("x\xf6x", "xox") > 0);
+ ATF_CHECK(strcmp("xxx", "xxxyyy") < 0);
+ ATF_CHECK(strcmp("xxxyyy", "xxx") > 0);
+
+ ATF_CHECK(strcmp(buf1 + 0, buf2 + 0) < 0);
+ ATF_CHECK(strcmp(buf1 + 1, buf2 + 1) < 0);
+ ATF_CHECK(strcmp(buf1 + 2, buf2 + 2) < 0);
+ ATF_CHECK(strcmp(buf1 + 3, buf2 + 3) == 0);
+
+ ATF_CHECK(strcmp(buf2 + 0, buf1 + 0) > 0);
+ ATF_CHECK(strcmp(buf2 + 1, buf1 + 1) > 0);
+ ATF_CHECK(strcmp(buf2 + 2, buf1 + 2) > 0);
+ ATF_CHECK(strcmp(buf2 + 3, buf1 + 3) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strcmp_basic);
+ ATF_TP_ADD_TC(tp, strcmp_simple);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcpy.c b/contrib/netbsd-tests/lib/libc/string/t_strcpy.c
new file mode 100644
index 0000000..285371e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strcpy.c
@@ -0,0 +1,124 @@
+/* $NetBSD: t_strcpy.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@acorntoolworks.com>
+ * Public domain.
+ */
+
+#include <atf-c.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+ATF_TC(strcpy_basic);
+ATF_TC_HEAD(strcpy_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strcpy(3) results");
+}
+
+ATF_TC_BODY(strcpy_basic, tc)
+{
+ /* try to trick the compiler */
+ char * (*f)(char *, const char *s) = strcpy;
+
+ unsigned int a0, a1, t;
+ char buf0[64];
+ char buf1[64];
+ char *ret;
+
+ struct tab {
+ const char* val;
+ size_t len;
+ };
+
+ const struct tab tab[] = {
+ /*
+ * patterns that check for all combinations of leading and
+ * trailing unaligned characters (on a 64 bit processor)
+ */
+
+ { "", 0 },
+ { "a", 1 },
+ { "ab", 2 },
+ { "abc", 3 },
+ { "abcd", 4 },
+ { "abcde", 5 },
+ { "abcdef", 6 },
+ { "abcdefg", 7 },
+ { "abcdefgh", 8 },
+ { "abcdefghi", 9 },
+ { "abcdefghij", 10 },
+ { "abcdefghijk", 11 },
+ { "abcdefghijkl", 12 },
+ { "abcdefghijklm", 13 },
+ { "abcdefghijklmn", 14 },
+ { "abcdefghijklmno", 15 },
+ { "abcdefghijklmnop", 16 },
+ { "abcdefghijklmnopq", 17 },
+ { "abcdefghijklmnopqr", 18 },
+ { "abcdefghijklmnopqrs", 19 },
+ { "abcdefghijklmnopqrst", 20 },
+ { "abcdefghijklmnopqrstu", 21 },
+ { "abcdefghijklmnopqrstuv", 22 },
+ { "abcdefghijklmnopqrstuvw", 23 },
+
+ /*
+ * patterns that check for the cases where the expression:
+ *
+ * ((word - 0x7f7f..7f) & 0x8080..80)
+ *
+ * returns non-zero even though there are no zero bytes in
+ * the word.
+ */
+
+ { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 },
+ { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 },
+ { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 },
+ { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 },
+ { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 },
+ { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 },
+ { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 },
+ { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 },
+ { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 },
+ };
+
+ for (a0 = 0; a0 < sizeof(long); ++a0) {
+ for (a1 = 0; a1 < sizeof(long); ++a1) {
+ for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
+
+ memcpy(&buf1[a1], tab[t].val, tab[t].len + 1);
+ ret = f(&buf0[a0], &buf1[a1]);
+
+ /*
+ * verify strcpy returns address of
+ * first parameter
+ */
+ if (&buf0[a0] != ret) {
+ fprintf(stderr, "a0 %d, a1 %d, t %d\n",
+ a0, a1, t);
+ atf_tc_fail("strcpy did not return "
+ "its first arg");
+ }
+
+ /*
+ * verify string was copied correctly
+ */
+ if (memcmp(&buf0[a0], &buf1[a1],
+ tab[t].len + 1) != 0) {
+ fprintf(stderr, "a0 %d, a1 %d, t %d\n",
+ a0, a1, t);
+ atf_tc_fail("not correctly copied");
+ }
+ }
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strcpy_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_strcspn.c b/contrib/netbsd-tests/lib/libc/string/t_strcspn.c
new file mode 100644
index 0000000..d38cdb4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strcspn.c
@@ -0,0 +1,58 @@
+/* $NetBSD: t_strcspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_strcspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $");
+
+#include <atf-c.h>
+#include <string.h>
+
+ATF_TC(strcspn);
+ATF_TC_HEAD(strcspn, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strcspn(3)");
+}
+
+ATF_TC_BODY(strcspn, tc)
+{
+ ATF_CHECK_EQ(strcspn("abcdefghijklmnop", ""), 16);
+ ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "a"), 0);
+ ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "b"), 1);
+ ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "cd"), 2);
+ ATF_CHECK_EQ(strcspn("abcdefghijklmnop", "qrstuvwxyz"), 16);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strcspn);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_strerror.c b/contrib/netbsd-tests/lib/libc/string/t_strerror.c
new file mode 100644
index 0000000..888a826
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strerror.c
@@ -0,0 +1,139 @@
+/* $NetBSD: t_strerror.c,v 1.3 2011/05/10 06:55:27 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_strerror.c,v 1.3 2011/05/10 06:55:27 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <string.h>
+
+#ifdef __FreeBSD__
+#include <stdio.h>
+#endif
+
+ATF_TC(strerror_basic);
+ATF_TC_HEAD(strerror_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of strerror(3)");
+}
+
+ATF_TC_BODY(strerror_basic, tc)
+{
+ int i;
+
+ for (i = 1; i < sys_nerr; i++)
+ ATF_REQUIRE(strstr(strerror(i), "Unknown error:") == NULL);
+
+ for (; i < sys_nerr + 10; i++)
+ ATF_REQUIRE(strstr(strerror(i), "Unknown error:") != NULL);
+}
+
+ATF_TC(strerror_err);
+ATF_TC_HEAD(strerror_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from strerror(3)");
+}
+
+ATF_TC_BODY(strerror_err, tc)
+{
+
+ errno = 0;
+
+ ATF_REQUIRE(strstr(strerror(INT_MAX), "Unknown error:") != NULL);
+ ATF_REQUIRE(errno == EINVAL);
+
+ errno = 0;
+
+ ATF_REQUIRE(strstr(strerror(INT_MIN), "Unknown error:") != NULL);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+ATF_TC(strerror_r_basic);
+ATF_TC_HEAD(strerror_r_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of strerror_r(3)");
+}
+
+ATF_TC_BODY(strerror_r_basic, tc)
+{
+ char buf[512];
+ int i;
+
+ for (i = 1; i < sys_nerr; i++) {
+ ATF_REQUIRE(strerror_r(i, buf, sizeof(buf)) == 0);
+ ATF_REQUIRE(strstr(buf, "Unknown error:") == NULL);
+ }
+
+ for (; i < sys_nerr + 10; i++) {
+ ATF_REQUIRE(strerror_r(i, buf, sizeof(buf)) == EINVAL);
+ ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL);
+ }
+}
+
+ATF_TC(strerror_r_err);
+ATF_TC_HEAD(strerror_r_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from strerror_r(3)");
+}
+
+ATF_TC_BODY(strerror_r_err, tc)
+{
+ char buf[512];
+ int rv;
+
+ rv = strerror_r(EPERM, buf, 1);
+ ATF_REQUIRE(rv == ERANGE);
+
+ rv = strerror_r(INT_MAX, buf, sizeof(buf));
+
+ ATF_REQUIRE(rv == EINVAL);
+ ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL);
+
+ rv = strerror_r(INT_MIN, buf, sizeof(buf));
+
+ ATF_REQUIRE(rv == EINVAL);
+ ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ (void)setlocale(LC_ALL, "C");
+
+ ATF_TP_ADD_TC(tp, strerror_basic);
+ ATF_TP_ADD_TC(tp, strerror_err);
+ ATF_TP_ADD_TC(tp, strerror_r_basic);
+ ATF_TP_ADD_TC(tp, strerror_r_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_stresep.c b/contrib/netbsd-tests/lib/libc/string/t_stresep.c
new file mode 100644
index 0000000..4678e55
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_stresep.c
@@ -0,0 +1,72 @@
+/* $NetBSD: t_stresep.c,v 1.3 2013/02/15 23:56:32 christos Exp $ */
+
+/*-
+ * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define expect(a) \
+ if ((p = stresep(&q, " ", '\\')) == NULL || strcmp(p, a)) { \
+ fprintf(stderr, "failed on line %d: %s != %s\n", \
+ __LINE__, p, a); \
+ atf_tc_fail("Check stderr for test id/line"); \
+ }
+
+ATF_TC(stresep_basic);
+ATF_TC_HEAD(stresep_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test stresep results");
+}
+
+ATF_TC_BODY(stresep_basic, tc)
+{
+ char brkstr[] = "foo\\ \\ bar baz bar\\ foo\\ bar\\ \\ foo \\ \\ \\ "
+ "baz bar\\ \\ ";
+ char *p, *q = brkstr;
+
+ expect("foo bar");
+ expect("baz");
+ expect("bar foo ");
+ expect("bar foo");
+ expect(" baz");
+ expect("bar ");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, stresep_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_strlen.c b/contrib/netbsd-tests/lib/libc/string/t_strlen.c
new file mode 100644
index 0000000..66158fd
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strlen.c
@@ -0,0 +1,199 @@
+/* $NetBSD: t_strlen.c,v 1.5 2011/07/14 07:33:20 jruoho Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@acorntoolworks.com>
+ * Public domain.
+ */
+
+#include <atf-c.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <unistd.h>
+
+static void write_num(int);
+
+static void
+write_num(int val)
+{
+ char buf[20];
+ int i;
+
+ for (i = sizeof buf; --i >= 0;) {
+ buf[i] = '0' + val % 10;
+ val /= 10;
+ if (val == 0) {
+ write(2, buf + i, sizeof buf - i);
+ return;
+ }
+ }
+ write(2, "overflow", 8);
+}
+
+ATF_TC(strlen_basic);
+ATF_TC_HEAD(strlen_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strlen(3) results");
+}
+
+ATF_TC_BODY(strlen_basic, tc)
+{
+ /* try to trick the compiler */
+ size_t (*strlen_fn)(const char *);
+
+ unsigned int a, t;
+ size_t len;
+ char buf[64];
+
+ struct tab {
+ const char* val;
+ size_t len;
+ };
+
+ const struct tab tab[] = {
+ /*
+ * patterns that check for all combinations of leading and
+ * trailing unaligned characters (on a 64 bit processor)
+ */
+
+ { "", 0 },
+ { "a", 1 },
+ { "ab", 2 },
+ { "abc", 3 },
+ { "abcd", 4 },
+ { "abcde", 5 },
+ { "abcdef", 6 },
+ { "abcdefg", 7 },
+ { "abcdefgh", 8 },
+ { "abcdefghi", 9 },
+ { "abcdefghij", 10 },
+ { "abcdefghijk", 11 },
+ { "abcdefghijkl", 12 },
+ { "abcdefghijklm", 13 },
+ { "abcdefghijklmn", 14 },
+ { "abcdefghijklmno", 15 },
+ { "abcdefghijklmnop", 16 },
+ { "abcdefghijklmnopq", 17 },
+ { "abcdefghijklmnopqr", 18 },
+ { "abcdefghijklmnopqrs", 19 },
+ { "abcdefghijklmnopqrst", 20 },
+ { "abcdefghijklmnopqrstu", 21 },
+ { "abcdefghijklmnopqrstuv", 22 },
+ { "abcdefghijklmnopqrstuvw", 23 },
+
+ /*
+ * patterns that check for the cases where the expression:
+ *
+ * ((word - 0x7f7f..7f) & 0x8080..80)
+ *
+ * returns non-zero even though there are no zero bytes in
+ * the word.
+ */
+
+ { "" "\xff\xff\xff\xff\xff\xff\xff\xff" "abcdefgh", 16 },
+ { "a" "\xff\xff\xff\xff\xff\xff\xff\xff" "bcdefgh", 16 },
+ { "ab" "\xff\xff\xff\xff\xff\xff\xff\xff" "cdefgh", 16 },
+ { "abc" "\xff\xff\xff\xff\xff\xff\xff\xff" "defgh", 16 },
+ { "abcd" "\xff\xff\xff\xff\xff\xff\xff\xff" "efgh", 16 },
+ { "abcde" "\xff\xff\xff\xff\xff\xff\xff\xff" "fgh", 16 },
+ { "abcdef" "\xff\xff\xff\xff\xff\xff\xff\xff" "gh", 16 },
+ { "abcdefg" "\xff\xff\xff\xff\xff\xff\xff\xff" "h", 16 },
+ { "abcdefgh" "\xff\xff\xff\xff\xff\xff\xff\xff" "", 16 },
+ };
+
+ /*
+ * During testing it is useful have the rest of the program
+ * use a known good version!
+ */
+ strlen_fn = dlsym(dlopen(NULL, RTLD_LAZY), "test_strlen");
+ if (!strlen_fn)
+ strlen_fn = strlen;
+
+ for (a = 0; a < sizeof(long); ++a) {
+ for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
+
+ memcpy(&buf[a], tab[t].val, tab[t].len + 1);
+ len = strlen_fn(&buf[a]);
+
+ if (len != tab[t].len) {
+ /* Write error without using printf / strlen */
+ write(2, "alignment ", 10);
+ write_num(a);
+ write(2, ", test ", 7);
+ write_num(t);
+ write(2, ", got len ", 10);
+ write_num(len);
+ write(2, ", not ", 6);
+ write_num(tab[t].len);
+ write(2, ", for '", 7);
+ write(2, tab[t].val, tab[t].len);
+ write(2, "'\n", 2);
+ atf_tc_fail("See stderr for details");
+ }
+ }
+ }
+}
+
+ATF_TC(strlen_huge);
+ATF_TC_HEAD(strlen_huge, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strlen(3) with huge strings");
+}
+
+ATF_TC_BODY(strlen_huge, tc)
+{
+ long page;
+ char *str;
+ size_t i;
+
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+ for (i = 1; i < 1000; i = i + 100) {
+
+ str = malloc(i * page + 1);
+
+ if (str == NULL)
+ continue;
+
+ (void)memset(str, 'x', i * page);
+ str[i * page] = '\0';
+
+ ATF_REQUIRE(strlen(str) == i * page);
+ free(str);
+ }
+}
+
+ATF_TC(strnlen_basic);
+ATF_TC_HEAD(strnlen_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A naive test of strnlen(3)");
+}
+
+ATF_TC_BODY(strnlen_basic, tc)
+{
+ char buf[1];
+
+ buf[0] = '\0';
+
+ ATF_CHECK(strnlen(buf, 000) == 0);
+ ATF_CHECK(strnlen(buf, 111) == 0);
+
+ ATF_CHECK(strnlen("xxx", 0) == 0);
+ ATF_CHECK(strnlen("xxx", 1) == 1);
+ ATF_CHECK(strnlen("xxx", 2) == 2);
+ ATF_CHECK(strnlen("xxx", 3) == 3);
+ ATF_CHECK(strnlen("xxx", 9) == 3);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strlen_basic);
+ ATF_TP_ADD_TC(tp, strlen_huge);
+ ATF_TP_ADD_TC(tp, strnlen_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c b/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c
new file mode 100644
index 0000000..d0f2d9b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strpbrk.c
@@ -0,0 +1,62 @@
+/* $NetBSD: t_strpbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_strpbrk.c,v 1.1 2011/11/21 23:50:45 joerg Exp $");
+
+#include <atf-c.h>
+#include <string.h>
+
+ATF_TC(strpbrk);
+ATF_TC_HEAD(strpbrk, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strpbrk(3)");
+}
+
+ATF_TC_BODY(strpbrk, tc)
+{
+ static const char s[] = "abcdefghijklmnop";
+
+ ATF_CHECK_EQ(strpbrk(s, ""), NULL);
+ ATF_CHECK_EQ(strpbrk(s, "qrst"), NULL);
+ ATF_CHECK_EQ(strpbrk(s, "a"), s);
+ ATF_CHECK_EQ(strpbrk(s, "b"), s + 1);
+ ATF_CHECK_EQ(strpbrk(s, "ab"), s);
+ ATF_CHECK_EQ(strpbrk(s, "cdef"), s + 2);
+ ATF_CHECK_EQ(strpbrk(s, "fedc"), s + 2);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strpbrk);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_strrchr.c b/contrib/netbsd-tests/lib/libc/string/t_strrchr.c
new file mode 100644
index 0000000..038daff
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strrchr.c
@@ -0,0 +1,257 @@
+/* $NetBSD: t_strrchr.c,v 1.1 2011/07/07 08:59:33 jruoho Exp $ */
+
+/*
+ * Written by J.T. Conklin <jtc@acorntoolworks.com>
+ * Public domain.
+ */
+
+#include <atf-c.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+ATF_TC(strrchr_basic);
+ATF_TC_HEAD(strrchr_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strrchr(3) results");
+}
+
+ATF_TC_BODY(strrchr_basic, tc)
+{
+ /* try to trick the compiler */
+ char * (*f)(const char *, int) = strrchr;
+
+ unsigned int a, t;
+ char *off, *off2;
+ char buf[32];
+
+ struct tab {
+ const char* val;
+ char match;
+ ssize_t f_off; /* offset of first match */
+ ssize_t l_off; /* offset of last match */
+ };
+
+ const struct tab tab[] = {
+ { "", 0, 0, 0 },
+ { "a", 0, 0, 0 },
+ { "aa", 0, 0, 0 },
+ { "abc", 0, 0, 0 },
+ { "abcd", 0, 0, 0 },
+ { "abcde", 0, 0, 0 },
+ { "abcdef", 0, 0, 0 },
+ { "abcdefg", 0, 0, 0 },
+ { "abcdefgh", 0, 0, 0 },
+
+ { "/", 1, 0, 0 },
+ { "//", 1, 0, 1 },
+ { "/a", 1, 0, 0 },
+ { "/a/", 1, 0, 2 },
+ { "/ab", 1, 0, 0 },
+ { "/ab/", 1, 0, 3 },
+ { "/abc", 1, 0, 0 },
+ { "/abc/", 1, 0, 4 },
+ { "/abcd", 1, 0, 0 },
+ { "/abcd/", 1, 0, 5 },
+ { "/abcde", 1, 0, 0 },
+ { "/abcde/", 1, 0, 6 },
+ { "/abcdef", 1, 0, 0 },
+ { "/abcdef/", 1, 0, 7 },
+ { "/abcdefg", 1, 0, 0 },
+ { "/abcdefg/", 1, 0, 8 },
+ { "/abcdefgh", 1, 0, 0 },
+ { "/abcdefgh/", 1, 0, 9 },
+
+ { "a/", 1, 1, 1 },
+ { "a//", 1, 1, 2 },
+ { "a/a", 1, 1, 1 },
+ { "a/a/", 1, 1, 3 },
+ { "a/ab", 1, 1, 1 },
+ { "a/ab/", 1, 1, 4 },
+ { "a/abc", 1, 1, 1 },
+ { "a/abc/", 1, 1, 5 },
+ { "a/abcd", 1, 1, 1 },
+ { "a/abcd/", 1, 1, 6 },
+ { "a/abcde", 1, 1, 1 },
+ { "a/abcde/", 1, 1, 7 },
+ { "a/abcdef", 1, 1, 1 },
+ { "a/abcdef/", 1, 1, 8 },
+ { "a/abcdefg", 1, 1, 1 },
+ { "a/abcdefg/", 1, 1, 9 },
+ { "a/abcdefgh", 1, 1, 1 },
+ { "a/abcdefgh/", 1, 1, 10 },
+
+ { "ab/", 1, 2, 2 },
+ { "ab//", 1, 2, 3 },
+ { "ab/a", 1, 2, 2 },
+ { "ab/a/", 1, 2, 4 },
+ { "ab/ab", 1, 2, 2 },
+ { "ab/ab/", 1, 2, 5 },
+ { "ab/abc", 1, 2, 2 },
+ { "ab/abc/", 1, 2, 6 },
+ { "ab/abcd", 1, 2, 2 },
+ { "ab/abcd/", 1, 2, 7 },
+ { "ab/abcde", 1, 2, 2 },
+ { "ab/abcde/", 1, 2, 8 },
+ { "ab/abcdef", 1, 2, 2 },
+ { "ab/abcdef/", 1, 2, 9 },
+ { "ab/abcdefg", 1, 2, 2 },
+ { "ab/abcdefg/", 1, 2, 10 },
+ { "ab/abcdefgh", 1, 2, 2 },
+ { "ab/abcdefgh/", 1, 2, 11 },
+
+ { "abc/", 1, 3, 3 },
+ { "abc//", 1, 3, 4 },
+ { "abc/a", 1, 3, 3 },
+ { "abc/a/", 1, 3, 5 },
+ { "abc/ab", 1, 3, 3 },
+ { "abc/ab/", 1, 3, 6 },
+ { "abc/abc", 1, 3, 3 },
+ { "abc/abc/", 1, 3, 7 },
+ { "abc/abcd", 1, 3, 3 },
+ { "abc/abcd/", 1, 3, 8 },
+ { "abc/abcde", 1, 3, 3 },
+ { "abc/abcde/", 1, 3, 9 },
+ { "abc/abcdef", 1, 3, 3 },
+ { "abc/abcdef/", 1, 3, 10 },
+ { "abc/abcdefg", 1, 3, 3 },
+ { "abc/abcdefg/", 1, 3, 11 },
+ { "abc/abcdefgh", 1, 3, 3 },
+ { "abc/abcdefgh/", 1, 3, 12 },
+
+ { "abcd/", 1, 4, 4 },
+ { "abcd//", 1, 4, 5 },
+ { "abcd/a", 1, 4, 4 },
+ { "abcd/a/", 1, 4, 6 },
+ { "abcd/ab", 1, 4, 4 },
+ { "abcd/ab/", 1, 4, 7 },
+ { "abcd/abc", 1, 4, 4 },
+ { "abcd/abc/", 1, 4, 8 },
+ { "abcd/abcd", 1, 4, 4 },
+ { "abcd/abcd/", 1, 4, 9 },
+ { "abcd/abcde", 1, 4, 4 },
+ { "abcd/abcde/", 1, 4, 10 },
+ { "abcd/abcdef", 1, 4, 4 },
+ { "abcd/abcdef/", 1, 4, 11 },
+ { "abcd/abcdefg", 1, 4, 4 },
+ { "abcd/abcdefg/", 1, 4, 12 },
+ { "abcd/abcdefgh", 1, 4, 4 },
+ { "abcd/abcdefgh/", 1, 4, 13 },
+
+ { "abcde/", 1, 5, 5 },
+ { "abcde//", 1, 5, 6 },
+ { "abcde/a", 1, 5, 5 },
+ { "abcde/a/", 1, 5, 7 },
+ { "abcde/ab", 1, 5, 5 },
+ { "abcde/ab/", 1, 5, 8 },
+ { "abcde/abc", 1, 5, 5 },
+ { "abcde/abc/", 1, 5, 9 },
+ { "abcde/abcd", 1, 5, 5 },
+ { "abcde/abcd/", 1, 5, 10 },
+ { "abcde/abcde", 1, 5, 5 },
+ { "abcde/abcde/", 1, 5, 11 },
+ { "abcde/abcdef", 1, 5, 5 },
+ { "abcde/abcdef/", 1, 5, 12 },
+ { "abcde/abcdefg", 1, 5, 5 },
+ { "abcde/abcdefg/", 1, 5, 13 },
+ { "abcde/abcdefgh", 1, 5, 5 },
+ { "abcde/abcdefgh/", 1, 5, 14 },
+
+ { "abcdef/", 1, 6, 6 },
+ { "abcdef//", 1, 6, 7 },
+ { "abcdef/a", 1, 6, 6 },
+ { "abcdef/a/", 1, 6, 8 },
+ { "abcdef/ab", 1, 6, 6 },
+ { "abcdef/ab/", 1, 6, 9 },
+ { "abcdef/abc", 1, 6, 6 },
+ { "abcdef/abc/", 1, 6, 10 },
+ { "abcdef/abcd", 1, 6, 6 },
+ { "abcdef/abcd/", 1, 6, 11 },
+ { "abcdef/abcde", 1, 6, 6 },
+ { "abcdef/abcde/", 1, 6, 12 },
+ { "abcdef/abcdef", 1, 6, 6 },
+ { "abcdef/abcdef/", 1, 6, 13 },
+ { "abcdef/abcdefg", 1, 6, 6 },
+ { "abcdef/abcdefg/", 1, 6, 14 },
+ { "abcdef/abcdefgh", 1, 6, 6 },
+ { "abcdef/abcdefgh/", 1, 6, 15 },
+
+ { "abcdefg/", 1, 7, 7 },
+ { "abcdefg//", 1, 7, 8 },
+ { "abcdefg/a", 1, 7, 7 },
+ { "abcdefg/a/", 1, 7, 9 },
+ { "abcdefg/ab", 1, 7, 7 },
+ { "abcdefg/ab/", 1, 7, 10 },
+ { "abcdefg/abc", 1, 7, 7 },
+ { "abcdefg/abc/", 1, 7, 11 },
+ { "abcdefg/abcd", 1, 7, 7 },
+ { "abcdefg/abcd/", 1, 7, 12 },
+ { "abcdefg/abcde", 1, 7, 7 },
+ { "abcdefg/abcde/", 1, 7, 13 },
+ { "abcdefg/abcdef", 1, 7, 7 },
+ { "abcdefg/abcdef/", 1, 7, 14 },
+ { "abcdefg/abcdefg", 1, 7, 7 },
+ { "abcdefg/abcdefg/", 1, 7, 15 },
+ { "abcdefg/abcdefgh", 1, 7, 7 },
+ { "abcdefg/abcdefgh/", 1, 7, 16 },
+
+ { "abcdefgh/", 1, 8, 8 },
+ { "abcdefgh//", 1, 8, 9 },
+ { "abcdefgh/a", 1, 8, 8 },
+ { "abcdefgh/a/", 1, 8, 10 },
+ { "abcdefgh/ab", 1, 8, 8 },
+ { "abcdefgh/ab/", 1, 8, 11 },
+ { "abcdefgh/abc", 1, 8, 8 },
+ { "abcdefgh/abc/", 1, 8, 12 },
+ { "abcdefgh/abcd", 1, 8, 8 },
+ { "abcdefgh/abcd/", 1, 8, 13 },
+ { "abcdefgh/abcde", 1, 8, 8 },
+ { "abcdefgh/abcde/", 1, 8, 14 },
+ { "abcdefgh/abcdef", 1, 8, 8 },
+ { "abcdefgh/abcdef/", 1, 8, 15 },
+ { "abcdefgh/abcdefg", 1, 8, 8 },
+ { "abcdefgh/abcdefg/", 1, 8, 16 },
+ { "abcdefgh/abcdefgh", 1, 8, 8 },
+ { "abcdefgh/abcdefgh/", 1, 8, 17 },
+ };
+
+ for (a = 0; a < sizeof(long); ++a) {
+ for (t = 0; t < (sizeof(tab) / sizeof(tab[0])); ++t) {
+ strcpy(&buf[a], tab[t].val);
+
+ off = f(&buf[a], '/');
+ if (tab[t].match == 0) {
+ if (off != 0) {
+ fprintf(stderr, "a %d, t %d\n", a, t);
+ atf_tc_fail("strrchr should not have "
+ "found the character");
+ }
+ } else if (tab[t].match == 1) {
+ if (tab[t].l_off != (off - &buf[a])) {
+ fprintf(stderr, "a %d, t %d\n", a, t);
+ atf_tc_fail("strrchr returns wrong "
+ "offset");
+ }
+ } else {
+ fprintf(stderr, "a %d, t %d\n", a, t);
+ atf_tc_fail("bad test case data");
+ }
+
+ /* check zero extension of char arg */
+ off2 = f(&buf[a], 0xffffff00 | '/');
+ if (off != off2) {
+ fprintf(stderr, "a %d, t %d\n", a, t);
+ atf_tc_fail("zero extension of char arg fails");
+ }
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strrchr_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_strspn.c b/contrib/netbsd-tests/lib/libc/string/t_strspn.c
new file mode 100644
index 0000000..6782181
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strspn.c
@@ -0,0 +1,60 @@
+/* $NetBSD: t_strspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_strspn.c,v 1.1 2011/11/21 23:50:45 joerg Exp $");
+
+#include <atf-c.h>
+#include <string.h>
+
+ATF_TC(strspn);
+ATF_TC_HEAD(strspn, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test strspn(3)");
+}
+
+ATF_TC_BODY(strspn, tc)
+{
+ ATF_CHECK_EQ(strspn("abcdefghijklmnop", ""), 0);
+ ATF_CHECK_EQ(strspn("abcdefghijklmnop", "a"), 1);
+ ATF_CHECK_EQ(strspn("abcdefghijklmnop", "b"), 0);
+ ATF_CHECK_EQ(strspn("abcdefghijklmnop", "ab"), 2);
+ ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abc"), 3);
+ ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abce"), 3);
+ ATF_CHECK_EQ(strspn("abcdefghijklmnop", "abcdefghijklmnop"), 16);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strspn);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_swab.c b/contrib/netbsd-tests/lib/libc/string/t_swab.c
new file mode 100644
index 0000000..797397a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_swab.c
@@ -0,0 +1,95 @@
+/* $NetBSD: t_swab.c,v 1.2 2011/07/07 08:27:36 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Christos Zoulas.
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <err.h>
+
+#define MAXCHK 100
+
+static void
+build(char *a, char *b, size_t n) {
+ size_t i;
+
+ n >>= 1;
+ for (i = 0; i < n; i += 2) {
+ b[i+1] = a[i] = (char)i;
+ b[i] = a[i+1] = (char)(i+1);
+ }
+ for (n <<= 1; n < MAXCHK; n++)
+ a[n] = b[n] = (char)~0;
+}
+
+static void
+dump(const char *f, char *b, size_t l)
+{
+
+ printf("%s ", f);
+ while (l--)
+ printf("%.2x ", (unsigned char)*b++);
+ printf("\n");
+}
+
+ATF_TC(swab_basic);
+ATF_TC_HEAD(swab_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test swab results");
+}
+
+ATF_TC_BODY(swab_basic, tc)
+{
+ char a[MAXCHK], b[MAXCHK], r[MAXCHK];
+ size_t i;
+
+ for (i = 0; i < MAXCHK; i += 2) {
+ build(a, b, i);
+ (void)memset(r, ~0, MAXCHK);
+ swab(a, r, i);
+ if (memcmp(b, r, MAXCHK) != 0) {
+ fprintf(stderr, "pattern mismatch at %lu bytes",
+ (unsigned long)i);
+ dump("expect:", b, MAXCHK);
+ dump("result:", r, MAXCHK);
+ atf_tc_fail("Check stderr for details");
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, swab_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c b/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c
new file mode 100644
index 0000000..0f2068a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c
@@ -0,0 +1,168 @@
+/* $NetBSD: all_sync_ops_linkable.c,v 1.4 2014/02/21 10:26:25 martin Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Martin Husemann <martin@NetBSD.org>.
+ *
+ * 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.
+ */
+
+/*
+ * This is a simple link-time test to verify all builtin atomic sync
+ * operations are available. Depending on the exact cpu/arch code generator
+ * options, some of these need support functions (which on NetBSD we
+ * typically provide in src/common/lib/libc/atomic).
+ *
+ * The list of operations has been extracted from sync-builtins.def file
+ * in the gcc distribution (as of gcc 4.8.2).
+ */
+
+#include <machine/types.h>
+#include <sys/inttypes.h>
+
+volatile uint8_t u8 = 0;
+volatile uint16_t u16 = 0;
+volatile uint32_t u32 = 0;
+
+#ifdef __HAVE_ATOMIC64_OPS
+volatile uint64_t u64 = 0;
+#endif
+
+int
+main(int argc, char **argv)
+{
+ __sync_synchronize();
+ __sync_add_and_fetch(&u8, 1);
+ __sync_add_and_fetch_1(&u8, 1);
+ __sync_add_and_fetch_2(&u16, 1);
+ __sync_add_and_fetch_4(&u32, 1);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_add_and_fetch_8(&u64, 1);
+#endif
+ __sync_bool_compare_and_swap(&u8, 1, 2);
+ __sync_bool_compare_and_swap_1(&u8, 1, 2);
+ __sync_bool_compare_and_swap_2(&u16, 1, 2);
+ __sync_bool_compare_and_swap_4(&u32, 1, 2);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_bool_compare_and_swap_8(&u64, 1, 2);
+#endif
+ __sync_fetch_and_add(&u8, 1);
+ __sync_fetch_and_add_1(&u8, 1);
+ __sync_fetch_and_add_2(&u16, 1);
+ __sync_fetch_and_add_4(&u32, 1);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_fetch_and_add_8(&u64, 1);
+#endif
+ __sync_fetch_and_and(&u8, 0x80);
+ __sync_fetch_and_and_1(&u8, 0x80);
+ __sync_fetch_and_and_2(&u16, 0x80);
+ __sync_fetch_and_and_4(&u32, 0x80);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_fetch_and_and_8(&u64, 0x80);
+#endif
+#ifndef __clang__
+ __sync_fetch_and_nand(&u8, 0x80);
+ __sync_fetch_and_nand_1(&u8, 0x80);
+ __sync_fetch_and_nand_2(&u16, 0x80);
+ __sync_fetch_and_nand_4(&u32, 0x80);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_fetch_and_nand_8(&u64, 0x80);
+#endif
+#endif
+ __sync_fetch_and_or(&u8, 0x80);
+ __sync_fetch_and_or_1(&u8, 0x80);
+ __sync_fetch_and_or_2(&u16, 0x80);
+ __sync_fetch_and_or_4(&u32, 0x80);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_fetch_and_or_8(&u64, 0x80);
+#endif
+ __sync_fetch_and_sub(&u8, 0x80);
+ __sync_fetch_and_sub_1(&u8, 0x80);
+ __sync_fetch_and_sub_2(&u16, 0x80);
+ __sync_fetch_and_sub_4(&u32, 0x80);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_fetch_and_sub_8(&u64, 0x80);
+#endif
+ __sync_fetch_and_xor(&u8, 0x80);
+ __sync_fetch_and_xor_1(&u8, 0x80);
+ __sync_fetch_and_xor_2(&u16, 0x80);
+ __sync_fetch_and_xor_4(&u32, 0x80);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_fetch_and_xor_8(&u64, 0x80);
+#endif
+ __sync_lock_release(&u8);
+ __sync_lock_release_1(&u8);
+ __sync_lock_release_2(&u16);
+ __sync_lock_release_4(&u32);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_lock_release_8(&u64);
+#endif
+ __sync_lock_test_and_set(&u8, 5);
+ __sync_lock_test_and_set_1(&u8, 5);
+ __sync_lock_test_and_set_2(&u16, 5);
+ __sync_lock_test_and_set_4(&u32, 5);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_lock_test_and_set_8(&u64, 5);
+#endif
+#ifndef __clang__
+ __sync_nand_and_fetch(&u8, 5);
+ __sync_nand_and_fetch_1(&u8, 5);
+ __sync_nand_and_fetch_2(&u16, 5);
+ __sync_nand_and_fetch_4(&u32, 5);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_nand_and_fetch_8(&u64, 5);
+#endif
+#endif
+ __sync_or_and_fetch(&u8, 5);
+ __sync_or_and_fetch_1(&u8, 5);
+ __sync_or_and_fetch_2(&u16, 5);
+ __sync_or_and_fetch_4(&u32, 5);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_or_and_fetch_8(&u64, 5);
+#endif
+ __sync_sub_and_fetch(&u8, 5);
+ __sync_sub_and_fetch_1(&u8, 5);
+ __sync_sub_and_fetch_2(&u16, 5);
+ __sync_sub_and_fetch_4(&u32, 5);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_sub_and_fetch_8(&u64, 5);
+#endif
+ __sync_val_compare_and_swap(&u8, 5, 9);
+ __sync_val_compare_and_swap_1(&u8, 5, 9);
+ __sync_val_compare_and_swap_2(&u16, 5, 9);
+ __sync_val_compare_and_swap_4(&u32, 5, 9);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_val_compare_and_swap_8(&u64, 5, 9);
+#endif
+ __sync_xor_and_fetch(&u8, 5);
+ __sync_xor_and_fetch_1(&u8, 5);
+ __sync_xor_and_fetch_2(&u16, 5);
+ __sync_xor_and_fetch_4(&u32, 5);
+#ifdef __HAVE_ATOMIC64_OPS
+ __sync_xor_and_fetch_8(&u64, 5);
+#endif
+
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_access.c b/contrib/netbsd-tests/lib/libc/sys/t_access.c
new file mode 100644
index 0000000..69d2df2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_access.c
@@ -0,0 +1,219 @@
+/* $NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#include <sys/stat.h>
+#endif
+
+static const char path[] = "access";
+static const int mode[4] = { R_OK, W_OK, X_OK, F_OK };
+
+ATF_TC_WITH_CLEANUP(access_access);
+ATF_TC_HEAD(access_access, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test access(2) for EACCES");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(access_access, tc)
+{
+ const int perm[3] = { 0200, 0400, 0000 };
+ size_t i;
+ int fd;
+
+ fd = open(path, O_RDONLY | O_CREAT);
+
+ if (fd < 0)
+ return;
+
+ for (i = 0; i < __arraycount(mode) - 1; i++) {
+
+ ATF_REQUIRE(fchmod(fd, perm[i]) == 0);
+
+ errno = 0;
+
+ ATF_REQUIRE(access(path, mode[i]) != 0);
+ ATF_REQUIRE(errno == EACCES);
+ }
+
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC_CLEANUP(access_access, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(access_fault);
+ATF_TC_HEAD(access_fault, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test access(2) for EFAULT");
+}
+
+ATF_TC_BODY(access_fault, tc)
+{
+ size_t i;
+
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ errno = 0;
+
+ ATF_REQUIRE(access(NULL, mode[i]) != 0);
+ ATF_REQUIRE(errno == EFAULT);
+
+ errno = 0;
+
+ ATF_REQUIRE(access((char *)-1, mode[i]) != 0);
+ ATF_REQUIRE(errno == EFAULT);
+ }
+}
+
+ATF_TC(access_inval);
+ATF_TC_HEAD(access_inval, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test access(2) for EINVAL");
+}
+
+ATF_TC_BODY(access_inval, tc)
+{
+
+#if defined(__FreeBSD__) && __FreeBSD_version < 1100033
+ atf_tc_expect_fail("arguments to access aren't validated; see "
+ "bug # 181155 for more details");
+#endif
+ errno = 0;
+
+ ATF_REQUIRE(access("/usr", -1) != 0);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+ATF_TC(access_notdir);
+ATF_TC_HEAD(access_notdir, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOTDIR");
+}
+
+ATF_TC_BODY(access_notdir, tc)
+{
+ size_t i;
+
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ errno = 0;
+
+ /*
+ * IEEE Std 1003.1-2008 about ENOTDIR:
+ *
+ * "A component of the path prefix is not a directory,
+ * or the path argument contains at least one non-<slash>
+ * character and ends with one or more trailing <slash>
+ * characters and the last pathname component names an
+ * existing file that is neither a directory nor a symbolic
+ * link to a directory."
+ */
+ ATF_REQUIRE(access("/etc/passwd//", mode[i]) != 0);
+ ATF_REQUIRE(errno == ENOTDIR);
+ }
+}
+
+ATF_TC(access_notexist);
+ATF_TC_HEAD(access_notexist, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test access(2) for ENOENT");
+}
+
+ATF_TC_BODY(access_notexist, tc)
+{
+ size_t i;
+
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ errno = 0;
+
+ ATF_REQUIRE(access("", mode[i]) != 0);
+ ATF_REQUIRE(errno == ENOENT);
+ }
+}
+
+ATF_TC(access_toolong);
+ATF_TC_HEAD(access_toolong, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test access(2) for ENAMETOOLONG");
+}
+
+ATF_TC_BODY(access_toolong, tc)
+{
+ char *buf;
+ size_t i;
+
+ buf = malloc(PATH_MAX);
+
+ if (buf == NULL)
+ return;
+
+ for (i = 0; i < PATH_MAX; i++)
+ buf[i] = 'x';
+
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ errno = 0;
+
+ ATF_REQUIRE(access(buf, mode[i]) != 0);
+ ATF_REQUIRE(errno == ENAMETOOLONG);
+ }
+
+ free(buf);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, access_access);
+ ATF_TP_ADD_TC(tp, access_fault);
+ ATF_TP_ADD_TC(tp, access_inval);
+ ATF_TP_ADD_TC(tp, access_notdir);
+ ATF_TP_ADD_TC(tp, access_notexist);
+ ATF_TP_ADD_TC(tp, access_toolong);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_chroot.c b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c
new file mode 100644
index 0000000..651dc10
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c
@@ -0,0 +1,321 @@
+/* $NetBSD: t_chroot.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_chroot.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <sys/stat.h>
+#endif
+
+ATF_TC(chroot_basic);
+ATF_TC_HEAD(chroot_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of chroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(chroot_basic, tc)
+{
+ char buf[PATH_MAX];
+ int fd, sta;
+ pid_t pid;
+
+ (void)memset(buf, '\0', sizeof(buf));
+ (void)getcwd(buf, sizeof(buf));
+ (void)strlcat(buf, "/dir", sizeof(buf));
+
+ ATF_REQUIRE(mkdir(buf, 0500) == 0);
+ ATF_REQUIRE(chdir(buf) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (chroot(buf) != 0)
+ _exit(EXIT_FAILURE);
+
+ errno = 0;
+
+ if (chroot("/root") != -1)
+ _exit(EXIT_FAILURE);
+
+ if (errno != ENOENT)
+ _exit(EXIT_FAILURE);
+
+ fd = open("file", O_RDONLY | O_CREAT, 0600);
+
+ if (fd < 0)
+ _exit(EXIT_FAILURE);
+
+ if (close(fd) != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("chroot(2) failed");
+
+ (void)chdir("/");
+ (void)strlcat(buf, "/file", sizeof(buf));
+
+ fd = open(buf, O_RDONLY);
+
+ if (fd < 0)
+ atf_tc_fail("chroot(2) did not change the root directory");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(buf) == 0);
+}
+
+ATF_TC(chroot_err);
+ATF_TC_HEAD(chroot_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of chroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(chroot_err, tc)
+{
+ char buf[PATH_MAX + 1];
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, chroot(buf) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, chroot((void *)-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, chroot("/a/b/c/d/e/f/g/h/i/j") == -1);
+}
+
+ATF_TC(chroot_perm);
+ATF_TC_HEAD(chroot_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with chroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(chroot_perm, tc)
+{
+ static char buf[LINE_MAX];
+ pid_t pid;
+ int sta;
+
+ (void)memset(buf, '\0', sizeof(buf));
+ ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ errno = 0;
+
+ if (chroot(buf) != -1)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EPERM)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("chroot(2) succeeded as unprivileged user");
+}
+
+#ifdef __NetBSD__
+ATF_TC(fchroot_basic);
+ATF_TC_HEAD(fchroot_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of fchroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(fchroot_basic, tc)
+{
+ char buf[PATH_MAX];
+ int fd, sta;
+ pid_t pid;
+
+ (void)memset(buf, '\0', sizeof(buf));
+ (void)getcwd(buf, sizeof(buf));
+ (void)strlcat(buf, "/dir", sizeof(buf));
+
+ ATF_REQUIRE(mkdir(buf, 0500) == 0);
+ ATF_REQUIRE(chdir(buf) == 0);
+
+ fd = open(buf, O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (fchroot(fd) != 0)
+ _exit(EXIT_FAILURE);
+
+ if (close(fd) != 0)
+ _exit(EXIT_FAILURE);
+
+ fd = open("file", O_RDONLY | O_CREAT, 0600);
+
+ if (fd < 0)
+ _exit(EXIT_FAILURE);
+
+ if (close(fd) != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("fchroot(2) failed");
+
+ (void)chdir("/");
+ (void)strlcat(buf, "/file", sizeof(buf));
+
+ fd = open(buf, O_RDONLY);
+
+ if (fd < 0)
+ atf_tc_fail("fchroot(2) did not change the root directory");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(buf) == 0);
+}
+
+ATF_TC(fchroot_err);
+ATF_TC_HEAD(fchroot_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of fchroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(fchroot_err, tc)
+{
+ int fd;
+
+ fd = open("/etc/passwd", O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fchroot(-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOTDIR, fchroot(fd) == -1);
+
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC(fchroot_perm);
+ATF_TC_HEAD(fchroot_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with fchroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(fchroot_perm, tc)
+{
+ static char buf[LINE_MAX];
+ struct passwd *pw;
+ int fd, sta;
+ pid_t pid;
+
+ (void)memset(buf, '\0', sizeof(buf));
+ ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL);
+
+ pw = getpwnam("nobody");
+ fd = open(buf, O_RDONLY);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(pw != NULL);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ (void)setuid(pw->pw_uid);
+
+ errno = 0;
+
+ if (fchroot(fd) != -1)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EPERM)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("fchroot(2) succeeded as unprivileged user");
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, chroot_basic);
+ ATF_TP_ADD_TC(tp, chroot_err);
+ ATF_TP_ADD_TC(tp, chroot_perm);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, fchroot_basic);
+ ATF_TP_ADD_TC(tp, fchroot_err);
+ ATF_TP_ADD_TC(tp, fchroot_perm);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c
new file mode 100644
index 0000000..229c343
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c
@@ -0,0 +1,220 @@
+/* $NetBSD: t_clock_gettime.c,v 1.1 2011/10/15 06:42:16 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Frank Kardel.
+ *
+ * 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 (c) 2006 Frank Kardel
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_clock_gettime.c,v 1.1 2011/10/15 06:42:16 jruoho Exp $");
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#ifdef __NetBSD__
+#include <machine/int_limits.h>
+#endif
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef __NetBSD__
+#include "../../../h_macros.h"
+#else
+#include <limits.h>
+#include <stdint.h>
+#include "h_macros.h"
+#endif
+
+#define MINPOSDIFF 15000000 /* 15 ms for now */
+#define TIMEOUT 5
+
+#define TC_HARDWARE "kern.timecounter.hardware"
+#define TC_CHOICE "kern.timecounter.choice"
+
+static void
+check_timecounter(void)
+{
+ struct timespec tsa, tsb, tsl, res;
+ long long mindiff = INTMAX_MAX;
+ time_t endlimit;
+
+#define CL(x) \
+ do { \
+ if ((x) != -1) \
+ break; \
+ atf_tc_fail_nonfatal("%s: %s", #x, strerror(errno)); \
+ return; \
+ } while (0)
+
+ CL(clock_gettime(CLOCK_REALTIME, &tsa));
+ tsl = tsa;
+
+ CL(time(&endlimit));
+ endlimit += TIMEOUT + 1;
+
+ while ((time_t)tsa.tv_sec < endlimit) {
+ long long diff;
+
+ CL(clock_gettime(CLOCK_REALTIME, &tsb));
+ diff = 1000000000LL * (tsb.tv_sec - tsa.tv_sec)
+ + tsb.tv_nsec - tsa.tv_nsec;
+
+ if (diff > 0 && mindiff > diff)
+ mindiff = diff;
+
+ if (diff < 0 || diff > MINPOSDIFF) {
+ long long elapsed;
+ (void)printf("%stime TSA: 0x%jx.%08jx, TSB: 0x%jx.%08jx, "
+ "diff = %lld nsec, ", (diff < 0) ? "BAD " : "",
+ (uintmax_t)tsa.tv_sec, (uintmax_t)tsa.tv_nsec,
+ (uintmax_t)tsb.tv_sec, (uintmax_t)tsb.tv_nsec, diff);
+
+ elapsed = 1000000000LL * (tsb.tv_sec - tsl.tv_sec)
+ + tsb.tv_nsec - tsl.tv_nsec;
+
+
+ (void)printf("%lld nsec\n", elapsed);
+ tsl = tsb;
+
+ ATF_CHECK(diff >= 0);
+ if (diff < 0)
+ return;
+ }
+
+ tsa.tv_sec = tsb.tv_sec;
+ tsa.tv_nsec = tsb.tv_nsec;
+ }
+
+ if (clock_getres(CLOCK_REALTIME, &res) == 0) {
+ long long r = res.tv_sec * 1000000000 + res.tv_nsec;
+
+ (void)printf("Claimed resolution: %lld nsec (%f Hz) or "
+ "better\n", r, 1.0 / r * 1e9);
+ (void)printf("Observed minimum non zero delta: %lld "
+ "nsec\n", mindiff);
+ }
+
+#undef CL
+}
+
+ATF_TC(clock_gettime_real);
+ATF_TC_HEAD(clock_gettime_real, tc)
+{
+ atf_tc_set_md_var(tc, "require.user", "root");
+ atf_tc_set_md_var(tc, "descr",
+ "Checks the monotonicity of the CLOCK_REALTIME implementation");
+ atf_tc_set_md_var(tc, "timeout", "300");
+}
+
+ATF_TC_BODY(clock_gettime_real, tc)
+{
+ char name[128], cbuf[512], ctrbuf[10240];
+ size_t cbufsiz = sizeof(cbuf);
+ size_t ctrbufsiz = sizeof(ctrbuf);
+ const char *p;
+ char *save;
+ int quality, n;
+
+ if (sysctlbyname(TC_HARDWARE, cbuf, &cbufsiz, NULL, 0) != 0) {
+ (void)printf("\nChecking legacy time implementation "
+ "for %d seconds\n", TIMEOUT);
+ check_timecounter();
+ return;
+ /* NOTREACHED */
+ }
+ (void)printf("%s = %s\n", TC_HARDWARE, cbuf);
+ REQUIRE_LIBC(save = strdup(cbuf), NULL);
+
+ RL(sysctlbyname(TC_CHOICE, ctrbuf, &ctrbufsiz, NULL, 0));
+ (void)printf("%s = %s\n", TC_CHOICE, ctrbuf);
+
+ for (p = ctrbuf, n = 0; sscanf(p, "%127[^(](q=%d, f=%*u Hz)%*[ ]%n",
+ name, &quality, &n) == 2; p += n) {
+ struct timespec ts;
+ int ret;
+
+ if (quality < 0)
+ continue;
+
+ (void)printf("\nChecking %s for %d seconds\n", name, TIMEOUT);
+ CHECK_LIBC(ret = sysctlbyname(TC_HARDWARE, NULL, 0,
+ name, strlen(name)), -1);
+ if (ret == -1)
+ continue;
+
+ /* wait a bit to select new counter in clockinterrupt */
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100000000;
+ (void)nanosleep(&ts, NULL);
+
+ check_timecounter();
+ }
+
+ RL(sysctlbyname(TC_HARDWARE, NULL, 0, save, strlen(save)));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, clock_gettime_real);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clone.c b/contrib/netbsd-tests/lib/libc/sys/t_clone.c
new file mode 100644
index 0000000..ea33f32
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_clone.c
@@ -0,0 +1,252 @@
+/* $NetBSD: t_clone.c,v 1.3 2011/12/12 20:55:44 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_clone.c,v 1.3 2011/12/12 20:55:44 joerg Exp $");
+
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <sched.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#define STACKSIZE (8 * 1024)
+#define FROBVAL 41973
+#define CHILDEXIT 0xa5
+
+static int
+dummy(void *arg)
+{
+
+ return 0;
+}
+
+static int
+clone_func(void *arg)
+{
+ long *frobp = arg, diff;
+
+ printf("child: stack ~= %p, frobme = %p\n", &frobp, frobp);
+ fflush(stdout);
+
+ if (frobp[0] != getppid())
+ return 1;
+
+ if (frobp[0] == getpid())
+ return 2;
+
+ diff = labs(frobp[1] - (long) &frobp);
+
+ if (diff > 1024)
+ return 3;
+
+ frobp[1] = FROBVAL;
+
+ return (CHILDEXIT);
+}
+
+ATF_TC(clone_basic);
+ATF_TC_HEAD(clone_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks clone(2)");
+}
+
+ATF_TC_BODY(clone_basic, tc)
+{
+ sigset_t mask;
+ void *allocstack, *stack;
+ pid_t pid;
+ volatile long frobme[2];
+ int stat;
+
+ allocstack = mmap(NULL, STACKSIZE, PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_PRIVATE|MAP_ANON, -1, (off_t) 0);
+
+ ATF_REQUIRE_ERRNO(errno, allocstack != MAP_FAILED);
+
+ stack = allocstack;
+#ifndef __MACHINE_STACK_GROWS_UP
+ stack = (char *)stack + STACKSIZE;
+#endif
+
+ printf("parent: stack = %p, frobme = %p\n", stack, frobme);
+ fflush(stdout);
+
+ frobme[0] = (long)getpid();
+ frobme[1] = (long)stack;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGUSR1);
+
+ ATF_REQUIRE_ERRNO(errno, sigprocmask(SIG_BLOCK, &mask, NULL) != -1);
+
+ switch (pid = __clone(clone_func, stack,
+ CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGUSR1,
+ __UNVOLATILE(frobme))) {
+ case 0:
+ atf_tc_fail("clone() returned 0");
+ /*NOTREACHED*/
+ case -1:
+ atf_tc_fail("clone() failed: %s", strerror(errno));
+ /*NOTREACHED*/
+ default:
+ while (waitpid(pid, &stat, __WCLONE) != pid)
+ continue;
+ }
+
+ ATF_REQUIRE_MSG(WIFEXITED(stat) != 0, "child didn't exit");
+
+ printf("parent: childexit = 0x%x, frobme = %ld\n",
+ WEXITSTATUS(stat), frobme[1]);
+
+ switch (WEXITSTATUS(stat)) {
+ case CHILDEXIT:
+ ATF_REQUIRE_EQ(frobme[1], FROBVAL);
+ break;
+ case 1:
+ atf_tc_fail("child: argument does not contain parent's pid");
+ /*NOTREACHED*/
+ case 2:
+ atf_tc_fail("child: called in parent's pid");
+ /*NOTREACHED*/
+ case 3:
+ atf_tc_fail("child: called with bad stack");
+ /*NOTREACHED*/
+ default:
+ atf_tc_fail("child returned unknown code: %d",
+ WEXITSTATUS(stat));
+ /*NOTREACHED*/
+ }
+
+ ATF_REQUIRE_ERRNO(errno, munmap(allocstack, STACKSIZE) != -1);
+}
+
+ATF_TC(clone_null_stack);
+ATF_TC_HEAD(clone_null_stack, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that clone(2) fails when stack pointer is NULL");
+}
+
+ATF_TC_BODY(clone_null_stack, tc)
+{
+ int rv;
+
+ rv = __clone(dummy, NULL,
+ CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, NULL);
+
+ ATF_REQUIRE_EQ(rv, -1);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+}
+
+ATF_TC(clone_null_func);
+ATF_TC_HEAD(clone_null_func, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that clone(2) fails when function pointer is NULL");
+}
+
+ATF_TC_BODY(clone_null_func, tc)
+{
+ void *allocstack, *stack;
+ int rv;
+
+ allocstack = mmap(NULL, STACKSIZE, PROT_READ|PROT_WRITE|PROT_EXEC,
+ MAP_PRIVATE|MAP_ANON, -1, (off_t) 0);
+ ATF_REQUIRE_ERRNO(errno, allocstack != MAP_FAILED);
+ stack = allocstack;
+#ifndef __MACHINE_STACK_GROWS_UP
+ stack = (char *)stack + STACKSIZE;
+#endif
+
+ errno = 0;
+ rv = __clone(0, stack,
+ CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, NULL);
+
+ ATF_REQUIRE_EQ(rv, -1);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+
+ ATF_REQUIRE_ERRNO(errno, munmap(allocstack, STACKSIZE) != -1);
+}
+
+ATF_TC(clone_out_of_proc);
+ATF_TC_HEAD(clone_out_of_proc, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that clone(2) fails when running out of processes");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(clone_out_of_proc, tc)
+{
+ struct rlimit rl;
+ int rv;
+
+ ATF_REQUIRE_ERRNO(errno, getrlimit(RLIMIT_NPROC, &rl) != -1);
+
+ rl.rlim_cur = 0;
+ rl.rlim_max = 0;
+
+ ATF_REQUIRE_ERRNO(errno, setrlimit(RLIMIT_NPROC, &rl) != -1);
+
+ errno = 0;
+ rv = __clone(dummy, malloc(10240),
+ CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD, (void *)&rl);
+
+ ATF_REQUIRE_EQ(rv, -1);
+ ATF_REQUIRE_EQ(errno, EAGAIN);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, clone_basic);
+ ATF_TP_ADD_TC(tp, clone_null_stack);
+ ATF_TP_ADD_TC(tp, clone_null_func);
+ ATF_TP_ADD_TC(tp, clone_out_of_proc);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_connect.c b/contrib/netbsd-tests/lib/libc/sys/t_connect.c
new file mode 100644
index 0000000..e492206
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_connect.c
@@ -0,0 +1,103 @@
+/* $NetBSD: t_connect.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $ */
+/*
+ * Copyright (c) 2007, 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 <err.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include <atf-c.h>
+
+#ifdef __FreeBSD__
+#include <sys/socket.h>
+#endif
+
+ATF_TC(connect_low_port);
+ATF_TC_HEAD(connect_low_port, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that low-port allocation "
+ "works");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(connect_low_port, tc)
+{
+ struct sockaddr_in sin, sinlist;
+ int sd, val, slist;
+ socklen_t slen;
+
+ slist = socket(AF_INET, SOCK_STREAM, 0);
+ sd = socket(AF_INET, SOCK_STREAM, 0);
+
+ /* bind listening socket */
+ memset(&sinlist, 0, sizeof(sinlist));
+ sinlist.sin_family = AF_INET;
+ sinlist.sin_port = htons(31522);
+ sinlist.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ ATF_REQUIRE_EQ(bind(slist,
+ (struct sockaddr *)&sinlist, sizeof(sinlist)), 0);
+ ATF_REQUIRE_EQ(listen(slist, 1), 0);
+
+ val = IP_PORTRANGE_LOW;
+ if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val,
+ sizeof(val)) == -1)
+ atf_tc_fail("setsockopt failed: %s", strerror(errno));
+
+ memset(&sin, 0, sizeof(sin));
+
+ sin.sin_port = htons(31522);
+ sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+ sin.sin_family = AF_INET;
+
+ if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
+ int serrno = errno;
+ atf_tc_fail("connect failed: %s%s",
+ strerror(serrno),
+ serrno != EACCES ? "" :
+ " (see http://mail-index.netbsd.org/"
+ "source-changes/2007/12/16/0011.html)");
+ }
+
+ slen = sizeof(sin);
+ ATF_REQUIRE_EQ(getsockname(sd, (struct sockaddr *)&sin, &slen), 0);
+ ATF_REQUIRE_EQ(slen, sizeof(sin));
+ ATF_REQUIRE(ntohs(sin.sin_port) <= IPPORT_RESERVEDMAX);
+
+ close(sd);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, connect_low_port);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_dup.c b/contrib/netbsd-tests/lib/libc/sys/t_dup.c
new file mode 100644
index 0000000..d8125ab
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_dup.c
@@ -0,0 +1,405 @@
+/* $NetBSD: t_dup.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_dup.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $");
+
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sysexits.h>
+
+#ifdef __FreeBSD__
+#include <stdbool.h>
+#endif
+
+static char path[] = "dup";
+#ifdef __NetBSD__
+static void check_mode(bool, bool, bool);
+#endif
+
+static void
+check_mode(bool _dup, bool _dup2, bool _dup3)
+{
+ int mode[3] = { O_RDONLY, O_WRONLY, O_RDWR };
+ int perm[5] = { 0700, 0400, 0600, 0444, 0666 };
+ struct stat st, st1;
+ int fd, fd1, fd2;
+ size_t i, j;
+
+ /*
+ * Check that a duplicated descriptor
+ * retains the mode of the original file.
+ */
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ for (j = 0; j < __arraycount(perm); j++) {
+
+ fd1 = open(path, mode[i] | O_CREAT, perm[j]);
+ fd2 = open("/etc/passwd", O_RDONLY);
+
+ ATF_REQUIRE(fd1 >= 0);
+ ATF_REQUIRE(fd2 >= 0);
+
+ if (_dup != false)
+ fd = dup(fd1);
+ else if (_dup2 != false)
+ fd = dup2(fd1, fd2);
+ else if (_dup3 != false)
+ fd = dup3(fd1, fd2, O_CLOEXEC);
+ else {
+ fd = -1;
+ }
+
+ ATF_REQUIRE(fd >= 0);
+
+ (void)memset(&st, 0, sizeof(struct stat));
+ (void)memset(&st1, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(fstat(fd, &st) == 0);
+ ATF_REQUIRE(fstat(fd1, &st1) == 0);
+
+ if (st.st_mode != st1.st_mode)
+ atf_tc_fail("invalid mode");
+
+ (void)close(fd);
+ (void)close(fd1);
+ (void)close(fd2);
+ (void)unlink(path);
+ }
+ }
+}
+
+ATF_TC(dup2_basic);
+ATF_TC_HEAD(dup2_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)");
+}
+
+ATF_TC_BODY(dup2_basic, tc)
+{
+ int fd, fd1, fd2;
+
+ fd1 = open("/etc/passwd", O_RDONLY);
+ fd2 = open("/etc/passwd", O_RDONLY);
+
+ ATF_REQUIRE(fd1 >= 0);
+ ATF_REQUIRE(fd2 >= 0);
+
+ fd = dup2(fd1, fd2);
+ ATF_REQUIRE(fd >= 0);
+
+ if (fd != fd2)
+ atf_tc_fail("invalid descriptor");
+
+ (void)close(fd);
+ (void)close(fd1);
+
+ ATF_REQUIRE(close(fd2) != 0);
+}
+
+ATF_TC(dup2_err);
+ATF_TC_HEAD(dup2_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of dup2(2)");
+}
+
+ATF_TC_BODY(dup2_err, tc)
+{
+ int fd;
+
+ fd = open("/etc/passwd", O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup2(-1, -1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup2(fd, -1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup2(-1, fd) == -1);
+
+ /*
+ * Note that this should not fail with EINVAL.
+ */
+ ATF_REQUIRE(dup2(fd, fd) != -1);
+
+ (void)close(fd);
+}
+
+ATF_TC(dup2_max);
+ATF_TC_HEAD(dup2_max, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test dup2(2) against limits");
+}
+
+ATF_TC_BODY(dup2_max, tc)
+{
+ struct rlimit res;
+
+ (void)memset(&res, 0, sizeof(struct rlimit));
+ (void)getrlimit(RLIMIT_NOFILE, &res);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup2(STDERR_FILENO, res.rlim_cur + 1) == -1);
+}
+
+ATF_TC_WITH_CLEANUP(dup2_mode);
+ATF_TC_HEAD(dup2_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)");
+}
+
+ATF_TC_BODY(dup2_mode, tc)
+{
+ check_mode(false, true, false);
+}
+
+ATF_TC_CLEANUP(dup2_mode, tc)
+{
+ (void)unlink(path);
+}
+
+
+ATF_TC(dup3_err);
+ATF_TC_HEAD(dup3_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test error conditions of dup3(2) (PR lib/45148)");
+}
+
+ATF_TC_BODY(dup3_err, tc)
+{
+ int fd;
+
+ fd = open("/etc/passwd", O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+#if defined(__FreeBSD__) || defined(__linux__)
+ /*
+ * FreeBSD and linux return EINVAL, because...
+ *
+ * [EINVAL] The oldd argument is equal to the newd argument.
+ */
+ ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) == -1);
+#else
+ ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) != -1);
+#endif
+
+ errno = 0;
+#if defined(__FreeBSD__) || defined(__linux__)
+ ATF_REQUIRE_ERRNO(EINVAL, dup3(-1, -1, O_CLOEXEC) == -1);
+ ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1);
+#else
+ ATF_REQUIRE_ERRNO(EBADF, dup3(-1, -1, O_CLOEXEC) == -1);
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup3(-1, fd, O_CLOEXEC) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, dup3(fd, 1, O_NOFOLLOW) == -1);
+
+ (void)close(fd);
+}
+
+ATF_TC(dup3_max);
+ATF_TC_HEAD(dup3_max, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test dup3(2) against limits");
+}
+
+ATF_TC_BODY(dup3_max, tc)
+{
+ struct rlimit res;
+
+ (void)memset(&res, 0, sizeof(struct rlimit));
+ (void)getrlimit(RLIMIT_NOFILE, &res);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup3(STDERR_FILENO,
+ res.rlim_cur + 1, O_CLOEXEC) == -1);
+}
+
+ATF_TC_WITH_CLEANUP(dup3_mode);
+ATF_TC_HEAD(dup3_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of dup3(2)");
+}
+
+ATF_TC_BODY(dup3_mode, tc)
+{
+ check_mode(false, false, true);
+}
+
+ATF_TC_CLEANUP(dup3_mode, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(dup_err);
+ATF_TC_HEAD(dup_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of dup(2)");
+}
+
+ATF_TC_BODY(dup_err, tc)
+{
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup(-1) == -1);
+}
+
+ATF_TC_WITH_CLEANUP(dup_max);
+ATF_TC_HEAD(dup_max, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test dup(2) against limits");
+}
+
+ATF_TC_BODY(dup_max, tc)
+{
+ struct rlimit res;
+ int *buf, fd, sta;
+ size_t i, n;
+ pid_t pid;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * Open a temporary file until the
+ * maximum number of open files is
+ * reached. Ater that dup(2) family
+ * should fail with EMFILE.
+ */
+ (void)closefrom(0);
+ (void)memset(&res, 0, sizeof(struct rlimit));
+
+ n = 10;
+ res.rlim_cur = res.rlim_max = n;
+ if (setrlimit(RLIMIT_NOFILE, &res) != 0)
+ _exit(EX_OSERR);
+
+ buf = calloc(n, sizeof(int));
+
+ if (buf == NULL)
+ _exit(EX_OSERR);
+
+ buf[0] = mkstemp(path);
+
+ if (buf[0] < 0)
+ _exit(EX_OSERR);
+
+ for (i = 1; i < n; i++) {
+
+ buf[i] = open(path, O_RDONLY);
+
+ if (buf[i] < 0)
+ _exit(EX_OSERR);
+ }
+
+ errno = 0;
+ fd = dup(buf[0]);
+
+ if (fd != -1 || errno != EMFILE)
+ _exit(EX_DATAERR);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
+
+ if (WEXITSTATUS(sta) == EX_OSERR)
+ atf_tc_fail("system call error");
+
+ if (WEXITSTATUS(sta) == EX_DATAERR)
+ atf_tc_fail("dup(2) dupped more than RLIMIT_NOFILE");
+
+ atf_tc_fail("unknown error");
+ }
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(dup_max, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(dup_mode);
+ATF_TC_HEAD(dup_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of dup(2)");
+}
+
+ATF_TC_BODY(dup_mode, tc)
+{
+ check_mode(true, false, false);
+}
+
+ATF_TC_CLEANUP(dup_mode, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, dup2_basic);
+ ATF_TP_ADD_TC(tp, dup2_err);
+ ATF_TP_ADD_TC(tp, dup2_max);
+ ATF_TP_ADD_TC(tp, dup2_mode);
+ ATF_TP_ADD_TC(tp, dup3_err);
+ ATF_TP_ADD_TC(tp, dup3_max);
+ ATF_TP_ADD_TC(tp, dup3_mode);
+ ATF_TP_ADD_TC(tp, dup_err);
+ ATF_TP_ADD_TC(tp, dup_max);
+ ATF_TP_ADD_TC(tp, dup_mode);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_fsync.c b/contrib/netbsd-tests/lib/libc/sys/t_fsync.c
new file mode 100644
index 0000000..e61ea7e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_fsync.c
@@ -0,0 +1,120 @@
+/* $NetBSD: t_fsync.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_fsync.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $");
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+ATF_TC(fsync_err);
+ATF_TC_HEAD(fsync_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test error conditions of fsync(2) (PR kern/30)");
+}
+
+ATF_TC_BODY(fsync_err, tc)
+{
+ int i, fd[2];
+
+ /*
+ * The fsync(2) call should fail with EBADF
+ * when the 'fd' is not a valid descriptor.
+ */
+ for (i = 1; i < 1024; i = i + 128) {
+
+ errno = 0;
+
+ ATF_REQUIRE(fsync(-i) == -1);
+ ATF_REQUIRE(errno == EBADF);
+ }
+
+ /*
+ * On the other hand, EINVAL should follow
+ * if the operation is not possible with
+ * the file descriptor.
+ */
+ ATF_REQUIRE(pipe(fd) == 0);
+
+ errno = 0;
+
+ ATF_REQUIRE(fsync(fd[0]) == -1);
+ ATF_REQUIRE(errno == EINVAL);
+
+ errno = 0;
+
+ ATF_REQUIRE(fsync(fd[1]) == -1);
+ ATF_REQUIRE(errno == EINVAL);
+
+ ATF_REQUIRE(close(fd[0]) == 0);
+ ATF_REQUIRE(close(fd[1]) == 0);
+}
+
+ATF_TC(fsync_sync);
+ATF_TC_HEAD(fsync_sync, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of fsync(2)");
+}
+
+ATF_TC_BODY(fsync_sync, tc)
+{
+ char buf[128];
+ int fd, i;
+
+ for (i = 0; i < 10; i++) {
+
+ (void)snprintf(buf, sizeof(buf), "t_fsync-%d", i);
+
+ fd = mkstemp(buf);
+
+ ATF_REQUIRE(fd != -1);
+ ATF_REQUIRE(write(fd, "0", 1) == 1);
+ ATF_REQUIRE(fsync(fd) == 0);
+
+ ATF_REQUIRE(unlink(buf) == 0);
+ ATF_REQUIRE(close(fd) == 0);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fsync_err);
+ ATF_TP_ADD_TC(tp, fsync_sync);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c
new file mode 100644
index 0000000..46c0ff1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c
@@ -0,0 +1,139 @@
+/* $NetBSD: t_getcontext.c,v 1.3 2011/07/14 04:59:14 jruoho Exp $ */
+
+/*-
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_getcontext.c,v 1.3 2011/07/14 04:59:14 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <ucontext.h>
+
+#define STACKSZ (10*1024)
+#define DEPTH 3
+
+static int calls;
+
+static void
+run(int n, ...)
+{
+ va_list va;
+ int i, ia;
+
+ ATF_REQUIRE_EQ(n, DEPTH - calls - 1);
+
+ va_start(va, n);
+#if defined(__FreeBSD__) && defined(__amd64__)
+ for (i = 0; i < 5; i++) {
+#else
+ for (i = 0; i < 9; i++) {
+#endif
+ ia = va_arg(va, int);
+ ATF_REQUIRE_EQ(i, ia);
+ }
+ va_end(va);
+
+ calls++;
+}
+
+ATF_TC(getcontext_err);
+ATF_TC_HEAD(getcontext_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from getcontext(2)");
+}
+
+ATF_TC_BODY(getcontext_err, tc)
+{
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, getcontext((void *)-1) == -1);
+}
+
+ATF_TC(setcontext_err);
+ATF_TC_HEAD(setcontext_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from setcontext(2)");
+}
+
+ATF_TC_BODY(setcontext_err, tc)
+{
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, setcontext((void *)-1) == -1);
+}
+
+ATF_TC(setcontext_link);
+ATF_TC_HEAD(setcontext_link, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks get/make/setcontext(), context linking via uc_link(), "
+ "and argument passing to the new context");
+}
+
+ATF_TC_BODY(setcontext_link, tc)
+{
+ ucontext_t uc[DEPTH];
+ ucontext_t save;
+ volatile int i = 0; /* avoid longjmp clobbering */
+
+ for (i = 0; i < DEPTH; ++i) {
+ ATF_REQUIRE_EQ(getcontext(&uc[i]), 0);
+
+ uc[i].uc_stack.ss_sp = malloc(STACKSZ);
+ uc[i].uc_stack.ss_size = STACKSZ;
+ uc[i].uc_link = (i > 0) ? &uc[i - 1] : &save;
+
+#if defined(__FreeBSD__) && defined(__amd64__)
+ /* FreeBSD/amd64 only permits up to 6 arguments. */
+ makecontext(&uc[i], (void *)run, 6, i,
+ 0, 1, 2, 3, 4);
+#else
+ makecontext(&uc[i], (void *)run, 10, i,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8);
+#endif
+ }
+
+ ATF_REQUIRE_EQ(getcontext(&save), 0);
+
+ if (calls == 0)
+ ATF_REQUIRE_EQ(setcontext(&uc[DEPTH-1]), 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getcontext_err);
+ ATF_TP_ADD_TC(tp, setcontext_err);
+ ATF_TP_ADD_TC(tp, setcontext_link);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c
new file mode 100644
index 0000000..7dedca4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c
@@ -0,0 +1,174 @@
+/* $NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+ATF_TC(getgroups_err);
+ATF_TC_HEAD(getgroups_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors in getgroups(2)");
+}
+
+ATF_TC_BODY(getgroups_err, tc)
+{
+ gid_t gidset[NGROUPS_MAX];
+
+ errno = 0;
+
+ ATF_REQUIRE(getgroups(10, (gid_t *)-1) == -1);
+ ATF_REQUIRE(errno == EFAULT);
+
+ errno = 0;
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("Reported as kern/189941");
+#endif
+ ATF_REQUIRE(getgroups(-1, gidset) == -1);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+ATF_TC(getgroups_getgid);
+ATF_TC_HEAD(getgroups_getgid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test getgid(2) from getgroups(2)");
+}
+
+ATF_TC_BODY(getgroups_getgid, tc)
+{
+ gid_t gidset[NGROUPS_MAX];
+ gid_t gid = getgid();
+ int i, n;
+
+ /*
+ * Check that getgid(2) is found from
+ * the GIDs returned by getgroups(2).
+ */
+ n = getgroups(NGROUPS_MAX, gidset);
+
+ for (i = 0; i < n; i++) {
+
+ if (gidset[i] == gid)
+ return;
+ }
+
+ atf_tc_fail("getgid(2) not found from getgroups(2)");
+}
+
+ATF_TC(getgroups_setgid);
+ATF_TC_HEAD(getgroups_setgid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setgid(2) from getgroups(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(getgroups_setgid, tc)
+{
+ gid_t gidset[NGROUPS_MAX];
+ int i, n, rv, sta;
+ pid_t pid;
+
+ /*
+ * Check that we can setgid(2)
+ * to the returned group IDs.
+ */
+ n = getgroups(NGROUPS_MAX, gidset);
+ ATF_REQUIRE(n >= 0);
+
+ for (i = 0; i < n; i++) {
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ rv = setgid(gidset[i]);
+
+ if (rv != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("getgroups(2) is inconsistent");
+ }
+}
+
+ATF_TC(getgroups_zero);
+ATF_TC_HEAD(getgroups_zero, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test getgroups(2) with zero param");
+}
+
+ATF_TC_BODY(getgroups_zero, tc)
+{
+ const gid_t val = 123456789;
+ gid_t gidset[NGROUPS_MAX];
+ size_t i;
+
+ /*
+ * If the first parameter is zero, the number
+ * of groups should be returned but the supplied
+ * buffer should remain intact.
+ */
+ for (i = 0; i < __arraycount(gidset); i++)
+ gidset[i] = val;
+
+ ATF_REQUIRE(getgroups(0, gidset) >= 0);
+
+ for (i = 0; i < __arraycount(gidset); i++) {
+
+ if (gidset[i] != val)
+ atf_tc_fail("getgroups(2) modified the buffer");
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getgroups_err);
+ ATF_TP_ADD_TC(tp, getgroups_getgid);
+ ATF_TP_ADD_TC(tp, getgroups_setgid);
+ ATF_TP_ADD_TC(tp, getgroups_zero);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c b/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c
new file mode 100644
index 0000000..0e4e7b6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c
@@ -0,0 +1,216 @@
+/* $NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $");
+
+#include <sys/time.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+static bool fail;
+static void sighandler(int);
+
+static void
+sighandler(int signo)
+{
+
+ if (signo == SIGALRM || signo == SIGVTALRM)
+ fail = false;
+}
+
+ATF_TC(getitimer_empty);
+ATF_TC_HEAD(getitimer_empty, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "getitimer(2) before setitimer(2)");
+}
+
+ATF_TC_BODY(getitimer_empty, tc)
+{
+ struct itimerval it;
+
+ /*
+ * Verify that the passed structure remains
+ * empty after calling getitimer(2) but before
+ * actually arming the timer with setitimer(2).
+ */
+ (void)memset(&it, 0, sizeof(struct itimerval));
+
+ ATF_REQUIRE(getitimer(ITIMER_REAL, &it) == 0);
+
+ if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0)
+ goto fail;
+
+ ATF_REQUIRE(getitimer(ITIMER_VIRTUAL, &it) == 0);
+
+ if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0)
+ goto fail;
+
+ ATF_REQUIRE(getitimer(ITIMER_PROF, &it) == 0);
+
+ if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0)
+ goto fail;
+
+ return;
+
+fail:
+ atf_tc_fail("getitimer(2) modfied the timer before it was armed");
+}
+
+ATF_TC(getitimer_err);
+ATF_TC_HEAD(getitimer_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from getitimer(2)");
+}
+
+ATF_TC_BODY(getitimer_err, tc)
+{
+ struct itimerval it;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, getitimer(-1, &it) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, getitimer(INT_MAX, &it) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, getitimer(ITIMER_REAL, (void *)-1) == -1);
+}
+
+ATF_TC(setitimer_basic);
+ATF_TC_HEAD(setitimer_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of setitimer(2)");
+}
+
+ATF_TC_BODY(setitimer_basic, tc)
+{
+ struct itimerval it;
+
+ it.it_value.tv_sec = 0;
+ it.it_value.tv_usec = 100;
+
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_usec = 0;
+
+ fail = true;
+
+ ATF_REQUIRE(signal(SIGALRM, sighandler) != SIG_ERR);
+ ATF_REQUIRE(setitimer(ITIMER_REAL, &it, NULL) == 0);
+
+ /*
+ * Although the interaction between
+ * setitimer(2) and sleep(3) can be
+ * unspecified, it is assumed that one
+ * second suspension will be enough for
+ * the timer to fire.
+ */
+ (void)sleep(1);
+
+ if (fail != false)
+ atf_tc_fail("timer did not fire");
+}
+
+ATF_TC(setitimer_err);
+ATF_TC_HEAD(setitimer_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from setitimer(2)"
+ " (PR standards/44927)");
+}
+
+ATF_TC_BODY(setitimer_err, tc)
+{
+ struct itimerval it, ot;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, setitimer(-1, &it, &ot) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, setitimer(INT_MAX, &it, &ot) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, setitimer(ITIMER_REAL,(void*)-1, &ot) == -1);
+}
+
+ATF_TC(setitimer_old);
+ATF_TC_HEAD(setitimer_old, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test old values from setitimer(2)");
+}
+
+ATF_TC_BODY(setitimer_old, tc)
+{
+ struct itimerval it, ot;
+
+ /*
+ * Make two calls; the second one
+ * should store the old values.
+ */
+ it.it_value.tv_sec = 4;
+ it.it_value.tv_usec = 3;
+
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_usec = 0;
+
+ ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0);
+
+ it.it_value.tv_sec = 2;
+ it.it_value.tv_usec = 1;
+
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_usec = 0;
+
+ ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0);
+
+#ifdef __FreeBSD__
+ if (ot.it_value.tv_sec == 4 && ot.it_value.tv_usec == 3)
+ atf_tc_fail("setitimer(2) did not return remaining time");
+#else
+ if (ot.it_value.tv_sec != 4 || ot.it_value.tv_usec != 3)
+ atf_tc_fail("setitimer(2) did not store old values");
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getitimer_empty);
+ ATF_TP_ADD_TC(tp, getitimer_err);
+ ATF_TP_ADD_TC(tp, setitimer_basic);
+ ATF_TP_ADD_TC(tp, setitimer_err);
+ ATF_TP_ADD_TC(tp, setitimer_old);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c b/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c
new file mode 100644
index 0000000..8c2b199
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c
@@ -0,0 +1,237 @@
+/* $NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_getlogin.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <sys/param.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+ATF_TC(getlogin_r_err);
+ATF_TC_HEAD(getlogin_r_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from getlogin_r(2)");
+}
+
+ATF_TC_BODY(getlogin_r_err, tc)
+{
+ char small[0];
+
+ ATF_REQUIRE(getlogin_r(small, sizeof(small)) == ERANGE);
+}
+
+ATF_TC(getlogin_same);
+ATF_TC_HEAD(getlogin_same, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "getlogin(2) vs. getlogin_r(2)");
+}
+
+ATF_TC_BODY(getlogin_same, tc)
+{
+ char buf[MAXLOGNAME];
+ char *str;
+
+ str = getlogin();
+
+ if (str == NULL)
+ return;
+
+ ATF_REQUIRE(getlogin_r(buf, sizeof(buf)) == 0);
+
+ if (strcmp(str, buf) != 0)
+ atf_tc_fail("getlogin(2) and getlogin_r(2) differ");
+}
+
+ATF_TC(setlogin_basic);
+ATF_TC_HEAD(setlogin_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that setlogin(2) works");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(setlogin_basic, tc)
+{
+ char *name;
+ pid_t pid;
+ int sta;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ (void)setsid();
+
+ if (setlogin("foobar") != 0)
+ _exit(EXIT_FAILURE);
+
+ name = getlogin();
+
+ if (name == NULL)
+ _exit(EXIT_FAILURE);
+
+ if (strcmp(name, "foobar") != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("setlogin(2) failed to set login name");
+}
+
+ATF_TC(setlogin_err);
+ATF_TC_HEAD(setlogin_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from setlogin(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(setlogin_err, tc)
+{
+ char buf[MAXLOGNAME + 1];
+ char *name;
+ pid_t pid;
+ int sta;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ if (pid == 0) {
+
+ (void)setsid();
+
+ errno = 0;
+
+ if (setlogin(buf) != -1)
+ _exit(EINVAL);
+
+ if (errno != EINVAL)
+ _exit(EINVAL);
+
+ errno = 0;
+
+ if (setlogin((void *)-1) != -1)
+ _exit(EFAULT);
+
+ if (errno != EFAULT)
+ _exit(EFAULT);
+
+ name = getlogin();
+
+ if (name == NULL)
+ _exit(EXIT_FAILURE);
+
+ if (strcmp(name, "foobar") == 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
+
+ if (WEXITSTATUS(sta) == EFAULT)
+ atf_tc_fail("expected EFAULT, but the call succeeded");
+
+ if (WEXITSTATUS(sta) == EINVAL)
+ atf_tc_fail("expected EINVAL, but the call succeeded");
+
+ atf_tc_fail("setlogin(2) failed, but login name was set");
+ }
+}
+
+ATF_TC(setlogin_perm);
+ATF_TC_HEAD(setlogin_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setlogin(2) as normal user");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(setlogin_perm, tc)
+{
+ char *name;
+ pid_t pid;
+ int sta;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ (void)setsid();
+
+ errno = 0;
+
+ if (setlogin("foobar") != -1)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EPERM)
+ _exit(EXIT_FAILURE);
+
+ name = getlogin();
+
+ if (name == NULL)
+ _exit(EXIT_FAILURE);
+
+ if (strcmp(name, "foobar") == 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("login name was set as an unprivileged user");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getlogin_r_err);
+ ATF_TP_ADD_TC(tp, getlogin_same);
+ ATF_TP_ADD_TC(tp, setlogin_basic);
+ ATF_TP_ADD_TC(tp, setlogin_err);
+ ATF_TP_ADD_TC(tp, setlogin_perm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getpid.c b/contrib/netbsd-tests/lib/libc/sys/t_getpid.c
new file mode 100644
index 0000000..b3ed393
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getpid.c
@@ -0,0 +1,134 @@
+/* $NetBSD: t_getpid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_getpid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+static int maxiter = 10;
+static void *threadfunc(void *);
+
+static void *
+threadfunc(void *arg)
+{
+ *(pid_t *)arg = getpid();
+
+ return NULL;
+}
+
+ATF_TC(getpid_process);
+ATF_TC_HEAD(getpid_process, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test getpid(2) with processes");
+}
+
+ATF_TC_BODY(getpid_process, tc)
+{
+ pid_t ppid, fpid, cpid, tpid, wpid;
+ int i, sta;
+
+ for (i = 0; i < maxiter; i++) {
+
+ tpid = getpid();
+ fpid = fork();
+
+ ATF_REQUIRE(fpid >= 0);
+
+ if (fpid == 0) {
+
+ cpid = getpid();
+ ppid = getppid();
+
+ if (tpid != ppid)
+ _exit(EXIT_FAILURE);
+
+ if (cpid == ppid)
+ _exit(EXIT_FAILURE);
+
+ if (tpid == fpid)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ wpid = wait(&sta);
+
+ if (wpid != fpid)
+ atf_tc_fail("PID mismatch");
+
+ ATF_REQUIRE(WIFEXITED(sta) != 0);
+
+ if (WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("PID mismatch");
+ }
+}
+
+ATF_TC(getpid_thread);
+ATF_TC_HEAD(getpid_thread, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test getpid(2) with threads");
+}
+
+ATF_TC_BODY(getpid_thread, tc)
+{
+ pid_t pid, tpid;
+ pthread_t tid;
+ int i, rv;
+
+ for (i = 0; i < maxiter; i++) {
+
+ pid = getpid();
+
+ rv = pthread_create(&tid, NULL, threadfunc, &tpid);
+ ATF_REQUIRE(rv == 0);
+
+ rv = pthread_join(tid, NULL);
+ ATF_REQUIRE(rv == 0);
+
+ if (pid != tpid)
+ atf_tc_fail("Unequal PIDs");
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getpid_process);
+ ATF_TP_ADD_TC(tp, getpid_thread);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c
new file mode 100644
index 0000000..85eeac6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c
@@ -0,0 +1,210 @@
+/* $NetBSD: t_getrusage.c,v 1.3 2014/09/03 19:24:12 matt Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_getrusage.c,v 1.3 2014/09/03 19:24:12 matt Exp $");
+
+#include <sys/resource.h>
+#include <sys/time.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdint.h>
+#include <string.h>
+
+static void work(void);
+static void sighandler(int);
+
+static const size_t maxiter = 2000;
+
+static void
+#ifdef __FreeBSD__
+sighandler(int signo __unused)
+#else
+sighandler(int signo)
+#endif
+{
+ /* Nothing. */
+}
+
+static void
+work(void)
+{
+ size_t n = UINT16_MAX * 10;
+
+ while (n > 0) {
+#ifdef __or1k__
+ asm volatile("l.nop"); /* Do something. */
+#else
+ asm volatile("nop"); /* Do something. */
+#endif
+ n--;
+ }
+}
+
+ATF_TC(getrusage_err);
+ATF_TC_HEAD(getrusage_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions");
+}
+
+ATF_TC_BODY(getrusage_err, tc)
+{
+ struct rusage ru;
+
+ errno = 0;
+
+ ATF_REQUIRE(getrusage(INT_MAX, &ru) != 0);
+ ATF_REQUIRE(errno == EINVAL);
+
+ errno = 0;
+
+ ATF_REQUIRE(getrusage(RUSAGE_SELF, (void *)0) != 0);
+ ATF_REQUIRE(errno == EFAULT);
+}
+
+ATF_TC(getrusage_sig);
+ATF_TC_HEAD(getrusage_sig, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test signal count with getrusage(2)");
+}
+
+ATF_TC_BODY(getrusage_sig, tc)
+{
+ struct rusage ru;
+ const long n = 5;
+ int i;
+
+ /*
+ * Test that signals are recorded.
+ */
+ ATF_REQUIRE(signal(SIGUSR1, sighandler) != SIG_ERR);
+
+ for (i = 0; i < n; i++)
+ ATF_REQUIRE(raise(SIGUSR1) == 0);
+
+ (void)memset(&ru, 0, sizeof(struct rusage));
+ ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0);
+
+ if (n != ru.ru_nsignals)
+ atf_tc_fail("getrusage(2) did not record signals");
+}
+
+ATF_TC(getrusage_utime_back);
+ATF_TC_HEAD(getrusage_utime_back, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test bogus values from getrusage(2)");
+}
+
+ATF_TC_BODY(getrusage_utime_back, tc)
+{
+ struct rusage ru1, ru2;
+ size_t i;
+
+ /*
+ * Test that two consecutive calls are sane.
+ */
+#ifdef __NetBSD__
+ atf_tc_expect_fail("PR kern/30115");
+#endif
+
+ for (i = 0; i < maxiter; i++) {
+
+ (void)memset(&ru1, 0, sizeof(struct rusage));
+ (void)memset(&ru2, 0, sizeof(struct rusage));
+
+ work();
+
+ ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru1) == 0);
+
+ work();
+
+ ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru2) == 0);
+
+ if (timercmp(&ru2.ru_utime, &ru1.ru_utime, <) != 0)
+ atf_tc_fail("user time went backwards");
+ }
+
+#ifdef __NetBSD__
+ atf_tc_fail("anticipated error did not occur");
+#endif
+}
+
+ATF_TC(getrusage_utime_zero);
+ATF_TC_HEAD(getrusage_utime_zero, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test zero utime from getrusage(2)");
+}
+
+ATF_TC_BODY(getrusage_utime_zero, tc)
+{
+ struct rusage ru;
+ size_t i;
+
+#ifdef __FreeBSD__
+ atf_tc_skip("this testcase passes/fails sporadically on FreeBSD/i386 "
+ "@ r273153 (at least)");
+#endif
+
+ /*
+ * Test that getrusage(2) does not return
+ * zero user time for the calling process.
+ *
+ * See also (duplicate) PR port-amd64/41734.
+ */
+ atf_tc_expect_fail("PR kern/30115");
+
+ for (i = 0; i < maxiter; i++) {
+
+ work();
+
+ (void)memset(&ru, 0, sizeof(struct rusage));
+
+ ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0);
+
+ if (ru.ru_utime.tv_sec == 0 && ru.ru_utime.tv_usec == 0)
+ atf_tc_fail("zero user time from getrusage(2)");
+ }
+
+ atf_tc_fail("anticipated error did not occur");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getrusage_err);
+ ATF_TP_ADD_TC(tp, getrusage_sig);
+ ATF_TP_ADD_TC(tp, getrusage_utime_back);
+ ATF_TP_ADD_TC(tp, getrusage_utime_zero);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getsid.c b/contrib/netbsd-tests/lib/libc/sys/t_getsid.c
new file mode 100644
index 0000000..76b54ab
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getsid.c
@@ -0,0 +1,119 @@
+/* $NetBSD: t_getsid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_getsid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+ATF_TC(getsid_current);
+ATF_TC_HEAD(getsid_current, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test getsid(0)");
+}
+
+ATF_TC_BODY(getsid_current, tc)
+{
+ pid_t sid;
+
+ sid = getsid(0);
+ ATF_REQUIRE(sid != -1);
+
+ if (sid != getsid(getpid()))
+ atf_tc_fail("getsid(0) did not match the calling process");
+}
+
+ATF_TC(getsid_err);
+ATF_TC_HEAD(getsid_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions in getsid(2)");
+}
+
+ATF_TC_BODY(getsid_err, tc)
+{
+
+ errno = 0;
+
+ ATF_REQUIRE(getsid(-1) == -1);
+ ATF_REQUIRE(errno == ESRCH);
+}
+
+ATF_TC(getsid_process);
+ATF_TC_HEAD(getsid_process, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test getsid(2) with processes");
+}
+
+ATF_TC_BODY(getsid_process, tc)
+{
+ pid_t csid, pid, ppid, sid;
+ int sta;
+
+ sid = getsid(0);
+ pid = fork();
+
+ ATF_REQUIRE(pid >= 0);
+ ATF_REQUIRE(sid != -1);
+
+ if (pid == 0) {
+
+ csid = getsid(0);
+ ppid = getppid();
+
+ if (sid != csid)
+ _exit(EXIT_FAILURE);
+
+ if (getsid(ppid) != csid)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("invalid session ID");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getsid_current);
+ ATF_TP_ADD_TC(tp, getsid_err);
+ ATF_TP_ADD_TC(tp, getsid_process);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c b/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c
new file mode 100644
index 0000000..1cf303b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c
@@ -0,0 +1,86 @@
+/* $NetBSD: t_gettimeofday.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_gettimeofday.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <sys/time.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <string.h>
+
+ATF_TC(gettimeofday_err);
+ATF_TC_HEAD(gettimeofday_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from gettimeofday(2)");
+}
+
+ATF_TC_BODY(gettimeofday_err, tc)
+{
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EFAULT, gettimeofday((void *)-1, NULL) != 0);
+}
+
+ATF_TC(gettimeofday_mono);
+ATF_TC_HEAD(gettimeofday_mono, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test monotonicity of gettimeofday(2)");
+}
+
+ATF_TC_BODY(gettimeofday_mono, tc)
+{
+ static const size_t maxiter = 100;
+ struct timeval tv1, tv2;
+ size_t i;
+
+ for (i = 0; i < maxiter; i++) {
+
+ (void)memset(&tv1, 0, sizeof(struct timeval));
+ (void)memset(&tv2, 0, sizeof(struct timeval));
+
+ ATF_REQUIRE(gettimeofday(&tv1, NULL) == 0);
+ ATF_REQUIRE(gettimeofday(&tv2, NULL) == 0);
+
+ if (timercmp(&tv2, &tv1, <) != 0)
+ atf_tc_fail("time went backwards");
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, gettimeofday_err);
+ ATF_TP_ADD_TC(tp, gettimeofday_mono);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c b/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c
new file mode 100644
index 0000000..b76ba39
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_issetugid.c
@@ -0,0 +1,148 @@
+/* $NetBSD: t_issetugid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_issetugid.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static bool check(int (*fuid)(uid_t), int (*fgid)(gid_t));
+
+static bool
+check(int (*fuid)(uid_t), int (*fgid)(gid_t))
+{
+ struct passwd *pw;
+ pid_t pid;
+ int sta;
+
+ pw = getpwnam("nobody");
+
+ if (pw == NULL)
+ return false;
+
+ pid = fork();
+
+ if (pid < 0)
+ return false;
+
+ if (pid == 0) {
+
+ if (fuid != NULL && (*fuid)(pw->pw_uid) != 0)
+ _exit(EXIT_FAILURE);
+
+ if (fgid != NULL && (*fgid)(pw->pw_gid) != 0)
+ _exit(EXIT_FAILURE);
+
+ if (issetugid() != 1)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ return false;
+
+ return true;
+}
+
+ATF_TC(issetugid_egid);
+ATF_TC_HEAD(issetugid_egid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), eff. GID");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(issetugid_egid, tc)
+{
+
+ if (check(NULL, setegid) != true)
+ atf_tc_fail("issetugid(2) failed with effective GID");
+}
+
+ATF_TC(issetugid_euid);
+ATF_TC_HEAD(issetugid_euid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), eff. UID");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(issetugid_euid, tc)
+{
+
+ if (check(seteuid, NULL) != true)
+ atf_tc_fail("issetugid(2) failed with effective UID");
+}
+
+ATF_TC(issetugid_rgid);
+ATF_TC_HEAD(issetugid_rgid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), real GID");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(issetugid_rgid, tc)
+{
+
+ if (check(NULL, setgid) != true)
+ atf_tc_fail("issetugid(2) failed with real GID");
+}
+
+ATF_TC(issetugid_ruid);
+ATF_TC_HEAD(issetugid_ruid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A test of issetugid(2), real UID");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(issetugid_ruid, tc)
+{
+
+ if (check(setuid, NULL) != true)
+ atf_tc_fail("issetugid(2) failed with real UID");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, issetugid_egid);
+ ATF_TP_ADD_TC(tp, issetugid_euid);
+ ATF_TP_ADD_TC(tp, issetugid_rgid);
+ ATF_TP_ADD_TC(tp, issetugid_ruid);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_kevent.c b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c
new file mode 100644
index 0000000..fe298c5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c
@@ -0,0 +1,206 @@
+/* $NetBSD: t_kevent.c,v 1.6 2012/11/29 09:13:44 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundatiom
+ * by Christos Zoulas.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_kevent.c,v 1.6 2012/11/29 09:13:44 martin Exp $");
+
+#include <sys/types.h>
+#include <sys/event.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <err.h>
+#ifdef __NetBSD__
+#include <sys/drvctlio.h>
+#endif
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#ifdef __FreeBSD__
+#define DRVCTLDEV "/nonexistent"
+#endif
+
+ATF_TC(kevent_zerotimer);
+ATF_TC_HEAD(kevent_zerotimer, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that kevent with a 0 timer "
+ "does not crash the system (PR lib/45618)");
+}
+
+ATF_TC_BODY(kevent_zerotimer, tc)
+{
+ struct kevent ev;
+ int kq;
+
+ ATF_REQUIRE((kq = kqueue()) != -1);
+ EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0);
+ ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) != -1);
+ ATF_REQUIRE(kevent(kq, NULL, 0, &ev, 1, NULL) == 1);
+}
+
+ATF_TC(kqueue_desc_passing);
+ATF_TC_HEAD(kqueue_desc_passing, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that passing a kqueue to "
+ "another process does not crash the kernel (PR 46463)");
+}
+
+ATF_TC_BODY(kqueue_desc_passing, tc)
+{
+ pid_t child;
+ int s[2], storage, status, kq;
+ struct cmsghdr *msg;
+ struct iovec iov;
+ struct msghdr m;
+ struct kevent ev;
+
+ ATF_REQUIRE((kq = kqueue()) != -1);
+
+ // atf_tc_skip("crashes kernel (PR 46463)");
+
+ ATF_REQUIRE(socketpair(AF_LOCAL, SOCK_STREAM, 0, s) != -1);
+ msg = malloc(CMSG_SPACE(sizeof(int)));
+ m.msg_iov = &iov;
+ m.msg_iovlen = 1;
+ m.msg_name = NULL;
+ m.msg_namelen = 0;
+ m.msg_control = msg;
+ m.msg_controllen = CMSG_SPACE(sizeof(int));
+
+ child = fork();
+ if (child == 0) {
+ close(s[0]);
+
+ iov.iov_base = &storage;
+ iov.iov_len = sizeof(int);
+ m.msg_iov = &iov;
+ m.msg_iovlen = 1;
+
+ if (recvmsg(s[1], &m, 0) == -1)
+ err(1, "child: could not recvmsg");
+
+#ifdef __FreeBSD__
+ bcopy(CMSG_DATA(msg), &kq, sizeof(kq));
+ printf("child (pid %d): received kq fd %d\n", getpid(), kq);
+ _exit(0);
+#else
+ kq = *(int *)CMSG_DATA(msg);
+ printf("child (pid %d): received kq fd %d\n", getpid(), kq);
+ exit(0);
+#endif
+ }
+
+ close(s[1]);
+
+ iov.iov_base = &storage;
+ iov.iov_len = sizeof(int);
+
+ msg->cmsg_level = SOL_SOCKET;
+ msg->cmsg_type = SCM_RIGHTS;
+ msg->cmsg_len = CMSG_LEN(sizeof(int));
+
+#ifdef __FreeBSD__
+ /*
+ * What is should have been
+ * bcopy(&s[0], CMSG_DATA(msg), sizeof(kq));
+ */
+ bcopy(&kq, CMSG_DATA(msg), sizeof(kq));
+#else
+ *(int *)CMSG_DATA(msg) = kq;
+#endif
+
+ EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0);
+ ATF_CHECK(kevent(kq, &ev, 1, NULL, 0, NULL) != -1);
+
+ printf("parent (pid %d): sending kq fd %d\n", getpid(), kq);
+ if (sendmsg(s[0], &m, 0) == -1) {
+#ifdef __NetBSD__
+ ATF_REQUIRE_EQ_MSG(errno, EBADF, "errno is %d", errno);
+ atf_tc_skip("PR kern/46523");
+#endif
+#ifdef __FreeBSD__
+ ATF_REQUIRE_EQ_MSG(errno, EOPNOTSUPP, "errno is %d", errno);
+ close(s[0]);
+#endif
+ }
+
+ close(kq);
+
+ waitpid(child, &status, 0);
+ ATF_CHECK(WIFEXITED(status) && WEXITSTATUS(status)==0);
+}
+
+ATF_TC(kqueue_unsupported_fd);
+ATF_TC_HEAD(kqueue_unsupported_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that watching an fd whose"
+ " type is not supported does not crash the kernel");
+}
+
+ATF_TC_BODY(kqueue_unsupported_fd, tc)
+{
+ /* mqueue and semaphore use fnullop_kqueue also */
+ int fd, kq;
+ struct kevent ev;
+
+ fd = open(DRVCTLDEV, O_RDONLY);
+ if (fd == -1 && errno == ENOENT)
+ atf_tc_skip("no " DRVCTLDEV " available for testing");
+ ATF_REQUIRE(fd != -1);
+ ATF_REQUIRE((kq = kqueue()) != -1);
+
+ EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
+ NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|
+ NOTE_RENAME|NOTE_REVOKE, 0, 0);
+
+ ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) == -1);
+ ATF_REQUIRE_ERRNO(EOPNOTSUPP, true);
+
+ (void)close(fd);
+}
+
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, kevent_zerotimer);
+ ATF_TP_ADD_TC(tp, kqueue_desc_passing);
+ ATF_TP_ADD_TC(tp, kqueue_unsupported_fd);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_kill.c b/contrib/netbsd-tests/lib/libc/sys/t_kill.c
new file mode 100644
index 0000000..2f42862
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_kill.c
@@ -0,0 +1,312 @@
+/* $NetBSD: t_kill.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_kill.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+ATF_TC(kill_basic);
+ATF_TC_HEAD(kill_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that kill(2) works");
+}
+
+ATF_TC_BODY(kill_basic, tc)
+{
+ const int sig[] = { SIGHUP, SIGINT, SIGKILL, SIGTERM };
+ pid_t pid;
+ size_t i;
+ int sta;
+
+ for (i = 0; i < __arraycount(sig); i++) {
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ switch (pid) {
+
+ case 0:
+ pause();
+ break;
+
+ default:
+ ATF_REQUIRE(kill(pid, sig[i]) == 0);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != sig[i])
+ atf_tc_fail("kill(2) failed to kill child");
+ }
+}
+
+ATF_TC(kill_err);
+ATF_TC_HEAD(kill_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of kill(2)");
+}
+
+ATF_TC_BODY(kill_err, tc)
+{
+ int rv, sta;
+ pid_t pid;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ errno = 0;
+ rv = kill(getpid(), -1);
+
+ if (rv == 0 || errno != EINVAL)
+ _exit(EINVAL);
+
+ errno = 0;
+ rv = kill(INT_MAX, SIGUSR1);
+
+ if (rv == 0 || errno != ESRCH)
+ _exit(ESRCH);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
+
+ if (WEXITSTATUS(sta) == EINVAL)
+ atf_tc_fail("expected EINVAL, but kill(2) succeeded");
+
+ if (WEXITSTATUS(sta) == ESRCH)
+ atf_tc_fail("expected ESRCH, but kill(2) succeeded");
+
+ atf_tc_fail("unknown error from kill(2)");
+ }
+}
+
+ATF_TC(kill_perm);
+ATF_TC_HEAD(kill_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test kill(2) permissions");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(kill_perm, tc)
+{
+ struct passwd *pw;
+ pid_t cpid, ppid;
+ uid_t cuid = 0;
+ uid_t puid = 0;
+ int sta;
+
+ /*
+ * Test that kill(2) fails when called
+ * for a PID owned by another user.
+ */
+ pw = getpwnam("operator");
+
+ if (pw != NULL)
+ cuid = pw->pw_uid;
+
+ pw = getpwnam("nobody");
+
+ if (pw != NULL)
+ puid = pw->pw_uid;
+
+ if (cuid == 0 || puid == 0 || cuid == puid)
+ atf_tc_fail("getpwnam(3) failed");
+
+ ppid = fork();
+
+ if (ppid < 0)
+ _exit(EXIT_FAILURE);
+
+ if (ppid == 0) {
+
+ cpid = fork();
+
+ if (cpid < 0)
+ _exit(EXIT_FAILURE);
+
+ if (cpid == 0) {
+
+ if (setuid(cuid) < 0)
+ _exit(EXIT_FAILURE);
+ else {
+ (void)sleep(1);
+ }
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ /*
+ * Try to kill the child after having
+ * set the real and effective UID.
+ */
+ if (setuid(puid) != 0)
+ _exit(EXIT_FAILURE);
+
+ errno = 0;
+
+ if (kill(cpid, SIGKILL) == 0)
+ _exit(EPERM);
+
+ if (errno != EPERM)
+ _exit(EPERM);
+
+ (void)waitpid(cpid, &sta, 0);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)waitpid(ppid, &sta, 0);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) == EPERM)
+ atf_tc_fail("killed a process of another user");
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("unknown error from kill(2)");
+}
+
+ATF_TC(kill_pgrp_neg);
+ATF_TC_HEAD(kill_pgrp_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test kill(2) with process group, #2");
+}
+
+ATF_TC_BODY(kill_pgrp_neg, tc)
+{
+ const int maxiter = 3;
+ pid_t cpid, ppid;
+ int i, sta;
+
+ ppid = fork();
+ ATF_REQUIRE(ppid >= 0);
+
+ if (ppid == 0) {
+
+ ATF_REQUIRE(setpgid(0, 0) == 0);
+
+ for (i = 0; i < maxiter; i++) {
+
+ cpid = fork();
+ ATF_REQUIRE(cpid >= 0);
+
+ if (cpid == 0)
+ pause();
+ }
+
+ /*
+ * Test the variant of killpg(3); if the process number
+ * is negative but not -1, the signal should be sent to
+ * all processes whose process group ID is equal to the
+ * absolute value of the process number.
+ */
+ ATF_REQUIRE(kill(-getpgrp(), SIGKILL) == 0);
+
+ (void)sleep(1);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)waitpid(ppid, &sta, 0);
+
+ if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL)
+ atf_tc_fail("failed to kill(2) a process group");
+}
+
+ATF_TC(kill_pgrp_zero);
+ATF_TC_HEAD(kill_pgrp_zero, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test kill(2) with process group, #1");
+}
+
+ATF_TC_BODY(kill_pgrp_zero, tc)
+{
+ const int maxiter = 3;
+ pid_t cpid, ppid;
+ int i, sta;
+
+ ppid = fork();
+ ATF_REQUIRE(ppid >= 0);
+
+ if (ppid == 0) {
+
+ ATF_REQUIRE(setpgid(0, 0) == 0);
+
+ for (i = 0; i < maxiter; i++) {
+
+ cpid = fork();
+ ATF_REQUIRE(cpid >= 0);
+
+ if (cpid == 0)
+ pause();
+ }
+
+ /*
+ * If the supplied process number is zero,
+ * the signal should be sent to all processes
+ * under the current process group.
+ */
+ ATF_REQUIRE(kill(0, SIGKILL) == 0);
+
+ (void)sleep(1);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)waitpid(ppid, &sta, 0);
+
+ if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL)
+ atf_tc_fail("failed to kill(2) a process group");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, kill_basic);
+ ATF_TP_ADD_TC(tp, kill_err);
+ ATF_TP_ADD_TC(tp, kill_perm);
+ ATF_TP_ADD_TC(tp, kill_pgrp_neg);
+ ATF_TP_ADD_TC(tp, kill_pgrp_zero);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_link.c b/contrib/netbsd-tests/lib/libc/sys/t_link.c
new file mode 100644
index 0000000..b8dcacc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_link.c
@@ -0,0 +1,233 @@
+/* $NetBSD: t_link.c,v 1.2 2014/04/21 14:39:36 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_link.c,v 1.2 2014/04/21 14:39:36 martin Exp $");
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+static const char *getpath(void);
+static char path[] = "link";
+static const char *pathl;
+
+static const char *
+getpath(void)
+{
+ static char buf[LINE_MAX];
+
+ (void)memset(buf, '\0', sizeof(buf));
+
+ if (getcwd(buf, sizeof(buf)) == NULL)
+ return NULL;
+
+ (void)strlcat(buf, path, sizeof(buf));
+ (void)strlcat(buf, ".link", sizeof(buf));
+
+ return buf;
+}
+
+ATF_TC_WITH_CLEANUP(link_count);
+ATF_TC_HEAD(link_count, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "link(2) counts are incremented?");
+}
+
+ATF_TC_BODY(link_count, tc)
+{
+ struct stat sa, sb;
+ int fd;
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ pathl = getpath();
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(pathl != NULL);
+
+ ATF_REQUIRE(stat(path, &sa) == 0);
+ ATF_REQUIRE(link(path, pathl) == 0);
+ ATF_REQUIRE(stat(path, &sb) == 0);
+
+ if (sa.st_nlink != sb.st_nlink - 1)
+ atf_tc_fail("incorrect link(2) count");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+ ATF_REQUIRE(unlink(pathl) == 0);
+}
+
+ATF_TC_CLEANUP(link_count, tc)
+{
+ (void)unlink(path);
+ (void)unlink(pathl);
+}
+
+ATF_TC_WITH_CLEANUP(link_err);
+ATF_TC_HEAD(link_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of link(2)");
+}
+
+ATF_TC_BODY(link_err, tc)
+{
+ char buf[MAXPATHLEN + 1];
+ int fd;
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ pathl = getpath();
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(pathl != NULL);
+
+ errno = 0;
+ ATF_REQUIRE(link(path, pathl) == 0);
+ ATF_REQUIRE_ERRNO(EEXIST, link(path, pathl) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, link(buf, "xxx") == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, link(path, "/d/c/b/a") == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", path) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", "/d/c/b/a") == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, link(path, (const char *)-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, link((const char *)-1, "xxx") == -1);
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+ ATF_REQUIRE(unlink(pathl) == 0);
+}
+
+ATF_TC_CLEANUP(link_err, tc)
+{
+ (void)unlink(path);
+ (void)unlink(pathl);
+}
+
+ATF_TC(link_perm);
+ATF_TC_HEAD(link_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with link(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(link_perm, tc)
+{
+ int rv;
+
+ errno = 0;
+ rv = link("/root", "/root.link");
+ ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM),
+ "link to a directory did not fail with EPERM or EACCESS; link() "
+ "returned %d, errno %d", rv, errno);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EACCES,
+ link("/root/.profile", "/root/.profile.link") == -1);
+}
+
+ATF_TC_WITH_CLEANUP(link_stat);
+ATF_TC_HEAD(link_stat, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check stat(2) of a linked file");
+}
+
+ATF_TC_BODY(link_stat, tc)
+{
+ struct stat sa, sb;
+ int fd;
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ pathl = getpath();
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(pathl != NULL);
+
+ ATF_REQUIRE(link(path, pathl) == 0);
+ ATF_REQUIRE(stat(path, &sa) == 0);
+ ATF_REQUIRE(lstat(pathl, &sb) == 0);
+
+ if (sa.st_uid != sb.st_uid)
+ atf_tc_fail("unequal UIDs");
+
+ if (sa.st_mode != sb.st_mode)
+ atf_tc_fail("unequal modes");
+
+ if (sa.st_ino != sb.st_ino)
+ atf_tc_fail("unequal inodes");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+ ATF_REQUIRE(unlink(pathl) == 0);
+}
+
+ATF_TC_CLEANUP(link_stat, tc)
+{
+ (void)unlink(path);
+ (void)unlink(pathl);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, link_count);
+ ATF_TP_ADD_TC(tp, link_err);
+ ATF_TP_ADD_TC(tp, link_perm);
+ ATF_TP_ADD_TC(tp, link_stat);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_listen.c b/contrib/netbsd-tests/lib/libc/sys/t_listen.c
new file mode 100644
index 0000000..d7c7d9e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_listen.c
@@ -0,0 +1,138 @@
+/* $NetBSD: t_listen.c,v 1.4 2012/03/18 07:00:52 jruoho Exp $ */
+/*
+ * 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.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#ifdef __FreeBSD__
+#include <sys/socket.h>
+#endif
+
+static const char *path = "listen";
+
+ATF_TC_WITH_CLEANUP(listen_err);
+ATF_TC_HEAD(listen_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks errors from listen(2) (PR standards/46150)");
+}
+
+ATF_TC_BODY(listen_err, tc)
+{
+ static const size_t siz = sizeof(struct sockaddr_in);
+ struct sockaddr_in sina, sinb;
+ int fda, fdb, fdc;
+
+ (void)memset(&sina, 0, sizeof(struct sockaddr_in));
+ (void)memset(&sinb, 0, sizeof(struct sockaddr_in));
+
+ sina.sin_family = AF_INET;
+ sina.sin_port = htons(31522);
+ sina.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ sinb.sin_family = AF_INET;
+ sinb.sin_port = htons(31522);
+ sinb.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ fda = socket(AF_INET, SOCK_STREAM, 0);
+ fdb = socket(AF_INET, SOCK_STREAM, 0);
+ fdc = open("listen", O_RDWR | O_CREAT, 0600);
+
+ ATF_REQUIRE(fda >= 0 && fdb >= 0 && fdc >= 0);
+ ATF_REQUIRE_ERRNO(ENOTSOCK, listen(fdc, 1) == -1);
+
+ (void)close(fdc);
+ (void)unlink(path);
+
+ ATF_REQUIRE(bind(fda, (struct sockaddr *)&sina, siz) == 0);
+ ATF_REQUIRE(listen(fda, 1) == 0);
+
+ /*
+ * According to IEEE Std 1003.1-2008: if the socket is
+ * already connected, the call should fail with EINVAL.
+ */
+ ATF_REQUIRE(connect(fdb, (struct sockaddr *)&sinb, siz) == 0);
+ ATF_REQUIRE_ERRNO(EINVAL, listen(fdb, 1) == -1);
+
+ (void)close(fda);
+ (void)close(fdb);
+
+ ATF_REQUIRE_ERRNO(EBADF, connect(fdb,
+ (struct sockaddr *)&sinb, siz) == -1);
+}
+
+ATF_TC_CLEANUP(listen_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(listen_low_port);
+ATF_TC_HEAD(listen_low_port, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Does low-port allocation work?");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(listen_low_port, tc)
+{
+ int sd, val;
+
+ sd = socket(AF_INET, SOCK_STREAM, 0);
+
+ val = IP_PORTRANGE_LOW;
+ if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val,
+ sizeof(val)) == -1)
+ atf_tc_fail("setsockopt failed: %s", strerror(errno));
+
+ if (listen(sd, 5) == -1) {
+ int serrno = errno;
+ atf_tc_fail("listen failed: %s%s",
+ strerror(serrno),
+ serrno != EACCES ? "" :
+ " (see http://mail-index.netbsd.org/"
+ "source-changes/2007/12/16/0011.html)");
+ }
+
+ close(sd);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, listen_err);
+ ATF_TP_ADD_TC(tp, listen_low_port);
+
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c b/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c
new file mode 100644
index 0000000..02545fe
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c
@@ -0,0 +1,247 @@
+/* $NetBSD: t_lwp_create.c,v 1.2 2012/05/22 09:23:39 martin Exp $ */
+
+/*-
+ * 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.
+ */
+
+/*
+ * This code is partly based on code by Joel Sing <joel at sing.id.au>
+ */
+
+#include <atf-c.h>
+#include <lwp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ucontext.h>
+#include <inttypes.h>
+#include <errno.h>
+
+#ifdef __alpha__
+#include <machine/alpha_cpu.h>
+#endif
+#ifdef __amd64__
+#include <machine/vmparam.h>
+#include <machine/psl.h>
+#endif
+#ifdef __hppa__
+#include <machine/psl.h>
+#endif
+#ifdef __i386__
+#include <machine/segments.h>
+#include <machine/psl.h>
+#endif
+#if defined(__m68k__) || defined(__sh3__) || defined __vax__
+#include <machine/psl.h>
+#endif
+
+volatile lwpid_t the_lwp_id = 0;
+
+static void lwp_main_func(void* arg)
+{
+ the_lwp_id = _lwp_self();
+ _lwp_exit();
+}
+
+/*
+ * Hard to document - see usage examples below.
+ */
+#define INVALID_UCONTEXT(ARCH,NAME,DESC) \
+static void ARCH##_##NAME(ucontext_t *); \
+ATF_TC(lwp_create_##ARCH##_fail_##NAME); \
+ATF_TC_HEAD(lwp_create_##ARCH##_fail_##NAME, tc) \
+{ \
+ atf_tc_set_md_var(tc, "descr", "verify rejection of invalid ucontext " \
+ "on " #ARCH " due to " DESC); \
+} \
+ \
+ATF_TC_BODY(lwp_create_##ARCH##_fail_##NAME, tc) \
+{ \
+ ucontext_t uc; \
+ lwpid_t lid; \
+ int error; \
+ \
+ getcontext(&uc); \
+ uc.uc_flags = _UC_CPU; \
+ ARCH##_##NAME(&uc); \
+ \
+ error = _lwp_create(&uc, 0, &lid); \
+ ATF_REQUIRE(error != 0 && errno == EINVAL); \
+} \
+static void ARCH##_##NAME(ucontext_t *uc) \
+{
+
+
+ATF_TC(lwp_create_works);
+ATF_TC_HEAD(lwp_create_works, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Verify creation of a lwp and waiting"
+ " for it to finish");
+}
+
+ATF_TC_BODY(lwp_create_works, tc)
+{
+ ucontext_t uc;
+ lwpid_t lid;
+ int error;
+ void *stack;
+ static const size_t ssize = 16*1024;
+
+ stack = malloc(ssize);
+ _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize);
+
+ error = _lwp_create(&uc, 0, &lid);
+ ATF_REQUIRE(error == 0);
+
+ error = _lwp_wait(lid, NULL);
+ ATF_REQUIRE(error == 0);
+ ATF_REQUIRE(lid == the_lwp_id);
+}
+
+INVALID_UCONTEXT(generic, no_uc_cpu, "not setting cpu registers")
+ uc->uc_flags &= ~_UC_CPU;
+}
+
+#ifdef __alpha__
+INVALID_UCONTEXT(alpha, pslset, "trying to clear the USERMODE flag")
+ uc->uc_mcontext.__gregs[_REG_PS] &= ~ALPHA_PSL_USERMODE;
+}
+INVALID_UCONTEXT(alpha, pslclr, "trying to set a 'must be zero' flag")
+ uc->uc_mcontext.__gregs[_REG_PS] |= ALPHA_PSL_IPL_HIGH;
+}
+#endif
+#ifdef __amd64__
+INVALID_UCONTEXT(amd64, untouchable_rflags, "forbidden rflags changed")
+ uc->uc_mcontext.__gregs[_REG_RFLAGS] |= PSL_MBZ;
+}
+/*
+ * XXX: add invalid GS/DS selector tests
+ */
+INVALID_UCONTEXT(amd64, pc_too_high,
+ "instruction pointer outside userland address space")
+ uc->uc_mcontext.__gregs[_REG_RIP] = VM_MAXUSER_ADDRESS;
+}
+#endif
+#ifdef __arm__
+INVALID_UCONTEXT(arm, invalid_mode, "psr or r15 set to non-user-mode")
+ uc->uc_mcontext.__gregs[_REG_PC] |= 0x1f /*PSR_SYS32_MODE*/;
+ uc->uc_mcontext.__gregs[_REG_CPSR] |= 0x03 /*R15_MODE_SVC*/;
+}
+#endif
+#ifdef __hppa__
+INVALID_UCONTEXT(hppa, invalid_1, "set illegal bits in psw")
+ uc->uc_mcontext.__gregs[_REG_PSW] |= PSW_MBZ;
+}
+INVALID_UCONTEXT(hppa, invalid_0, "clear illegal bits in psw")
+ uc->uc_mcontext.__gregs[_REG_PSW] &= ~PSW_MBS;
+}
+#endif
+#ifdef __i386__
+INVALID_UCONTEXT(i386, untouchable_eflags, "changing forbidden eflags")
+ uc->uc_mcontext.__gregs[_REG_EFL] |= PSL_IOPL;
+}
+INVALID_UCONTEXT(i386, priv_escalation, "modifying priviledge level")
+ uc->uc_mcontext.__gregs[_REG_CS] &= ~SEL_RPL;
+}
+#endif
+#ifdef __m68k__
+INVALID_UCONTEXT(m68k, invalid_ps_bits,
+ "setting forbidden bits in the ps register")
+ uc->uc_mcontext.__gregs[_REG_PS] |= (PSL_MBZ|PSL_IPL|PSL_S);
+}
+#endif
+#ifdef __sh3__
+INVALID_UCONTEXT(sh3, modify_userstatic,
+ "modifying illegal bits in the status register")
+ uc->uc_mcontext.__gregs[_REG_SR] |= PSL_MD;
+}
+#endif
+#ifdef __sparc__
+INVALID_UCONTEXT(sparc, pc_odd, "mis-aligned instruction pointer")
+ uc->uc_mcontext.__gregs[_REG_PC] = 0x100002;
+}
+INVALID_UCONTEXT(sparc, npc_odd, "mis-aligned next instruction pointer")
+ uc->uc_mcontext.__gregs[_REG_nPC] = 0x100002;
+}
+INVALID_UCONTEXT(sparc, pc_null, "NULL instruction pointer")
+ uc->uc_mcontext.__gregs[_REG_PC] = 0;
+}
+INVALID_UCONTEXT(sparc, npc_null, "NULL next instruction pointer")
+ uc->uc_mcontext.__gregs[_REG_nPC] = 0;
+}
+#endif
+#ifdef __vax__
+INVALID_UCONTEXT(vax, psl_0, "clearing forbidden bits in psl")
+ uc->uc_mcontext.__gregs[_REG_PSL] &= ~(PSL_U | PSL_PREVU);
+}
+INVALID_UCONTEXT(vax, psl_1, "setting forbidden bits in psl")
+ uc->uc_mcontext.__gregs[_REG_PSL] |= PSL_IPL | PSL_IS;
+}
+INVALID_UCONTEXT(vax, psl_cm, "setting CM bit in psl")
+ uc->uc_mcontext.__gregs[_REG_PSL] |= PSL_CM;
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, lwp_create_works);
+ ATF_TP_ADD_TC(tp, lwp_create_generic_fail_no_uc_cpu);
+#ifdef __alpha__
+ ATF_TP_ADD_TC(tp, lwp_create_alpha_fail_pslset);
+ ATF_TP_ADD_TC(tp, lwp_create_alpha_fail_pslclr);
+#endif
+#ifdef __amd64__
+ ATF_TP_ADD_TC(tp, lwp_create_amd64_fail_untouchable_rflags);
+ ATF_TP_ADD_TC(tp, lwp_create_amd64_fail_pc_too_high);
+#endif
+#ifdef __arm__
+ ATF_TP_ADD_TC(tp, lwp_create_arm_fail_invalid_mode);
+#endif
+#ifdef __hppa__
+ ATF_TP_ADD_TC(tp, lwp_create_hppa_fail_invalid_1);
+ ATF_TP_ADD_TC(tp, lwp_create_hppa_fail_invalid_0);
+#endif
+#ifdef __i386__
+ ATF_TP_ADD_TC(tp, lwp_create_i386_fail_untouchable_eflags);
+ ATF_TP_ADD_TC(tp, lwp_create_i386_fail_priv_escalation);
+#endif
+#ifdef __m68k__
+ ATF_TP_ADD_TC(tp, lwp_create_m68k_fail_invalid_ps_bits);
+#endif
+#ifdef __sh3__
+ ATF_TP_ADD_TC(tp, lwp_create_sh3_fail_modify_userstatic);
+#endif
+#ifdef __sparc__
+ ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_pc_odd);
+ ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_npc_odd);
+ ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_pc_null);
+ ATF_TP_ADD_TC(tp, lwp_create_sparc_fail_npc_null);
+#endif
+#ifdef __vax__
+ ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_0);
+ ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_1);
+ ATF_TP_ADD_TC(tp, lwp_create_vax_fail_psl_cm);
+#endif
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c b/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c
new file mode 100644
index 0000000..1b28f75
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c
@@ -0,0 +1,74 @@
+/* $NetBSD: t_lwp_ctl.c,v 1.2 2012/03/18 06:20:51 jruoho Exp $ */
+
+/*-
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_lwp_ctl.c,v 1.2 2012/03/18 06:20:51 jruoho Exp $");
+
+#include <sys/lwpctl.h>
+
+#include <atf-c.h>
+#include <lwp.h>
+#include <stdio.h>
+#include <time.h>
+
+ATF_TC(lwpctl_counter);
+ATF_TC_HEAD(lwpctl_counter, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks lwpctl preemption counter");
+}
+
+ATF_TC_BODY(lwpctl_counter, tc)
+{
+ lwpctl_t *lc;
+ struct timespec ts;
+ int ctr1, ctr2;
+
+ ATF_REQUIRE(_lwp_ctl(LWPCTL_FEATURE_PCTR, &lc) == 0);
+
+ /* Ensure that preemption is reported. */
+ ctr1 = lc->lc_pctr;
+ (void)printf("pctr = %d\n", ctr1);
+ ts.tv_nsec = 10*1000000;
+ ts.tv_sec = 0;
+
+ ATF_REQUIRE(nanosleep(&ts, 0) != -1);
+
+ ctr2 = lc->lc_pctr;
+ (void)printf("pctr = %d\n", ctr2);
+
+ ATF_REQUIRE_MSG(ctr1 != ctr2, "counters match");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, lwpctl_counter);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mincore.c b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c
new file mode 100644
index 0000000..499493f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c
@@ -0,0 +1,336 @@
+/* $NetBSD: t_mincore.c,v 1.8 2012/06/08 07:18:58 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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 (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_mincore.c,v 1.8 2012/06/08 07:18:58 martin Exp $");
+
+#include <sys/mman.h>
+#include <sys/shm.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <kvm.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/resource.h>
+
+#ifdef __FreeBSD__
+#include <sys/stat.h>
+#endif
+
+static long page = 0;
+static const char path[] = "mincore";
+static size_t check_residency(void *, size_t);
+
+static size_t
+check_residency(void *addr, size_t npgs)
+{
+ size_t i, resident;
+ char *vec;
+
+ vec = malloc(npgs);
+
+ ATF_REQUIRE(vec != NULL);
+ ATF_REQUIRE(mincore(addr, npgs * page, vec) == 0);
+
+ for (i = resident = 0; i < npgs; i++) {
+
+ if (vec[i] != 0)
+ resident++;
+
+#if 0
+ (void)fprintf(stderr, "page 0x%p is %sresident\n",
+ (char *)addr + (i * page), vec[i] ? "" : "not ");
+#endif
+ }
+
+ free(vec);
+
+ return resident;
+}
+
+ATF_TC(mincore_err);
+ATF_TC_HEAD(mincore_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from mincore(2)");
+}
+
+ATF_TC_BODY(mincore_err, tc)
+{
+ char *map, *vec;
+
+ map = mmap(NULL, page, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ vec = malloc(page);
+
+ ATF_REQUIRE(vec != NULL);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+#ifdef __NetBSD__
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, mincore(map, 0, vec) == -1);
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOMEM, mincore(0, page, vec) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, mincore(map, page, (void *)-1) == -1);
+
+ free(vec);
+ ATF_REQUIRE(munmap(map, page) == 0);
+}
+
+ATF_TC_WITH_CLEANUP(mincore_resid);
+ATF_TC_HEAD(mincore_resid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test page residency with mincore(2)");
+}
+
+ATF_TC_BODY(mincore_resid, tc)
+{
+ void *addr, *addr2, *addr3, *buf;
+ size_t npgs = 0, resident;
+ struct stat st;
+ int fd, rv;
+ struct rlimit rlim;
+
+ ATF_REQUIRE(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
+ rlim.rlim_cur = rlim.rlim_max;
+ ATF_REQUIRE(setrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ fd = open(path, O_RDWR | O_CREAT, 0700);
+ buf = malloc(page * 5);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(buf != NULL);
+
+ rv = write(fd, buf, page * 5);
+ ATF_REQUIRE(rv >= 0);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(fstat(fd, &st) == 0);
+
+ addr = mmap(NULL, (size_t)st.st_size, PROT_READ,
+ MAP_FILE | MAP_SHARED, fd, (off_t) 0);
+
+ ATF_REQUIRE(addr != MAP_FAILED);
+
+ (void)close(fd);
+
+ npgs = st.st_size / page;
+
+ if (st.st_size % page != 0)
+ npgs++;
+
+ (void)check_residency(addr, npgs);
+
+ rv = mlock(addr, npgs * page);
+ if (rv == -1 && errno == EAGAIN)
+ atf_tc_skip("hit process resource limits");
+ ATF_REQUIRE(munmap(addr, st.st_size) == 0);
+
+ npgs = 128;
+
+#ifdef __FreeBSD__
+ addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, (off_t)0);
+#else
+ addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE | MAP_WIRED, -1, (off_t)0);
+#endif
+
+ if (addr == MAP_FAILED)
+ atf_tc_skip("could not mmap wired anonymous test area, system "
+ "might be low on memory");
+
+#ifdef __FreeBSD__
+ ATF_REQUIRE(mlock(addr, npgs * page) == 0);
+#endif
+ ATF_REQUIRE(check_residency(addr, npgs) == npgs);
+ ATF_REQUIRE(munmap(addr, npgs * page) == 0);
+
+ npgs = 128;
+
+ addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, (off_t)0);
+
+ ATF_REQUIRE(addr != MAP_FAILED);
+
+ /*
+ * Check that the in-core pages match the locked pages.
+ */
+ ATF_REQUIRE(check_residency(addr, npgs) == 0);
+
+ errno = 0;
+ if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0 && errno != ENOMEM)
+ atf_tc_fail("mlockall(2) failed");
+ if (errno == ENOMEM)
+ atf_tc_skip("mlockall() exceeded process resource limits");
+
+ resident = check_residency(addr, npgs);
+ if (resident < npgs)
+ atf_tc_fail("mlockall(MCL_FUTURE) succeeded, still only "
+ "%zu pages of the newly mapped %zu pages are resident",
+ resident, npgs);
+
+ addr2 = mmap(NULL, npgs * page, PROT_READ, MAP_ANON, -1, (off_t)0);
+ addr3 = mmap(NULL, npgs * page, PROT_NONE, MAP_ANON, -1, (off_t)0);
+
+ if (addr2 == MAP_FAILED || addr3 == MAP_FAILED)
+ atf_tc_skip("could not mmap more anonymous test pages with "
+ "mlockall(MCL_FUTURE) in effect, system "
+ "might be low on memory");
+
+ ATF_REQUIRE(check_residency(addr2, npgs) == npgs);
+ ATF_REQUIRE(check_residency(addr3, npgs) == 0);
+ ATF_REQUIRE(mprotect(addr3, npgs * page, PROT_READ) == 0);
+ ATF_REQUIRE(check_residency(addr, npgs) == npgs);
+ ATF_REQUIRE(check_residency(addr2, npgs) == npgs);
+
+ (void)munlockall();
+
+ ATF_REQUIRE(madvise(addr2, npgs * page, MADV_FREE) == 0);
+#ifdef __NetBSD__
+ ATF_REQUIRE(check_residency(addr2, npgs) == 0);
+#endif
+
+ (void)memset(addr, 0, npgs * page);
+
+ ATF_REQUIRE(madvise(addr, npgs * page, MADV_FREE) == 0);
+#ifdef __NetBSD__
+ ATF_REQUIRE(check_residency(addr, npgs) == 0);
+#endif
+
+ (void)munmap(addr, npgs * page);
+ (void)munmap(addr2, npgs * page);
+ (void)munmap(addr3, npgs * page);
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(mincore_resid, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(mincore_shmseg);
+ATF_TC_HEAD(mincore_shmseg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "residency of shared memory");
+}
+
+ATF_TC_BODY(mincore_shmseg, tc)
+{
+ size_t npgs = 128;
+ void *addr = NULL;
+ int shmid;
+
+ shmid = shmget(IPC_PRIVATE, npgs * page,
+ IPC_CREAT | S_IRUSR | S_IWUSR);
+
+ ATF_REQUIRE(shmid != -1);
+
+ addr = shmat(shmid, NULL, 0);
+
+ ATF_REQUIRE(addr != NULL);
+ ATF_REQUIRE(check_residency(addr, npgs) == 0);
+
+ (void)memset(addr, 0xff, npgs * page);
+
+ ATF_REQUIRE(check_residency(addr, npgs) == npgs);
+ ATF_REQUIRE(madvise(addr, npgs * page, MADV_FREE) == 0);
+
+ /*
+ * NOTE! Even though we have MADV_FREE'd the range,
+ * there is another reference (the kernel's) to the
+ * object which owns the pages. In this case, the
+ * kernel does not simply free the pages, as haphazardly
+ * freeing pages when there are still references to
+ * an object can cause data corruption (say, the other
+ * referencer doesn't expect the pages to be freed,
+ * and is surprised by the subsequent ZFOD).
+ *
+ * Because of this, we simply report the number of
+ * pages still resident, for information only.
+ */
+ npgs = check_residency(addr, npgs);
+
+ (void)fprintf(stderr, "%zu pages still resident\n", npgs);
+
+ ATF_REQUIRE(shmdt(addr) == 0);
+ ATF_REQUIRE(shmctl(shmid, IPC_RMID, NULL) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+ ATF_TP_ADD_TC(tp, mincore_err);
+ ATF_TP_ADD_TC(tp, mincore_resid);
+ ATF_TP_ADD_TC(tp, mincore_shmseg);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_minherit.c b/contrib/netbsd-tests/lib/libc/sys/t_minherit.c
new file mode 100644
index 0000000..0bdf6bc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_minherit.c
@@ -0,0 +1,200 @@
+/* $NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_minherit.c,v 1.1 2014/07/18 12:34:52 christos Exp $");
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+static long page;
+
+static void *
+makemap(int v, int f) {
+ void *map = mmap(NULL, page, PROT_READ|PROT_WRITE,
+ MAP_SHARED|MAP_ANON, -1, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+ memset(map, v, page);
+ if (f != 666)
+ ATF_REQUIRE(minherit(map, page, f) == 0);
+ else
+ ATF_REQUIRE(minherit(map, page, f) == -1);
+ return map;
+}
+
+ATF_TC(minherit_copy);
+ATF_TC_HEAD(minherit_copy, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test for MAP_INHERIT_COPY from minherit(2)");
+}
+
+ATF_TC_BODY(minherit_copy, tc)
+{
+ void *map1 = makemap(1, MAP_INHERIT_COPY);
+ void *map2 = makemap(1, MAP_INHERIT_COPY);
+ switch (fork()) {
+ default:
+ ATF_REQUIRE(wait(NULL) != -1);
+ ATF_REQUIRE(memcmp(map1, map2, page) == 0);
+ break;
+ case -1:
+ ATF_REQUIRE(0);
+ break;
+ case 0:
+ ATF_REQUIRE(memcmp(map1, map2, page) == 0);
+ memset(map1, 0, page);
+ exit(0);
+ }
+}
+
+ATF_TC(minherit_share);
+ATF_TC_HEAD(minherit_share, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test for MAP_INHERIT_SHARE from minherit(2)");
+}
+
+ATF_TC_BODY(minherit_share, tc)
+{
+ void *map1 = makemap(1, MAP_INHERIT_SHARE);
+ void *map2 = makemap(1, MAP_INHERIT_SHARE);
+
+ switch (fork()) {
+ default:
+ ATF_REQUIRE(wait(NULL) != -1);
+ memset(map2, 0, page);
+ ATF_REQUIRE(memcmp(map1, map2, page) == 0);
+ break;
+ case -1:
+ ATF_REQUIRE(0);
+ break;
+ case 0:
+ ATF_REQUIRE(memcmp(map1, map2, page) == 0);
+ memset(map1, 0, page);
+ exit(0);
+ }
+}
+
+static void
+segv(int n) {
+ _exit(n);
+}
+
+ATF_TC(minherit_none);
+ATF_TC_HEAD(minherit_none, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test for MAP_INHERIT_NONE from minherit(2)");
+}
+
+ATF_TC_BODY(minherit_none, tc)
+{
+ void *map1 = makemap(0, MAP_INHERIT_NONE);
+ int status;
+
+ switch (fork()) {
+ default:
+ ATF_REQUIRE(wait(&status) != -1);
+ ATF_REQUIRE(WEXITSTATUS(status) == SIGSEGV);
+ break;
+ case -1:
+ ATF_REQUIRE(0);
+ break;
+ case 0:
+ ATF_REQUIRE(signal(SIGSEGV, segv) != SIG_ERR);
+ memset(map1, 0, page);
+ exit(0);
+ }
+}
+
+ATF_TC(minherit_zero);
+ATF_TC_HEAD(minherit_zero, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test for MAP_INHERIT_ZERO from minherit(2)");
+}
+
+ATF_TC_BODY(minherit_zero, tc)
+{
+ void *map1 = makemap(1, MAP_INHERIT_ZERO);
+ void *map2 = makemap(0, MAP_INHERIT_SHARE);
+
+ switch (fork()) {
+ default:
+ ATF_REQUIRE(wait(NULL) != -1);
+ memset(map2, 1, page);
+ ATF_REQUIRE(memcmp(map1, map2, page) == 0);
+ break;
+ case -1:
+ ATF_REQUIRE(0);
+ break;
+ case 0:
+ ATF_REQUIRE(memcmp(map1, map2, page) == 0);
+ memset(map1, 2, page);
+ exit(0);
+ }
+}
+
+ATF_TC(minherit_bad);
+ATF_TC_HEAD(minherit_bad, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test for bad minherit(2)");
+}
+
+ATF_TC_BODY(minherit_bad, tc)
+{
+ (void)makemap(0, 666);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+ ATF_TP_ADD_TC(tp, minherit_copy);
+ ATF_TP_ADD_TC(tp, minherit_share);
+ ATF_TP_ADD_TC(tp, minherit_none);
+ ATF_TP_ADD_TC(tp, minherit_zero);
+ ATF_TP_ADD_TC(tp, minherit_bad);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c b/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c
new file mode 100644
index 0000000..d97a20b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mkdir.c
@@ -0,0 +1,210 @@
+/* $NetBSD: t_mkdir.c,v 1.2 2011/10/15 07:38:31 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2008, 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe and Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_mkdir.c,v 1.2 2011/10/15 07:38:31 jruoho Exp $");
+
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+ATF_TC(mkdir_err);
+ATF_TC_HEAD(mkdir_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks errors from mkdir(2)");
+}
+
+ATF_TC_BODY(mkdir_err, tc)
+{
+ char buf[PATH_MAX + 1];
+ int fd;
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ fd = open("/etc", O_RDONLY);
+
+ if (fd >= 0) {
+
+ (void)close(fd);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EEXIST, mkdir("/etc", 0500) == -1);
+ }
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, mkdir((void *)-1, 0500) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, mkdir(buf, 0500) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, mkdir("/a/b/c/d/e/f/g/h/i/j/k", 0500) == -1);
+}
+
+ATF_TC_WITH_CLEANUP(mkdir_perm);
+ATF_TC_HEAD(mkdir_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks permissions with mkdir(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(mkdir_perm, tc)
+{
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EACCES, mkdir("/usr/__nonexistent__", 0500) == -1);
+}
+
+ATF_TC_CLEANUP(mkdir_perm, tc)
+{
+ (void)rmdir("/usr/__nonexistent__");
+}
+
+ATF_TC_WITH_CLEANUP(mkdir_mode);
+ATF_TC_HEAD(mkdir_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that UIDs and GIDs are right "
+ "for a directory created with mkdir(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(mkdir_mode, tc)
+{
+ static const char *path = "/tmp/mkdir";
+ struct stat st_a, st_b;
+ struct passwd *pw;
+ pid_t pid;
+ int sta;
+
+ (void)memset(&st_a, 0, sizeof(struct stat));
+ (void)memset(&st_b, 0, sizeof(struct stat));
+
+ pw = getpwnam("nobody");
+
+ ATF_REQUIRE(pw != NULL);
+ ATF_REQUIRE(stat("/tmp", &st_a) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (setuid(pw->pw_uid) != 0)
+ _exit(EXIT_FAILURE);
+
+ if (mkdir(path, 0500) != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)sleep(1);
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("failed to create '%s'", path);
+
+ ATF_REQUIRE(stat(path, &st_b) == 0);
+ ATF_REQUIRE(rmdir(path) == 0);
+
+ /*
+ * The directory's owner ID should be set to the
+ * effective UID, whereas the group ID should be
+ * set to that of the parent directory.
+ */
+ if (st_b.st_uid != pw->pw_uid)
+ atf_tc_fail("invalid UID for '%s'", path);
+
+ if (st_b.st_gid != st_a.st_gid)
+ atf_tc_fail("GID did not follow the parent directory");
+}
+
+ATF_TC_CLEANUP(mkdir_mode, tc)
+{
+ (void)rmdir("/tmp/mkdir");
+}
+
+ATF_TC(mkdir_trail);
+ATF_TC_HEAD(mkdir_trail, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks mkdir(2) for trailing slashes");
+}
+
+ATF_TC_BODY(mkdir_trail, tc)
+{
+ const char *tests[] = {
+ /*
+ * IEEE 1003.1 second ed. 2.2.2.78:
+ *
+ * If the pathname refers to a directory, it may also have
+ * one or more trailing slashes. Multiple successive slashes
+ * are considered to be the same as one slash.
+ */
+ "dir1/",
+ "dir2//",
+
+ NULL,
+ };
+
+ const char **test;
+
+ for (test = &tests[0]; *test != NULL; ++test) {
+
+ (void)printf("Checking \"%s\"\n", *test);
+ (void)rmdir(*test);
+
+ ATF_REQUIRE(mkdir(*test, 0777) == 0);
+ ATF_REQUIRE(rename(*test, "foo") == 0);
+ ATF_REQUIRE(rename("foo/", *test) == 0);
+ ATF_REQUIRE(rmdir(*test) == 0);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mkdir_err);
+ ATF_TP_ADD_TC(tp, mkdir_perm);
+ ATF_TP_ADD_TC(tp, mkdir_mode);
+ ATF_TP_ADD_TC(tp, mkdir_trail);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c b/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c
new file mode 100644
index 0000000..56bc4c8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c
@@ -0,0 +1,276 @@
+/* $NetBSD: t_mkfifo.c,v 1.2 2011/11/02 06:04:48 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_mkfifo.c,v 1.2 2011/11/02 06:04:48 jruoho Exp $");
+
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char path[] = "fifo";
+static void support(void);
+
+static void
+support(void)
+{
+
+ errno = 0;
+
+ if (mkfifo(path, 0600) == 0) {
+ ATF_REQUIRE(unlink(path) == 0);
+ return;
+ }
+
+ if (errno == EOPNOTSUPP)
+ atf_tc_skip("the kernel does not support FIFOs");
+ else {
+ atf_tc_fail("mkfifo(2) failed");
+ }
+}
+
+ATF_TC_WITH_CLEANUP(mkfifo_block);
+ATF_TC_HEAD(mkfifo_block, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that FIFOs block");
+}
+
+ATF_TC_BODY(mkfifo_block, tc)
+{
+ int sta, fd = -1;
+ pid_t pid;
+
+ support();
+
+ ATF_REQUIRE(mkfifo(path, 0600) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * If we open the FIFO as read-only (write-only),
+ * the call should block until another process
+ * opens the FIFO for writing (reading).
+ */
+ fd = open(path, O_RDONLY);
+
+ _exit(EXIT_FAILURE); /* NOTREACHED */
+ }
+
+ (void)sleep(1);
+
+ ATF_REQUIRE(kill(pid, SIGKILL) == 0);
+
+ (void)wait(&sta);
+
+ if (WIFSIGNALED(sta) == 0 || WTERMSIG(sta) != SIGKILL)
+ atf_tc_fail("FIFO did not block");
+
+ (void)close(fd);
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(mkfifo_block, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mkfifo_err);
+ATF_TC_HEAD(mkfifo_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erros from mkfifo(2)");
+}
+
+ATF_TC_BODY(mkfifo_err, tc)
+{
+ char buf[PATH_MAX + 1];
+
+ support();
+
+ (void)memset(buf, 'x', sizeof(buf));
+ ATF_REQUIRE(mkfifo(path, 0600) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, mkfifo((char *)-1, 0600) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EEXIST, mkfifo("/etc/passwd", 0600) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EEXIST, mkfifo(path, 0600) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, mkfifo(buf, 0600) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, mkfifo("/a/b/c/d/e/f/g", 0600) == -1);
+
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(mkfifo_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mkfifo_nonblock);
+ATF_TC_HEAD(mkfifo_nonblock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test O_NONBLOCK with FIFOs");
+}
+
+ATF_TC_BODY(mkfifo_nonblock, tc)
+{
+ int fd, sta;
+ pid_t pid;
+
+ support();
+
+ fd = -1;
+ ATF_REQUIRE(mkfifo(path, 0600) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * If we open the FIFO as O_NONBLOCK, the O_RDONLY
+ * call should return immediately, whereas the call
+ * for write-only should fail with ENXIO.
+ */
+ fd = open(path, O_RDONLY | O_NONBLOCK);
+
+ if (fd >= 0)
+ _exit(EXIT_SUCCESS);
+
+ (void)pause(); /* NOTREACHED */
+ }
+
+ (void)sleep(1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENXIO, open(path, O_WRONLY | O_NONBLOCK) == -1);
+
+ (void)kill(pid, SIGKILL);
+ (void)wait(&sta);
+
+ if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL)
+ atf_tc_fail("FIFO blocked for O_NONBLOCK open(2)");
+
+ (void)close(fd);
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(mkfifo_nonblock, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mkfifo_perm);
+ATF_TC_HEAD(mkfifo_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with mkfifo(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(mkfifo_perm, tc)
+{
+
+ support();
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EACCES, mkfifo("/root/fifo", 0600) == -1);
+
+ ATF_REQUIRE(mkfifo(path, 0600) == 0);
+
+ /*
+ * For some reason this fails with EFTYPE...
+ */
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFTYPE, chmod(path, 1777) == -1);
+
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(mkfifo_perm, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mkfifo_stat);
+ATF_TC_HEAD(mkfifo_stat, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mkfifo(2) with stat");
+}
+
+ATF_TC_BODY(mkfifo_stat, tc)
+{
+ struct stat st;
+
+ support();
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(mkfifo(path, 0600) == 0);
+ ATF_REQUIRE(stat(path, &st) == 0);
+
+ if (S_ISFIFO(st.st_mode) == 0)
+ atf_tc_fail("invalid mode from mkfifo(2)");
+
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(mkfifo_stat, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mkfifo_block);
+ ATF_TP_ADD_TC(tp, mkfifo_err);
+ ATF_TP_ADD_TC(tp, mkfifo_nonblock);
+ ATF_TP_ADD_TC(tp, mkfifo_perm);
+ ATF_TP_ADD_TC(tp, mkfifo_stat);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mknod.c b/contrib/netbsd-tests/lib/libc/sys/t_mknod.c
new file mode 100644
index 0000000..1c5cd9b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mknod.c
@@ -0,0 +1,202 @@
+/* $NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $");
+
+#include <sys/stat.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+static char path[] = "node";
+
+ATF_TC_WITH_CLEANUP(mknod_err);
+ATF_TC_HEAD(mknod_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test error conditions of mknod(2) (PR kern/45111)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(mknod_err, tc)
+{
+ char buf[PATH_MAX + 1];
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+#ifndef __FreeBSD__
+ /*
+ * As of FreeBSD 6.0 device nodes may be created in regular file systems but
+ * such nodes cannot be used to access devices. As a result an invalid dev
+ * argument is unchecked.
+ */
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, mknod(path, S_IFCHR, -1) == -1);
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, mknod(buf, S_IFCHR, 0) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, mknod((char *)-1, S_IFCHR, 0) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, mknod("/a/b/c/d/e/f/g", S_IFCHR, 0) == -1);
+}
+
+ATF_TC_CLEANUP(mknod_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mknod_exist);
+ATF_TC_HEAD(mknod_exist, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test EEXIST from mknod(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(mknod_exist, tc)
+{
+ int fd;
+
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd >= 0) {
+
+ (void)close(fd);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EEXIST,
+ mknod("/etc/passwd", S_IFCHR, 0) == -1);
+ }
+
+ ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EEXIST, mknod(path, S_IFCHR, 0) == -1);
+
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(mknod_exist, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mknod_perm);
+ATF_TC_HEAD(mknod_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions of mknod(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(mknod_perm, tc)
+{
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFCHR, 0) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFBLK, 0) == -1);
+}
+
+ATF_TC_CLEANUP(mknod_perm, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mknod_stat);
+ATF_TC_HEAD(mknod_stat, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of mknod(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(mknod_stat, tc)
+{
+ struct stat st;
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0);
+ ATF_REQUIRE(stat(path, &st) == 0);
+
+ if (S_ISCHR(st.st_mode) == 0)
+ atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFCHR)");
+
+ ATF_REQUIRE(unlink(path) == 0);
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(mknod(path, S_IFBLK, 0) == 0);
+ ATF_REQUIRE(stat(path, &st) == 0);
+
+ if (S_ISBLK(st.st_mode) == 0)
+ atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFBLK)");
+
+ ATF_REQUIRE(unlink(path) == 0);
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("mknod does not allow S_IFREG");
+#endif
+ ATF_REQUIRE(mknod(path, S_IFREG, 0) == 0);
+ ATF_REQUIRE(stat(path, &st) == 0);
+
+ if (S_ISREG(st.st_mode) == 0)
+ atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFREG)");
+
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(mknod_stat, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mknod_err);
+ ATF_TP_ADD_TC(tp, mknod_exist);
+ ATF_TP_ADD_TC(tp, mknod_perm);
+ ATF_TP_ADD_TC(tp, mknod_stat);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mlock.c b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c
new file mode 100644
index 0000000..0397b5c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c
@@ -0,0 +1,286 @@
+/* $NetBSD: t_mlock.c,v 1.5 2014/02/26 20:49:26 martin Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_mlock.c,v 1.5 2014/02/26 20:49:26 martin Exp $");
+
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#endif
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <atf-c.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#define _KMEMUSER
+#include <machine/vmparam.h>
+#endif
+
+static long page = 0;
+
+ATF_TC(mlock_clip);
+ATF_TC_HEAD(mlock_clip, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test with mlock(2) that UVM only "
+ "clips if the clip address is within the entry (PR kern/44788)");
+}
+
+ATF_TC_BODY(mlock_clip, tc)
+{
+ void *buf;
+
+ buf = malloc(page);
+ ATF_REQUIRE(buf != NULL);
+
+ if (page < 1024)
+ atf_tc_skip("page size too small");
+
+ for (size_t i = page; i >= 1; i = i - 1024) {
+ (void)mlock(buf, page - i);
+ (void)munlock(buf, page - i);
+ }
+
+ free(buf);
+}
+
+ATF_TC(mlock_err);
+ATF_TC_HEAD(mlock_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test error conditions in mlock(2) and munlock(2)");
+}
+
+ATF_TC_BODY(mlock_err, tc)
+{
+#ifdef __NetBSD__
+ unsigned long vmin = 0;
+ size_t len = sizeof(vmin);
+#endif
+ void *invalid_ptr;
+ int null_errno = ENOMEM; /* error expected for NULL */
+
+#ifdef __FreeBSD__
+#ifdef VM_MIN_ADDRESS
+ if ((uintptr_t)VM_MIN_ADDRESS > 0)
+ null_errno = EINVAL; /* NULL is not inside user VM */
+#endif
+#else
+ if (sysctlbyname("vm.minaddress", &vmin, &len, NULL, 0) != 0)
+ atf_tc_fail("failed to read vm.minaddress");
+
+ if (vmin > 0)
+ null_errno = EINVAL; /* NULL is not inside user VM */
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(null_errno, mlock(NULL, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(null_errno, mlock((char *)0, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, mlock((char *)-1, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(null_errno, munlock(NULL, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(null_errno, munlock((char *)0, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, munlock((char *)-1, page) == -1);
+
+ /*
+ * Try to create a pointer to an unmapped page - first after current
+ * brk will likely do.
+ */
+ invalid_ptr = (void*)(((uintptr_t)sbrk(0)+page) & ~(page-1));
+ printf("testing with (hopefully) invalid pointer %p\n", invalid_ptr);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOMEM, mlock(invalid_ptr, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOMEM, munlock(invalid_ptr, page) == -1);
+}
+
+ATF_TC(mlock_limits);
+ATF_TC_HEAD(mlock_limits, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test system limits with mlock(2)");
+}
+
+ATF_TC_BODY(mlock_limits, tc)
+{
+ struct rlimit res;
+ void *buf;
+ pid_t pid;
+ int sta;
+
+ buf = malloc(page);
+ ATF_REQUIRE(buf != NULL);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ for (ssize_t i = page; i >= 2; i -= 100) {
+
+ res.rlim_cur = i - 1;
+ res.rlim_max = i - 1;
+
+ (void)fprintf(stderr, "trying to lock %zd bytes "
+ "with %zu byte limit\n", i, (size_t)res.rlim_cur);
+
+ if (setrlimit(RLIMIT_MEMLOCK, &res) != 0)
+ _exit(EXIT_FAILURE);
+
+ errno = 0;
+
+#ifdef __FreeBSD__
+ /*
+ * NetBSD doesn't conform to POSIX with ENOMEM requirement;
+ * FreeBSD does.
+ *
+ * See: NetBSD PR # kern/48962 for more details.
+ */
+ if (mlock(buf, i) != -1 || errno != ENOMEM) {
+#else
+ if (mlock(buf, i) != -1 || errno != EAGAIN) {
+#endif
+ (void)munlock(buf, i);
+ _exit(EXIT_FAILURE);
+ }
+ }
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("mlock(2) locked beyond system limits");
+
+ free(buf);
+}
+
+ATF_TC(mlock_mmap);
+ATF_TC_HEAD(mlock_mmap, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mlock(2)-mmap(2) interaction");
+}
+
+ATF_TC_BODY(mlock_mmap, tc)
+{
+#ifdef __NetBSD__
+ static const int flags = MAP_ANON | MAP_PRIVATE | MAP_WIRED;
+#else
+ static const int flags = MAP_ANON | MAP_PRIVATE;
+#endif
+ void *buf;
+
+ /*
+ * Make a wired RW mapping and check that mlock(2)
+ * does not fail for the (already locked) mapping.
+ */
+ buf = mmap(NULL, page, PROT_READ | PROT_WRITE, flags, -1, 0);
+
+ ATF_REQUIRE(buf != MAP_FAILED);
+#ifdef __FreeBSD__
+ /*
+ * The duplicate mlock call is added to ensure that the call works
+ * as described above without MAP_WIRED support.
+ */
+ ATF_REQUIRE(mlock(buf, page) == 0);
+#endif
+ ATF_REQUIRE(mlock(buf, page) == 0);
+ ATF_REQUIRE(munlock(buf, page) == 0);
+ ATF_REQUIRE(munmap(buf, page) == 0);
+ ATF_REQUIRE(munlock(buf, page) != 0);
+
+ /*
+ * But it should be impossible to mlock(2) a PROT_NONE mapping.
+ */
+ buf = mmap(NULL, page, PROT_NONE, flags, -1, 0);
+
+ ATF_REQUIRE(buf != MAP_FAILED);
+#ifdef __FreeBSD__
+ ATF_REQUIRE_ERRNO(ENOMEM, mlock(buf, page) != 0);
+#else
+ ATF_REQUIRE(mlock(buf, page) != 0);
+#endif
+ ATF_REQUIRE(munmap(buf, page) == 0);
+}
+
+ATF_TC(mlock_nested);
+ATF_TC_HEAD(mlock_nested, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that consecutive mlock(2) calls succeed");
+}
+
+ATF_TC_BODY(mlock_nested, tc)
+{
+ const size_t maxiter = 100;
+ void *buf;
+
+ buf = malloc(page);
+ ATF_REQUIRE(buf != NULL);
+
+ for (size_t i = 0; i < maxiter; i++)
+ ATF_REQUIRE(mlock(buf, page) == 0);
+
+ ATF_REQUIRE(munlock(buf, page) == 0);
+ free(buf);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+ ATF_TP_ADD_TC(tp, mlock_clip);
+ ATF_TP_ADD_TC(tp, mlock_err);
+ ATF_TP_ADD_TC(tp, mlock_limits);
+ ATF_TP_ADD_TC(tp, mlock_mmap);
+ ATF_TP_ADD_TC(tp, mlock_nested);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mmap.c b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c
new file mode 100644
index 0000000..5d821ec
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c
@@ -0,0 +1,524 @@
+/* $NetBSD: t_mmap.c,v 1.7 2012/06/14 17:47:58 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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 (c)2004 YAMAMOTO Takashi,
+ * 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 AUTHOR 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 AUTHOR 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/cdefs.h>
+__RCSID("$NetBSD: t_mmap.c,v 1.7 2012/06/14 17:47:58 bouyer Exp $");
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+#ifdef __NetBSD__
+#include <machine/disklabel.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <sys/disklabel.h>
+#include <sys/stat.h>
+#include <stdint.h>
+#endif
+
+static long page = 0;
+static char path[] = "mmap";
+static void map_check(void *, int);
+static void map_sighandler(int);
+static void testloan(void *, void *, char, int);
+
+#define BUFSIZE (32 * 1024) /* enough size to trigger sosend_loan */
+
+static void
+map_check(void *map, int flag)
+{
+
+ if (flag != 0) {
+ ATF_REQUIRE(map == MAP_FAILED);
+ return;
+ }
+
+ ATF_REQUIRE(map != MAP_FAILED);
+ ATF_REQUIRE(munmap(map, page) == 0);
+}
+
+void
+testloan(void *vp, void *vp2, char pat, int docheck)
+{
+ char buf[BUFSIZE];
+ char backup[BUFSIZE];
+ ssize_t nwritten;
+ ssize_t nread;
+ int fds[2];
+ int val;
+
+ val = BUFSIZE;
+
+ if (docheck != 0)
+ (void)memcpy(backup, vp, BUFSIZE);
+
+ if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, fds) != 0)
+ atf_tc_fail("socketpair() failed");
+
+ val = BUFSIZE;
+
+ if (setsockopt(fds[1], SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) != 0)
+ atf_tc_fail("setsockopt() failed, SO_RCVBUF");
+
+ val = BUFSIZE;
+
+ if (setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) != 0)
+ atf_tc_fail("setsockopt() failed, SO_SNDBUF");
+
+ if (fcntl(fds[0], F_SETFL, O_NONBLOCK) != 0)
+ atf_tc_fail("fcntl() failed");
+
+ nwritten = write(fds[0], (char *)vp + page, BUFSIZE - page);
+
+ if (nwritten == -1)
+ atf_tc_fail("write() failed");
+
+ /* Break loan. */
+ (void)memset(vp2, pat, BUFSIZE);
+
+ nread = read(fds[1], buf + page, BUFSIZE - page);
+
+ if (nread == -1)
+ atf_tc_fail("read() failed");
+
+ if (nread != nwritten)
+ atf_tc_fail("too short read");
+
+ if (docheck != 0 && memcmp(backup, buf + page, nread) != 0)
+ atf_tc_fail("data mismatch");
+
+ ATF_REQUIRE(close(fds[0]) == 0);
+ ATF_REQUIRE(close(fds[1]) == 0);
+}
+
+static void
+map_sighandler(int signo)
+{
+ _exit(signo);
+}
+
+#ifdef __NetBSD__
+ATF_TC(mmap_block);
+ATF_TC_HEAD(mmap_block, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) with a block device");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(mmap_block, tc)
+{
+ static const int mib[] = { CTL_HW, HW_DISKNAMES };
+ static const unsigned int miblen = __arraycount(mib);
+ char *map, *dk, *drives, dev[PATH_MAX];
+ size_t len;
+ int fd = -1;
+
+ atf_tc_skip("The test case causes a panic (PR kern/38889, kern/46592)");
+
+ ATF_REQUIRE(sysctl(mib, miblen, NULL, &len, NULL, 0) == 0);
+ drives = malloc(len);
+ ATF_REQUIRE(drives != NULL);
+ ATF_REQUIRE(sysctl(mib, miblen, drives, &len, NULL, 0) == 0);
+ for (dk = strtok(drives, " "); dk != NULL; dk = strtok(NULL, " ")) {
+ sprintf(dev, _PATH_DEV "%s%c", dk, 'a'+RAW_PART);
+ fprintf(stderr, "trying: %s\n", dev);
+
+ if ((fd = open(dev, O_RDONLY)) >= 0) {
+ (void)fprintf(stderr, "using %s\n", dev);
+ break;
+ }
+ }
+ free(drives);
+
+ if (fd < 0)
+ atf_tc_skip("failed to find suitable block device");
+
+ map = mmap(NULL, 4096, PROT_READ, MAP_FILE, fd, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ (void)fprintf(stderr, "first byte %x\n", *map);
+ ATF_REQUIRE(close(fd) == 0);
+ (void)fprintf(stderr, "first byte %x\n", *map);
+
+ ATF_REQUIRE(munmap(map, 4096) == 0);
+}
+#endif
+
+ATF_TC(mmap_err);
+ATF_TC_HEAD(mmap_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of mmap(2)");
+}
+
+ATF_TC_BODY(mmap_err, tc)
+{
+ size_t addr = SIZE_MAX;
+ void *map;
+
+ errno = 0;
+ map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, -1, 0);
+
+ ATF_REQUIRE(map == MAP_FAILED);
+ ATF_REQUIRE(errno == EBADF);
+
+ errno = 0;
+ map = mmap(&addr, page, PROT_READ, MAP_FIXED|MAP_PRIVATE, -1, 0);
+
+ ATF_REQUIRE(map == MAP_FAILED);
+ ATF_REQUIRE(errno == EINVAL);
+
+ errno = 0;
+ map = mmap(NULL, page, PROT_READ, MAP_ANON|MAP_PRIVATE, INT_MAX, 0);
+
+ ATF_REQUIRE(map == MAP_FAILED);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+ATF_TC_WITH_CLEANUP(mmap_loan);
+ATF_TC_HEAD(mmap_loan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test uvm page loanout with mmap(2)");
+}
+
+ATF_TC_BODY(mmap_loan, tc)
+{
+ char buf[BUFSIZE];
+ char *vp, *vp2;
+ int fd;
+
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+ ATF_REQUIRE(fd >= 0);
+
+ (void)memset(buf, 'x', sizeof(buf));
+ (void)write(fd, buf, sizeof(buf));
+
+ vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_PRIVATE, fd, 0);
+
+ ATF_REQUIRE(vp != MAP_FAILED);
+
+ vp2 = vp;
+
+ testloan(vp, vp2, 'A', 0);
+ testloan(vp, vp2, 'B', 1);
+
+ ATF_REQUIRE(munmap(vp, BUFSIZE) == 0);
+
+ vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, fd, 0);
+
+ vp2 = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, fd, 0);
+
+ ATF_REQUIRE(vp != MAP_FAILED);
+ ATF_REQUIRE(vp2 != MAP_FAILED);
+
+ testloan(vp, vp2, 'E', 1);
+
+ ATF_REQUIRE(munmap(vp, BUFSIZE) == 0);
+ ATF_REQUIRE(munmap(vp2, BUFSIZE) == 0);
+}
+
+ATF_TC_CLEANUP(mmap_loan, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mmap_prot_1);
+ATF_TC_HEAD(mmap_prot_1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #1");
+}
+
+ATF_TC_BODY(mmap_prot_1, tc)
+{
+ void *map;
+ int fd;
+
+ /*
+ * Open a file write-only and try to
+ * map it read-only. This should fail.
+ */
+ fd = open(path, O_WRONLY | O_CREAT, 0700);
+
+ if (fd < 0)
+ return;
+
+ ATF_REQUIRE(write(fd, "XXX", 3) == 3);
+
+ map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
+ map_check(map, 1);
+
+ map = mmap(NULL, 3, PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0);
+ map_check(map, 0);
+
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC_CLEANUP(mmap_prot_1, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(mmap_prot_2);
+ATF_TC_HEAD(mmap_prot_2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #2");
+}
+
+ATF_TC_BODY(mmap_prot_2, tc)
+{
+ char buf[2];
+ void *map;
+ pid_t pid;
+ int sta;
+
+ /*
+ * Make a PROT_NONE mapping and try to access it.
+ * If we catch a SIGSEGV, all works as expected.
+ */
+ map = mmap(NULL, page, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR);
+ ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0);
+ }
+
+ (void)wait(&sta);
+
+ ATF_REQUIRE(WIFEXITED(sta) != 0);
+ ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV);
+ ATF_REQUIRE(munmap(map, page) == 0);
+}
+
+ATF_TC_WITH_CLEANUP(mmap_prot_3);
+ATF_TC_HEAD(mmap_prot_3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #3");
+}
+
+ATF_TC_BODY(mmap_prot_3, tc)
+{
+ char buf[2];
+ int fd, sta;
+ void *map;
+ pid_t pid;
+
+ /*
+ * Open a file, change the permissions
+ * to read-only, and try to map it as
+ * PROT_NONE. This should succeed, but
+ * the access should generate SIGSEGV.
+ */
+ fd = open(path, O_RDWR | O_CREAT, 0700);
+
+ if (fd < 0)
+ return;
+
+ ATF_REQUIRE(write(fd, "XXX", 3) == 3);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(chmod(path, 0444) == 0);
+
+ fd = open(path, O_RDONLY);
+ ATF_REQUIRE(fd != -1);
+
+ map = mmap(NULL, 3, PROT_NONE, MAP_FILE | MAP_SHARED, fd, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ pid = fork();
+
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR);
+ ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0);
+ }
+
+ (void)wait(&sta);
+
+ ATF_REQUIRE(WIFEXITED(sta) != 0);
+ ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV);
+ ATF_REQUIRE(munmap(map, 3) == 0);
+}
+
+ATF_TC_CLEANUP(mmap_prot_3, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mmap_truncate);
+ATF_TC_HEAD(mmap_truncate, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) and ftruncate(2)");
+}
+
+ATF_TC_BODY(mmap_truncate, tc)
+{
+ char *map;
+ long i;
+ int fd;
+
+ fd = open(path, O_RDWR | O_CREAT, 0700);
+
+ if (fd < 0)
+ return;
+
+ /*
+ * See that ftruncate(2) works
+ * while the file is mapped.
+ */
+ ATF_REQUIRE(ftruncate(fd, page) == 0);
+
+ map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE,
+ fd, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ for (i = 0; i < page; i++)
+ map[i] = 'x';
+
+ ATF_REQUIRE(ftruncate(fd, 0) == 0);
+ ATF_REQUIRE(ftruncate(fd, page / 8) == 0);
+ ATF_REQUIRE(ftruncate(fd, page / 4) == 0);
+ ATF_REQUIRE(ftruncate(fd, page / 2) == 0);
+ ATF_REQUIRE(ftruncate(fd, page / 12) == 0);
+ ATF_REQUIRE(ftruncate(fd, page / 64) == 0);
+
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC_CLEANUP(mmap_truncate, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(mmap_va0);
+ATF_TC_HEAD(mmap_va0, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) and vm.user_va0_disable");
+}
+
+ATF_TC_BODY(mmap_va0, tc)
+{
+ int flags = MAP_ANON | MAP_FIXED | MAP_PRIVATE;
+ size_t len = sizeof(int);
+ void *map;
+ int val;
+
+ /*
+ * Make an anonymous fixed mapping at zero address. If the address
+ * is restricted as noted in security(7), the syscall should fail.
+ */
+#ifdef __FreeBSD__
+ if (sysctlbyname("security.bsd.map_at_zero", &val, &len, NULL, 0) != 0)
+ atf_tc_fail("failed to read security.bsd.map_at_zero");
+ val = !val; /* 1 == enable map at zero */
+#endif
+#ifdef __NetBSD__
+ if (sysctlbyname("vm.user_va0_disable", &val, &len, NULL, 0) != 0)
+ atf_tc_fail("failed to read vm.user_va0_disable");
+#endif
+
+ map = mmap(NULL, page, PROT_EXEC, flags, -1, 0);
+ map_check(map, val);
+
+ map = mmap(NULL, page, PROT_READ, flags, -1, 0);
+ map_check(map, val);
+
+ map = mmap(NULL, page, PROT_WRITE, flags, -1, 0);
+ map_check(map, val);
+
+ map = mmap(NULL, page, PROT_READ|PROT_WRITE, flags, -1, 0);
+ map_check(map, val);
+
+ map = mmap(NULL, page, PROT_EXEC|PROT_READ|PROT_WRITE, flags, -1, 0);
+ map_check(map, val);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, mmap_block);
+#endif
+ ATF_TP_ADD_TC(tp, mmap_err);
+ ATF_TP_ADD_TC(tp, mmap_loan);
+ ATF_TP_ADD_TC(tp, mmap_prot_1);
+ ATF_TP_ADD_TC(tp, mmap_prot_2);
+ ATF_TP_ADD_TC(tp, mmap_prot_3);
+ ATF_TP_ADD_TC(tp, mmap_truncate);
+ ATF_TP_ADD_TC(tp, mmap_va0);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c
new file mode 100644
index 0000000..ee345aa
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c
@@ -0,0 +1,365 @@
+/* $NetBSD: t_mprotect.c,v 1.3 2011/07/20 22:53:44 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_mprotect.c,v 1.3 2011/07/20 22:53:44 jym Exp $");
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#ifdef __NetBSD__
+#include "../common/exec_prot.h"
+#endif
+
+static long page = 0;
+static int pax_global = -1;
+static int pax_enabled = -1;
+static char path[] = "mmap";
+
+static void sighandler(int);
+static bool paxinit(void);
+static bool paxset(int, int);
+
+static void
+sighandler(int signo)
+{
+ _exit(signo);
+}
+
+static bool
+paxinit(void)
+{
+ size_t len = sizeof(int);
+ int rv;
+
+ rv = sysctlbyname("security.pax.mprotect.global",
+ &pax_global, &len, NULL, 0);
+
+ if (rv != 0)
+ return false;
+
+ rv = sysctlbyname("security.pax.mprotect.enabled",
+ &pax_enabled, &len, NULL, 0);
+
+ if (rv != 0)
+ return false;
+
+ return paxset(1, 1);
+}
+
+static bool
+paxset(int global, int enabled)
+{
+ size_t len = sizeof(int);
+ int rv;
+
+ rv = sysctlbyname("security.pax.mprotect.global",
+ NULL, NULL, &global, len);
+
+ if (rv != 0)
+ return false;
+
+ rv = sysctlbyname("security.pax.mprotect.enabled",
+ NULL, NULL, &enabled, len);
+
+ if (rv != 0)
+ return false;
+
+ return true;
+}
+
+
+ATF_TC_WITH_CLEANUP(mprotect_access);
+ATF_TC_HEAD(mprotect_access, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test for EACCES from mprotect(2)");
+}
+
+ATF_TC_BODY(mprotect_access, tc)
+{
+ int prot[2] = { PROT_NONE, PROT_READ };
+ void *map;
+ size_t i;
+ int fd;
+
+ fd = open(path, O_RDONLY | O_CREAT);
+ ATF_REQUIRE(fd >= 0);
+
+ /*
+ * The call should fail with EACCES if we try to mark
+ * a PROT_NONE or PROT_READ file/section as PROT_WRITE.
+ */
+ for (i = 0; i < __arraycount(prot); i++) {
+
+ map = mmap(NULL, page, prot[i], MAP_SHARED, fd, 0);
+
+ if (map == MAP_FAILED)
+ continue;
+
+ errno = 0;
+
+ ATF_REQUIRE(mprotect(map, page, PROT_WRITE) != 0);
+ ATF_REQUIRE(errno == EACCES);
+ ATF_REQUIRE(munmap(map, page) == 0);
+ }
+
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC_CLEANUP(mprotect_access, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(mprotect_err);
+ATF_TC_HEAD(mprotect_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of mprotect(2)");
+}
+
+ATF_TC_BODY(mprotect_err, tc)
+{
+ errno = 0;
+
+ ATF_REQUIRE(mprotect((char *)-1, 1, PROT_READ) != 0);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+#ifdef __NetBSD__
+ATF_TC(mprotect_exec);
+ATF_TC_HEAD(mprotect_exec, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test mprotect(2) executable space protections");
+}
+
+/*
+ * Trivial function -- should fit into a page
+ */
+ATF_TC_BODY(mprotect_exec, tc)
+{
+ pid_t pid;
+ void *map;
+ int sta, xp_support;
+
+ xp_support = exec_prot_support();
+
+ switch (xp_support) {
+ case NOTIMPL:
+ atf_tc_skip(
+ "Execute protection callback check not implemented");
+ break;
+ case NO_XP:
+ atf_tc_skip(
+ "Host does not support executable space protection");
+ break;
+ case PARTIAL_XP: case PERPAGE_XP: default:
+ break;
+ }
+
+ /*
+ * Map a page read/write and copy a trivial assembly function inside.
+ * We will then change the mapping rights:
+ * - first by setting the execution right, and check that we can
+ * call the code found in the allocated page.
+ * - second by removing the execution right. This should generate
+ * a SIGSEGV on architectures that can enforce --x permissions.
+ */
+
+ map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ memcpy(map, (void *)return_one,
+ (uintptr_t)return_one_end - (uintptr_t)return_one);
+
+ /* give r-x rights then call code in page */
+ ATF_REQUIRE(mprotect(map, page, PROT_EXEC|PROT_READ) == 0);
+ ATF_REQUIRE(((int (*)(void))map)() == 1);
+
+ /* remove --x right */
+ ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR);
+ ATF_CHECK(((int (*)(void))map)() == 1);
+ _exit(0);
+ }
+
+ (void)wait(&sta);
+
+ ATF_REQUIRE(munmap(map, page) == 0);
+
+ ATF_REQUIRE(WIFEXITED(sta) != 0);
+
+ switch (xp_support) {
+ case PARTIAL_XP:
+ /* Partial protection might fail; skip the test when it does */
+ if (WEXITSTATUS(sta) != SIGSEGV) {
+ atf_tc_skip("Host only supports "
+ "partial executable space protection");
+ }
+ break;
+ case PERPAGE_XP: default:
+ /* Per-page --x protection should not fail */
+ ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV);
+ break;
+ }
+}
+#endif
+
+ATF_TC(mprotect_pax);
+ATF_TC_HEAD(mprotect_pax, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "PaX restrictions and mprotect(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(mprotect_pax, tc)
+{
+ const int prot[4] = { PROT_NONE, PROT_READ, PROT_WRITE };
+ const char *str = NULL;
+ void *map;
+ size_t i;
+ int rv;
+
+ if (paxinit() != true)
+ return;
+
+ /*
+ * As noted in the original PaX documentation [1],
+ * the following restrictions should apply:
+ *
+ * (1) creating executable anonymous mappings
+ *
+ * (2) creating executable/writable file mappings
+ *
+ * (3) making a non-executable mapping executable
+ *
+ * (4) making an executable/read-only file mapping
+ * writable except for performing relocations
+ * on an ET_DYN ELF file (non-PIC shared library)
+ *
+ * The following will test only the case (3).
+ *
+ * [1] http://pax.grsecurity.net/docs/mprotect.txt
+ *
+ * (Sun Apr 3 11:06:53 EEST 2011.)
+ */
+ for (i = 0; i < __arraycount(prot); i++) {
+
+ map = mmap(NULL, page, prot[i], MAP_ANON, -1, 0);
+
+ if (map == MAP_FAILED)
+ continue;
+
+ rv = mprotect(map, 1, prot[i] | PROT_EXEC);
+
+ (void)munmap(map, page);
+
+ if (rv == 0) {
+ str = "non-executable mapping made executable";
+ goto out;
+ }
+ }
+
+out:
+ if (pax_global != -1 && pax_enabled != -1)
+ (void)paxset(pax_global, pax_enabled);
+
+ if (str != NULL)
+ atf_tc_fail("%s", str);
+}
+
+ATF_TC(mprotect_write);
+ATF_TC_HEAD(mprotect_write, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mprotect(2) write protections");
+}
+
+ATF_TC_BODY(mprotect_write, tc)
+{
+ pid_t pid;
+ void *map;
+ int sta;
+
+ /*
+ * Map a page read/write, change the protection
+ * to read-only with mprotect(2), and try to write
+ * to the page. This should generate a SIGSEGV.
+ */
+ map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ ATF_REQUIRE(strlcpy(map, "XXX", 3) == 3);
+ ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR);
+ ATF_REQUIRE(strlcpy(map, "XXX", 3) == 0);
+ }
+
+ (void)wait(&sta);
+
+ ATF_REQUIRE(WIFEXITED(sta) != 0);
+ ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV);
+ ATF_REQUIRE(munmap(map, page) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+ ATF_TP_ADD_TC(tp, mprotect_access);
+ ATF_TP_ADD_TC(tp, mprotect_err);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, mprotect_exec);
+#endif
+ ATF_TP_ADD_TC(tp, mprotect_pax);
+ ATF_TP_ADD_TC(tp, mprotect_write);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c b/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c
new file mode 100644
index 0000000..b9b3067
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c
@@ -0,0 +1,362 @@
+/* $NetBSD: t_msgctl.c,v 1.4 2014/02/27 00:59:50 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_msgctl.c,v 1.4 2014/02/27 00:59:50 joerg Exp $");
+
+#include <sys/msg.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+#define MSG_KEY 12345689
+#define MSG_MTYPE_1 0x41
+
+struct msg {
+ long mtype;
+ char buf[3];
+};
+
+static void clean(void);
+
+static void
+clean(void)
+{
+ int id;
+
+ if ((id = msgget(MSG_KEY, 0)) != -1)
+ (void)msgctl(id, IPC_RMID, 0);
+}
+
+ATF_TC_WITH_CLEANUP(msgctl_err);
+ATF_TC_HEAD(msgctl_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from msgctl(2)");
+}
+
+ATF_TC_BODY(msgctl_err, tc)
+{
+ const int cmd[] = { IPC_STAT, IPC_SET, IPC_RMID };
+ struct msqid_ds msgds;
+ size_t i;
+ int id;
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, msgctl(id, INT_MAX, &msgds) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, msgctl(id, IPC_STAT, (void *)-1) == -1);
+
+ for (i = 0; i < __arraycount(cmd); i++) {
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, msgctl(-1, cmd[i], &msgds) == -1);
+ }
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgctl_err, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgctl_perm);
+ATF_TC_HEAD(msgctl_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with msgctl(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(msgctl_perm, tc)
+{
+ struct msqid_ds msgds;
+ struct passwd *pw;
+ pid_t pid;
+ int sta;
+ int id;
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ pw = getpwnam("nobody");
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+
+ ATF_REQUIRE(id != -1);
+ ATF_REQUIRE(pw != NULL);
+ ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (setuid(pw->pw_uid) != 0)
+ _exit(EX_OSERR);
+
+ msgds.msg_perm.uid = getuid();
+ msgds.msg_perm.gid = getgid();
+
+ errno = 0;
+
+ if (msgctl(id, IPC_SET, &msgds) == 0)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EPERM)
+ _exit(EXIT_FAILURE);
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ if (msgctl(id, IPC_STAT, &msgds) != 0)
+ _exit(EX_OSERR);
+
+ msgds.msg_qbytes = 1;
+
+ if (msgctl(id, IPC_SET, &msgds) == 0)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EPERM)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0) {
+
+ if (WEXITSTATUS(sta) == EX_OSERR)
+ atf_tc_fail("system call failed");
+
+ if (WEXITSTATUS(sta) == EXIT_FAILURE)
+ atf_tc_fail("UID %u manipulated root's "
+ "message queue", pw->pw_uid);
+ }
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgctl_perm, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgctl_pid);
+ATF_TC_HEAD(msgctl_pid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that PIDs are updated");
+}
+
+ATF_TC_BODY(msgctl_pid, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msqid_ds msgds;
+ int id, sta;
+ pid_t pid;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)sleep(1);
+ (void)wait(&sta);
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
+
+ if (pid != msgds.msg_lspid)
+ atf_tc_fail("the PID of last msgsnd(2) was not updated");
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ (void)msgrcv(id, &msg,
+ sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)sleep(1);
+ (void)wait(&sta);
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
+
+ if (pid != msgds.msg_lrpid)
+ atf_tc_fail("the PID of last msgrcv(2) was not updated");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgctl_pid, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgctl_set);
+ATF_TC_HEAD(msgctl_set, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test msgctl(2) with IPC_SET");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(msgctl_set, tc)
+{
+ struct msqid_ds msgds;
+ struct passwd *pw;
+ int id;
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ pw = getpwnam("nobody");
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+
+ ATF_REQUIRE(id != -1);
+ ATF_REQUIRE(pw != NULL);
+ ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
+
+ msgds.msg_perm.uid = pw->pw_uid;
+
+ if (msgctl(id, IPC_SET, &msgds) != 0)
+ atf_tc_fail("root failed to change the UID of message queue");
+
+ msgds.msg_perm.uid = getuid();
+ msgds.msg_perm.gid = pw->pw_gid;
+
+ if (msgctl(id, IPC_SET, &msgds) != 0)
+ atf_tc_fail("root failed to change the GID of message queue");
+
+ /*
+ * Note: setting the qbytes to zero fails even as root.
+ */
+ msgds.msg_qbytes = 1;
+ msgds.msg_perm.gid = getgid();
+
+ if (msgctl(id, IPC_SET, &msgds) != 0)
+ atf_tc_fail("root failed to change qbytes of message queue");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgctl_set, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgctl_time);
+ATF_TC_HEAD(msgctl_time, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that access times are updated");
+}
+
+ATF_TC_BODY(msgctl_time, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msqid_ds msgds;
+ time_t t;
+ int id;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ t = time(NULL);
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+ (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
+ (void)msgctl(id, IPC_STAT, &msgds);
+
+ if (llabs(t - msgds.msg_stime) > 1)
+ atf_tc_fail("time of last msgsnd(2) was not updated");
+
+ if (msgds.msg_rtime != 0)
+ atf_tc_fail("time of last msgrcv(2) was updated incorrectly");
+
+ t = time(NULL);
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+ (void)msgrcv(id, &msg, sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
+ (void)msgctl(id, IPC_STAT, &msgds);
+
+ if (llabs(t - msgds.msg_rtime) > 1)
+ atf_tc_fail("time of last msgrcv(2) was not updated");
+
+ /*
+ * Note: this is non-zero even after the memset(3).
+ */
+ if (msgds.msg_stime == 0)
+ atf_tc_fail("time of last msgsnd(2) was updated incorrectly");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgctl_time, tc)
+{
+ clean();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, msgctl_err);
+ ATF_TP_ADD_TC(tp, msgctl_perm);
+ ATF_TP_ADD_TC(tp, msgctl_pid);
+ ATF_TP_ADD_TC(tp, msgctl_set);
+ ATF_TP_ADD_TC(tp, msgctl_time);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgget.c b/contrib/netbsd-tests/lib/libc/sys/t_msgget.c
new file mode 100644
index 0000000..e26cde2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msgget.c
@@ -0,0 +1,292 @@
+/* $NetBSD: t_msgget.c,v 1.2 2014/02/27 00:59:50 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_msgget.c,v 1.2 2014/02/27 00:59:50 joerg Exp $");
+
+#include <sys/msg.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <time.h>
+#include <unistd.h>
+
+#define MSG_KEY 12345689
+
+static void clean(void);
+
+static void
+clean(void)
+{
+ int id;
+
+ if ((id = msgget(MSG_KEY, 0)) != -1)
+ (void)msgctl(id, IPC_RMID, 0);
+}
+
+ATF_TC_WITH_CLEANUP(msgget_excl);
+ATF_TC_HEAD(msgget_excl, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test msgget(2) with IPC_EXCL");
+}
+
+ATF_TC_BODY(msgget_excl, tc)
+{
+ int id;
+
+ /*
+ * Create a message queue and re-open it with
+ * O_CREAT and IPC_EXCL set. This should fail.
+ */
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+
+ if (id < 0)
+ atf_tc_fail("failed to create message queue");
+
+ errno = 0;
+
+ if (msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | 0600) != -1)
+ atf_tc_fail("msgget(2) failed for IPC_EXCL");
+
+ ATF_REQUIRE(errno == EEXIST);
+
+ /*
+ * However, the same call should succeed
+ * when IPC_EXCL is not set in the flags.
+ */
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+
+ if (id < 0)
+ atf_tc_fail("msgget(2) failed to re-open");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgget_excl, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgget_exit);
+ATF_TC_HEAD(msgget_exit, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that XSI message queues are "
+ "not removed when the process exits");
+}
+
+ATF_TC_BODY(msgget_exit, tc)
+{
+ int id, sta;
+ pid_t pid;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | 0600) == -1)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("failed to create message queue");
+
+ id = msgget(MSG_KEY, 0);
+
+ if (id == -1)
+ atf_tc_fail("message queue was removed on process exit");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgget_exit, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgget_init);
+ATF_TC_HEAD(msgget_init, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that msgget(2) initializes data structures properly");
+}
+
+ATF_TC_BODY(msgget_init, tc)
+{
+ const uid_t uid = geteuid();
+ const gid_t gid = getegid();
+ struct msqid_ds msgds;
+ time_t t;
+ int id;
+
+ (void)memset(&msgds, 0x9, sizeof(struct msqid_ds));
+
+ t = time(NULL);
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+
+ ATF_REQUIRE(id !=-1);
+ ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
+
+ ATF_CHECK(msgds.msg_qnum == 0);
+ ATF_CHECK(msgds.msg_lspid == 0);
+ ATF_CHECK(msgds.msg_lrpid == 0);
+ ATF_CHECK(msgds.msg_rtime == 0);
+ ATF_CHECK(msgds.msg_stime == 0);
+ ATF_CHECK(msgds.msg_perm.uid == uid);
+ ATF_CHECK(msgds.msg_perm.gid == gid);
+ ATF_CHECK(msgds.msg_perm.cuid == uid);
+ ATF_CHECK(msgds.msg_perm.cgid == gid);
+ ATF_CHECK(msgds.msg_perm.mode == 0600);
+
+ if (llabs(t - msgds.msg_ctime) > 5)
+ atf_tc_fail("msgget(2) initialized current time incorrectly");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgget_init, tc)
+{
+ clean();
+}
+
+ATF_TC(msgget_limit);
+ATF_TC_HEAD(msgget_limit, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test msgget(2) against system limits");
+}
+
+ATF_TC_BODY(msgget_limit, tc)
+{
+ size_t len = sizeof(int);
+ bool fail = false;
+ int i, lim = 0;
+ int *buf;
+
+ if (sysctlbyname("kern.ipc.msgmni", &lim, &len, NULL, 0) != 0)
+ atf_tc_skip("failed to read kern.ipc.msgmni sysctl");
+
+ buf = calloc(lim + 1, sizeof(*buf));
+ ATF_REQUIRE(buf != NULL);
+
+ for (i = 0; i < lim; i++) {
+
+ buf[i] = msgget(MSG_KEY + i, IPC_CREAT | IPC_EXCL | 0600);
+
+ (void)fprintf(stderr, "key[%d] = %d\n", i, buf[i]);
+
+ /*
+ * This test only works when there are zero existing
+ * message queues. Thus, bypass the unit test when
+ * this precondition is not met, for reason or another.
+ */
+ if (buf[i] == -1)
+ goto out;
+ }
+
+ i++;
+ errno = 0;
+
+ buf[i] = msgget(MSG_KEY + i, IPC_CREAT | IPC_EXCL | 0600);
+
+ if (buf[i] != -1 || errno != ENOSPC)
+ fail = true;
+
+out: /* Remember to clean-up. */
+ for (i = 0; i < lim; i++)
+ (void)msgctl(buf[i], IPC_RMID, 0);
+
+ free(buf);
+
+ if (fail != false)
+ atf_tc_fail("msgget(2) opened more than %d queues", lim);
+}
+
+ATF_TC_WITH_CLEANUP(msgget_mode);
+ATF_TC_HEAD(msgget_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test different modes with msgget(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(msgget_mode, tc)
+{
+ static const mode_t mode[] = {
+ S_IRWXU, S_IRUSR, S_IWUSR, S_IXUSR, S_IRWXG, S_IRGRP,
+ S_IWGRP, S_IXGRP, S_IRWXO, S_IROTH, S_IWOTH, S_IXOTH
+ };
+
+ struct msqid_ds msgds;
+ size_t i;
+ int id;
+
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ (void)fprintf(stderr, "testing mode %d\n", mode[i]);
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ id = msgget(MSG_KEY, IPC_CREAT | IPC_EXCL | (int)mode[i]);
+
+ ATF_REQUIRE(id != -1);
+ ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
+ ATF_REQUIRE(msgds.msg_perm.mode == mode[i]);
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+ }
+}
+
+ATF_TC_CLEANUP(msgget_mode, tc)
+{
+ clean();
+}
+
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, msgget_excl);
+ ATF_TP_ADD_TC(tp, msgget_exit);
+ ATF_TP_ADD_TC(tp, msgget_init);
+ ATF_TP_ADD_TC(tp, msgget_limit);
+ ATF_TP_ADD_TC(tp, msgget_mode);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c
new file mode 100644
index 0000000..70f8906
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c
@@ -0,0 +1,346 @@
+/* $NetBSD: t_msgrcv.c,v 1.3 2013/07/24 11:44:10 skrll Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_msgrcv.c,v 1.3 2013/07/24 11:44:10 skrll Exp $");
+
+#include <sys/msg.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+#define MSG_KEY 1234
+#define MSG_MTYPE_1 0x41
+#define MSG_MTYPE_2 0x42
+#define MSG_MTYPE_3 0x43
+#define MSG_LEN 3
+
+struct msg {
+ long mtype;
+ char buf[MSG_LEN];
+};
+
+static void clean(void);
+
+static void
+clean(void)
+{
+ int id;
+
+ if ((id = msgget(MSG_KEY, 0)) != -1)
+ (void)msgctl(id, IPC_RMID, 0);
+}
+
+ATF_TC_WITH_CLEANUP(msgrcv_basic);
+ATF_TC_HEAD(msgrcv_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of msgrcv(2)");
+}
+
+ATF_TC_BODY(msgrcv_basic, tc)
+{
+ struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msg msg2 = { MSG_MTYPE_1, { 'x', 'y', 'z' } };
+ int id;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT);
+ (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT);
+
+ ATF_CHECK(msg1.buf[0] == msg2.buf[0]);
+ ATF_CHECK(msg1.buf[1] == msg2.buf[1]);
+ ATF_CHECK(msg1.buf[2] == msg2.buf[2]);
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_basic, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgrcv_block);
+ATF_TC_HEAD(msgrcv_block, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that msgrcv(2) blocks");
+}
+
+ATF_TC_BODY(msgrcv_block, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ int id, sta;
+ pid_t pid;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1, 0) < 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ /*
+ * Below msgsnd(2) should unblock the child,
+ * and hence kill(2) should fail with ESRCH.
+ */
+ (void)sleep(1);
+ (void)msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT);
+ (void)sleep(1);
+ (void)kill(pid, SIGKILL);
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0)
+ atf_tc_fail("msgrcv(2) did not block");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_block, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgrcv_err);
+ATF_TC_HEAD(msgrcv_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from msgrcv(2)");
+}
+
+ATF_TC_BODY(msgrcv_err, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ int id, r = 0;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(ENOMSG, msgrcv(id, &msg,
+ MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1);
+
+ ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EFAULT, msgrcv(id, (void *)-1,
+ MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg,
+ MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg,
+ SSIZE_MAX, MSG_MTYPE_1, IPC_NOWAIT) == -1);
+
+ ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(E2BIG, msgrcv(id, &r,
+ MSG_LEN - 1, MSG_MTYPE_1, IPC_NOWAIT) == -1);
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_err, tc)
+{
+ clean();
+}
+
+
+ATF_TC_WITH_CLEANUP(msgrcv_mtype);
+ATF_TC_HEAD(msgrcv_mtype, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test message types with msgrcv(2)");
+}
+
+ATF_TC_BODY(msgrcv_mtype, tc)
+{
+ struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msg msg2 = { MSG_MTYPE_3, { 'x', 'y', 'z' } };
+ int id;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT);
+ (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_2, IPC_NOWAIT);
+
+ ATF_CHECK(msg1.buf[0] != msg2.buf[0]); /* Different mtype. */
+ ATF_CHECK(msg1.buf[1] != msg2.buf[1]);
+ ATF_CHECK(msg1.buf[2] != msg2.buf[2]);
+
+ (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT);
+
+ ATF_CHECK(msg1.buf[0] == msg2.buf[0]); /* Same mtype. */
+ ATF_CHECK(msg1.buf[1] == msg2.buf[1]);
+ ATF_CHECK(msg1.buf[2] == msg2.buf[2]);
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_mtype, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgrcv_nonblock);
+ATF_TC_HEAD(msgrcv_nonblock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with IPC_NOWAIT");
+ atf_tc_set_md_var(tc, "timeout", "10");
+}
+
+ATF_TC_BODY(msgrcv_nonblock, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ const ssize_t n = 10;
+ int id, sta;
+ ssize_t i;
+ pid_t pid;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ for (i = 0; i < n; i++) {
+
+ ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0);
+ }
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ while (i != 0) {
+
+ if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1,
+ IPC_NOWAIT) == -1)
+ _exit(EXIT_FAILURE);
+
+ i--;
+ }
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)sleep(2);
+ (void)kill(pid, SIGKILL);
+ (void)wait(&sta);
+
+ if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL)
+ atf_tc_fail("msgrcv(2) blocked with IPC_NOWAIT");
+
+ if (WIFEXITED(sta) == 0 && WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("msgrcv(2) failed");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_nonblock, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgrcv_truncate);
+ATF_TC_HEAD(msgrcv_truncate, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with MSG_NOERROR");
+}
+
+ATF_TC_BODY(msgrcv_truncate, tc)
+{
+#define MSG_SMALLLEN 2
+ struct msgsmall {
+ long mtype;
+ char buf[MSG_SMALLLEN];
+ };
+
+ struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msgsmall msg2 = { MSG_MTYPE_1, { 'x', 'y' } };
+ int id;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT);
+ (void)msgrcv(id, &msg2, MSG_SMALLLEN,
+ MSG_MTYPE_1, IPC_NOWAIT | MSG_NOERROR);
+
+ ATF_CHECK(msg1.buf[0] == msg2.buf[0]);
+ ATF_CHECK(msg1.buf[1] == msg2.buf[1]);
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_truncate, tc)
+{
+ clean();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, msgrcv_basic);
+ ATF_TP_ADD_TC(tp, msgrcv_block);
+ ATF_TP_ADD_TC(tp, msgrcv_err);
+ ATF_TP_ADD_TC(tp, msgrcv_mtype);
+ ATF_TP_ADD_TC(tp, msgrcv_nonblock);
+ ATF_TP_ADD_TC(tp, msgrcv_truncate);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c
new file mode 100644
index 0000000..d30cb7b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c
@@ -0,0 +1,342 @@
+/* $NetBSD: t_msgsnd.c,v 1.2 2011/11/05 08:47:54 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_msgsnd.c,v 1.2 2011/11/05 08:47:54 jruoho Exp $");
+
+#include <sys/msg.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+#define MSG_KEY 1234
+#define MSG_MTYPE_1 0x41
+#define MSG_MTYPE_2 0x42
+#define MSG_MTYPE_3 0x43
+
+struct msg {
+ long mtype;
+ char buf[3];
+};
+
+static void clean(void);
+
+static void
+clean(void)
+{
+ int id;
+
+ if ((id = msgget(MSG_KEY, 0)) != -1)
+ (void)msgctl(id, IPC_RMID, 0);
+}
+
+ATF_TC_WITH_CLEANUP(msgsnd_block);
+ATF_TC_HEAD(msgsnd_block, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that msgsnd(2) blocks");
+ atf_tc_set_md_var(tc, "timeout", "10");
+}
+
+ATF_TC_BODY(msgsnd_block, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ int id, sta;
+ pid_t pid;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * Enqueue messages until some limit (e.g. the maximum
+ * number of messages in the queue or the maximum number
+ * of bytes in the queue) is reached. After this the call
+ * should block when the IPC_NOWAIT is not set.
+ */
+ for (;;) {
+
+ if (msgsnd(id, &msg, sizeof(struct msg), 0) < 0)
+ _exit(EXIT_FAILURE);
+ }
+ }
+
+ (void)sleep(2);
+ (void)kill(pid, SIGKILL);
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) != 0 || WIFSIGNALED(sta) == 0)
+ atf_tc_fail("msgsnd(2) did not block");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgsnd_block, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgsnd_count);
+ATF_TC_HEAD(msgsnd_count, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that msgsnd(2) increments the amount of "
+ "message in the queue, as given by msgctl(2)");
+ atf_tc_set_md_var(tc, "timeout", "10");
+}
+
+ATF_TC_BODY(msgsnd_count, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msqid_ds ds;
+ size_t i = 0;
+ int id, rv;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ for (;;) {
+
+ errno = 0;
+ rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
+
+ if (rv == 0) {
+ i++;
+ continue;
+ }
+
+ if (rv == -1 && errno == EAGAIN)
+ break;
+
+ atf_tc_fail("failed to enqueue a message");
+ }
+
+ (void)memset(&ds, 0, sizeof(struct msqid_ds));
+ (void)msgctl(id, IPC_STAT, &ds);
+
+ if (ds.msg_qnum != i)
+ atf_tc_fail("incorrect message count");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgsnd_count, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgsnd_err);
+ATF_TC_HEAD(msgsnd_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from msgsnd(2)");
+}
+
+ATF_TC_BODY(msgsnd_err, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ int id;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EFAULT, msgsnd(id, (void *)-1,
+ sizeof(struct msg), IPC_NOWAIT) == -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg,
+ sizeof(struct msg), IPC_NOWAIT) == -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg,
+ SSIZE_MAX, IPC_NOWAIT) == -1);
+
+ errno = 0;
+ msg.mtype = 0;
+
+ ATF_REQUIRE_ERRNO(EINVAL, msgsnd(id, &msg,
+ sizeof(struct msg), IPC_NOWAIT) == -1);
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgsnd_err, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgsnd_nonblock);
+ATF_TC_HEAD(msgsnd_nonblock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test msgsnd(2) with IPC_NOWAIT");
+ atf_tc_set_md_var(tc, "timeout", "10");
+}
+
+ATF_TC_BODY(msgsnd_nonblock, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ int id, rv, sta;
+ pid_t pid;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ for (;;) {
+
+ errno = 0;
+ rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
+
+ if (rv == -1 && errno == EAGAIN)
+ _exit(EXIT_SUCCESS);
+ }
+ }
+
+ (void)sleep(2);
+ (void)kill(pid, SIGKILL);
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0)
+ atf_tc_fail("msgsnd(2) blocked with IPC_NOWAIT");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgsnd_nonblock, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgsnd_perm);
+ATF_TC_HEAD(msgsnd_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with msgsnd(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(msgsnd_perm, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct passwd *pw;
+ int id, sta;
+ pid_t pid;
+ uid_t uid;
+
+ pw = getpwnam("nobody");
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+
+ ATF_REQUIRE(id != -1);
+ ATF_REQUIRE(pw != NULL);
+
+ uid = pw->pw_uid;
+ ATF_REQUIRE(uid != 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * Try to enqueue a message to the queue
+ * created by root as RW for owner only.
+ */
+ if (setuid(uid) != 0)
+ _exit(EX_OSERR);
+
+ id = msgget(MSG_KEY, 0);
+
+ if (id == -1)
+ _exit(EX_OSERR);
+
+ errno = 0;
+
+ if (msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT) == 0)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EACCES)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
+
+ if (errno == EX_OSERR)
+ atf_tc_fail("system call failed");
+
+ atf_tc_fail("UID %u enqueued message to root's queue", uid);
+ }
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgsnd_perm, tc)
+{
+ clean();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, msgsnd_block);
+ ATF_TP_ADD_TC(tp, msgsnd_count);
+ ATF_TP_ADD_TC(tp, msgsnd_err);
+ ATF_TP_ADD_TC(tp, msgsnd_nonblock);
+ ATF_TP_ADD_TC(tp, msgsnd_perm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msync.c b/contrib/netbsd-tests/lib/libc/sys/t_msync.c
new file mode 100644
index 0000000..70d0ccf
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msync.c
@@ -0,0 +1,248 @@
+/* $NetBSD: t_msync.c,v 1.2 2012/03/16 06:15:17 matt Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_msync.c,v 1.2 2012/03/16 06:15:17 matt Exp $");
+
+#include <sys/mman.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static long page = 0;
+static const off_t off = 512;
+static const char path[] = "msync";
+
+static const char *msync_sync(const char *, int);
+
+static const char *
+msync_sync(const char *garbage, int flags)
+{
+ char *buf, *map = MAP_FAILED;
+ const char *str = NULL;
+ size_t i, len;
+ ssize_t tot;
+ int fd, rv;
+
+ /*
+ * Create a temporary file, write
+ * one page to it, and map the file.
+ */
+ buf = malloc(page);
+
+ if (buf == NULL)
+ return NULL;
+
+ for (i = 0; i < (size_t)page; i++)
+ buf[i] = 'x';
+
+ fd = open(path, O_RDWR | O_CREAT, 0700);
+
+ if (fd < 0) {
+ str = "failed to open";
+ goto out;
+ }
+
+ tot = 0;
+
+ while (tot < page) {
+
+ rv = write(fd, buf, sizeof(buf));
+
+ if (rv < 0) {
+ str = "failed to write";
+ goto out;
+ }
+
+ tot += rv;
+ }
+
+ map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE,
+ fd, 0);
+
+ if (map == MAP_FAILED) {
+ str = "failed to map";
+ goto out;
+ }
+
+ /*
+ * Seek to an arbitrary offset and
+ * write garbage to this position.
+ */
+ if (lseek(fd, off, SEEK_SET) != off) {
+ str = "failed to seek";
+ goto out;
+ }
+
+ len = strlen(garbage);
+ rv = write(fd, garbage, len);
+
+ if (rv != (ssize_t)len) {
+ str = "failed to write garbage";
+ goto out;
+ }
+
+ /*
+ * Synchronize the mapping and verify
+ * that garbage is at the given offset.
+ */
+ if (msync(map, page, flags) != 0) {
+ str = "failed to msync";
+ goto out;
+ }
+
+ if (memcmp(map + off, garbage, len) != 0) {
+ str = "msync did not synchronize";
+ goto out;
+ }
+
+out:
+ free(buf);
+
+ (void)close(fd);
+ (void)unlink(path);
+
+ if (map != MAP_FAILED)
+ (void)munmap(map, page);
+
+ return str;
+}
+
+ATF_TC(msync_async);
+ATF_TC_HEAD(msync_async, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_ASYNC");
+}
+
+ATF_TC_BODY(msync_async, tc)
+{
+ const char *str;
+
+ str = msync_sync("garbage", MS_ASYNC);
+
+ if (str != NULL)
+ atf_tc_fail("%s", str);
+}
+
+ATF_TC(msync_err);
+ATF_TC_HEAD(msync_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions in msync(2)");
+}
+
+ATF_TC_BODY(msync_err, tc)
+{
+
+ char *map = MAP_FAILED;
+
+ /*
+ * Test that invalid flags error out.
+ */
+#ifdef __FreeBSD__
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, msync_sync("error", -1) != NULL);
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, msync_sync("error", INT_MAX) != NULL);
+#else
+ ATF_REQUIRE(msync_sync("error", -1) != NULL);
+ ATF_REQUIRE(msync_sync("error", INT_MAX) != NULL);
+#endif
+
+ errno = 0;
+
+ /*
+ * Map a page and then unmap to get an unmapped address.
+ */
+ map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
+ -1, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ (void)munmap(map, page);
+
+ ATF_REQUIRE(msync(map, page, MS_SYNC) != 0);
+#ifdef __FreeBSD__
+ ATF_REQUIRE(errno == ENOMEM);
+#else
+ ATF_REQUIRE(errno == EFAULT);
+#endif
+}
+
+ATF_TC(msync_invalidate);
+ATF_TC_HEAD(msync_invalidate, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_INVALIDATE");
+}
+
+ATF_TC_BODY(msync_invalidate, tc)
+{
+ const char *str;
+
+ str = msync_sync("garbage", MS_INVALIDATE);
+
+ if (str != NULL)
+ atf_tc_fail("%s", str);
+}
+
+ATF_TC(msync_sync);
+ATF_TC_HEAD(msync_sync, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_SYNC");
+}
+
+ATF_TC_BODY(msync_sync, tc)
+{
+ const char *str;
+
+ str = msync_sync("garbage", MS_SYNC);
+
+ if (str != NULL)
+ atf_tc_fail("%s", str);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ page = sysconf(_SC_PAGESIZE);
+
+ ATF_REQUIRE(page >= 0);
+ ATF_REQUIRE(page > off);
+
+ ATF_TP_ADD_TC(tp, msync_async);
+ ATF_TP_ADD_TC(tp, msync_err);
+ ATF_TP_ADD_TC(tp, msync_invalidate);
+ ATF_TP_ADD_TC(tp, msync_sync);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c
new file mode 100644
index 0000000..b4d9f8a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c
@@ -0,0 +1,191 @@
+/* $NetBSD: t_nanosleep.c,v 1.3 2013/03/31 16:47:16 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_nanosleep.c,v 1.3 2013/03/31 16:47:16 christos Exp $");
+
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <time.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+static void
+#ifdef __FreeBSD__
+handler(int signo __unused)
+#else
+handler(int signo)
+#endif
+{
+ /* Nothing. */
+}
+
+ATF_TC(nanosleep_basic);
+ATF_TC_HEAD(nanosleep_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that nanosleep(2) works");
+}
+
+ATF_TC_BODY(nanosleep_basic, tc)
+{
+ static const size_t maxiter = 10;
+ struct timespec ts1, ts2, tsn;
+ size_t i;
+
+ for (i = 1; i < maxiter; i++) {
+
+ tsn.tv_sec = 0;
+ tsn.tv_nsec = i;
+
+ (void)memset(&ts1, 0, sizeof(struct timespec));
+ (void)memset(&ts2, 0, sizeof(struct timespec));
+
+ ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts1) == 0);
+ ATF_REQUIRE(nanosleep(&tsn, NULL) == 0);
+ ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts2) == 0);
+
+ /*
+ * Verify that we slept at least one nanosecond.
+ */
+ if (timespeccmp(&ts2, &ts1, <=) != 0) {
+
+ (void)fprintf(stderr,
+ "sleep time:: sec %llu, nsec %lu\n\t\t"
+ "ts1: sec %llu, nsec %lu\n\t\t"
+ "ts2: sec %llu, nsec %lu\n",
+ (unsigned long long)tsn.tv_sec, tsn.tv_nsec,
+ (unsigned long long)ts1.tv_sec, ts1.tv_nsec,
+ (unsigned long long)ts2.tv_sec, ts2.tv_nsec);
+
+ atf_tc_fail_nonfatal("inaccuracies in sleep time "
+ "(resolution = %lu nsec)", tsn.tv_nsec);
+ }
+ }
+}
+
+ATF_TC(nanosleep_err);
+ATF_TC_HEAD(nanosleep_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test errors from nanosleep(2) (PR bin/14558)");
+}
+
+ATF_TC_BODY(nanosleep_err, tc)
+{
+ struct timespec ts;
+
+ ts.tv_sec = 1;
+ ts.tv_nsec = -1;
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, nanosleep(&ts, NULL) == -1);
+
+ ts.tv_sec = 1;
+ ts.tv_nsec = 1000000000;
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, nanosleep(&ts, NULL) == -1);
+
+ ts.tv_sec = -1;
+ ts.tv_nsec = 0;
+ errno = 0;
+ ATF_REQUIRE_ERRNO(0, nanosleep(&ts, NULL) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, nanosleep((void *)-1, NULL) == -1);
+}
+
+ATF_TC(nanosleep_sig);
+ATF_TC_HEAD(nanosleep_sig, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test signal for nanosleep(2)");
+}
+
+ATF_TC_BODY(nanosleep_sig, tc)
+{
+ struct timespec tsn, tsr;
+ pid_t pid;
+ int sta;
+
+ /*
+ * Test that a signal interrupts nanosleep(2).
+ *
+ * (In which case the return value should be -1 and the
+ * second parameter should contain the unslept time.)
+ */
+ pid = fork();
+
+ ATF_REQUIRE(pid >= 0);
+ ATF_REQUIRE(signal(SIGINT, handler) == 0);
+
+ if (pid == 0) {
+
+ tsn.tv_sec = 10;
+ tsn.tv_nsec = 0;
+
+ tsr.tv_sec = 0;
+ tsr.tv_nsec = 0;
+
+ errno = 0;
+
+ if (nanosleep(&tsn, &tsr) != -1)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EINTR)
+ _exit(EXIT_FAILURE);
+
+ if (tsr.tv_sec == 0 && tsr.tv_nsec == 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)sleep(1);
+ (void)kill(pid, SIGINT);
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("signal did not interrupt nanosleep(2)");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, nanosleep_basic);
+ ATF_TP_ADD_TC(tp, nanosleep_err);
+ ATF_TP_ADD_TC(tp, nanosleep_sig);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_pipe.c b/contrib/netbsd-tests/lib/libc/sys/t_pipe.c
new file mode 100644
index 0000000..b30b94d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_pipe.c
@@ -0,0 +1,163 @@
+/* $NetBSD: t_pipe.c,v 1.3 2011/10/31 15:41:31 christos Exp $ */
+
+/*-
+ * Copyright (c) 2001, 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_pipe.c,v 1.3 2011/10/31 15:41:31 christos Exp $");
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <sched.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "../../../h_macros.h"
+
+static pid_t pid;
+static int nsiginfo = 0;
+
+/*
+ * This is used for both parent and child. Handle parent's SIGALRM,
+ * the childs SIGINFO doesn't need anything.
+ */
+static void
+sighand(int sig)
+{
+ if (sig == SIGALRM) {
+ kill(pid, SIGINFO);
+ }
+ if (sig == SIGINFO) {
+ nsiginfo++;
+ }
+}
+
+ATF_TC(pipe_restart);
+ATF_TC_HEAD(pipe_restart, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that writing to pipe "
+ "works correctly after being interrupted and restarted "
+ "(kern/14087)");
+}
+
+ATF_TC_BODY(pipe_restart, tc)
+{
+ int pp[2], st;
+ ssize_t sz, todo, done;
+ char *f;
+ sigset_t asigset, osigset, emptysigset;
+
+ /* Initialise signal masks */
+ RL(sigemptyset(&emptysigset));
+ RL(sigemptyset(&asigset));
+ RL(sigaddset(&asigset, SIGINFO));
+
+ /* Register signal handlers for both read and writer */
+ REQUIRE_LIBC(signal(SIGINFO, sighand), SIG_ERR);
+ REQUIRE_LIBC(signal(SIGALRM, sighand), SIG_ERR);
+
+ todo = 2 * 1024 * 1024;
+ REQUIRE_LIBC(f = malloc(todo), NULL);
+
+ RL(pipe(pp));
+
+ RL(pid = fork());
+ if (pid == 0) {
+ /* child */
+ RL(close(pp[1]));
+
+ /* Do inital write. This should succeed, make
+ * the other side do partial write and wait for us to pick
+ * rest up.
+ */
+ RL(done = read(pp[0], f, 128 * 1024));
+
+ /* Wait until parent is alarmed and awakens us */
+ RL(sigprocmask(SIG_BLOCK, &asigset, &osigset));
+ while (nsiginfo == 0) {
+ if (sigsuspend(&emptysigset) != -1 || errno != EINTR)
+ atf_tc_fail("sigsuspend(&emptysigset): %s",
+ strerror(errno));
+ }
+ RL(sigprocmask(SIG_SETMASK, &osigset, NULL));
+
+ /* Read all what parent wants to give us */
+ while((sz = read(pp[0], f, 1024 * 1024)) > 0)
+ done += sz;
+
+ /*
+ * Exit with 1 if number of bytes read doesn't match
+ * number of expected bytes
+ */
+ printf("Read: %#zx\n", (size_t)done);
+ printf("Expected: %#zx\n", (size_t)todo);
+
+ exit(done != todo);
+
+ /* NOTREACHED */
+ } else {
+ RL(close(pp[0]));
+
+ /*
+ * Arrange for alarm after two seconds. Since we have
+ * handler setup for SIGARLM, the write(2) call should
+ * be restarted internally by kernel.
+ */
+ (void)alarm(2);
+
+ /* We write exactly 'todo' bytes. The very first write(2)
+ * should partially succeed, block and eventually
+ * be restarted by kernel
+ */
+ while(todo > 0 && ((sz = write(pp[1], f, todo)) > 0))
+ todo -= sz;
+
+ /* Close the pipe, so that child would stop reading */
+ RL(close(pp[1]));
+
+ /* And pickup child's exit status */
+ RL(waitpid(pid, &st, 0));
+
+ ATF_REQUIRE_EQ(WEXITSTATUS(st), 0);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, pipe_restart);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c
new file mode 100644
index 0000000..8208cf7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c
@@ -0,0 +1,210 @@
+/* $NetBSD: t_pipe2.c,v 1.8 2012/05/16 13:54:28 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 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/cdefs.h>
+__RCSID("$NetBSD: t_pipe2.c,v 1.8 2012/05/16 13:54:28 jruoho Exp $");
+
+#include <atf-c.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/resource.h>
+
+static void
+run(int flags)
+{
+ int fd[2], i;
+
+ while ((i = open("/", O_RDONLY)) < 3)
+ ATF_REQUIRE(i != -1);
+
+#ifdef __FreeBSD__
+ closefrom(3);
+#else
+ ATF_REQUIRE(fcntl(3, F_CLOSEM) != -1);
+#endif
+
+ ATF_REQUIRE(pipe2(fd, flags) == 0);
+
+ ATF_REQUIRE(fd[0] == 3);
+ ATF_REQUIRE(fd[1] == 4);
+
+ if (flags & O_CLOEXEC) {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0);
+ } else {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0);
+ }
+
+ if (flags & O_NONBLOCK) {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0);
+ } else {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0);
+ }
+
+#ifndef __FreeBSD__
+ if (flags & O_NOSIGPIPE) {
+ ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) != 0);
+ ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) != 0);
+ } else {
+ ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) == 0);
+ ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) == 0);
+ }
+#endif
+
+ ATF_REQUIRE(close(fd[0]) != -1);
+ ATF_REQUIRE(close(fd[1]) != -1);
+}
+
+ATF_TC(pipe2_basic);
+ATF_TC_HEAD(pipe2_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of pipe2(2)");
+}
+
+ATF_TC_BODY(pipe2_basic, tc)
+{
+ run(0);
+}
+
+ATF_TC(pipe2_consume);
+ATF_TC_HEAD(pipe2_consume, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that consuming file descriptors "
+ "with pipe2(2) does not crash the system (PR kern/46457)");
+}
+
+ATF_TC_BODY(pipe2_consume, tc)
+{
+ struct rlimit rl;
+ int err, filedes[2];
+#ifdef __FreeBSD__
+ int old;
+
+ closefrom(4);
+#else
+ err = fcntl(4, F_CLOSEM);
+ ATF_REQUIRE(err == 0);
+#endif
+
+ err = getrlimit(RLIMIT_NOFILE, &rl);
+ ATF_REQUIRE(err == 0);
+ /*
+ * The heart of this test is to run against the number of open
+ * file descriptor limit in the middle of a pipe2() call - i.e.
+ * before the call only a single descriptor may be openend.
+ */
+#ifdef __FreeBSD__
+ old = rl.rlim_cur;
+#endif
+ rl.rlim_cur = 4;
+ err = setrlimit(RLIMIT_NOFILE, &rl);
+ ATF_REQUIRE(err == 0);
+
+ err = pipe2(filedes, O_CLOEXEC);
+ ATF_REQUIRE(err == -1);
+#ifdef __FreeBSD__
+ rl.rlim_cur = old;
+ err = setrlimit(RLIMIT_NOFILE, &rl);
+#endif
+}
+
+ATF_TC(pipe2_nonblock);
+ATF_TC_HEAD(pipe2_nonblock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A non-blocking test of pipe2(2)");
+}
+
+ATF_TC_BODY(pipe2_nonblock, tc)
+{
+ run(O_NONBLOCK);
+}
+
+ATF_TC(pipe2_cloexec);
+ATF_TC_HEAD(pipe2_cloexec, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A close-on-exec test of pipe2(2)");
+}
+
+ATF_TC_BODY(pipe2_cloexec, tc)
+{
+ run(O_CLOEXEC);
+}
+
+#ifdef __NetBSD__
+ATF_TC(pipe2_nosigpipe);
+ATF_TC_HEAD(pipe2_nosigpipe, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A no sigpipe test of pipe2(2)");
+}
+
+ATF_TC_BODY(pipe2_nosigpipe, tc)
+{
+ run(O_NOSIGPIPE);
+}
+#endif
+
+ATF_TC(pipe2_einval);
+ATF_TC_HEAD(pipe2_einval, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A error check of pipe2(2)");
+}
+
+ATF_TC_BODY(pipe2_einval, tc)
+{
+ int fd[2];
+ ATF_REQUIRE_ERRNO(EINVAL, pipe2(fd, O_ASYNC) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, pipe2_basic);
+ ATF_TP_ADD_TC(tp, pipe2_consume);
+ ATF_TP_ADD_TC(tp, pipe2_nonblock);
+ ATF_TP_ADD_TC(tp, pipe2_cloexec);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, pipe2_nosigpipe);
+#endif
+ ATF_TP_ADD_TC(tp, pipe2_einval);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_poll.c b/contrib/netbsd-tests/lib/libc/sys/t_poll.c
new file mode 100644
index 0000000..6214486
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_poll.c
@@ -0,0 +1,396 @@
+/* $NetBSD: t_poll.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matthias Scheler.
+ *
+ * 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/time.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <poll.h>
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+
+static int desc;
+
+static void
+child1(void)
+{
+ struct pollfd pfd;
+
+ pfd.fd = desc;
+ pfd.events = POLLIN | POLLHUP | POLLOUT;
+
+ (void)poll(&pfd, 1, 2000);
+ (void)printf("child1 exit\n");
+}
+
+static void
+child2(void)
+{
+ struct pollfd pfd;
+
+ pfd.fd = desc;
+ pfd.events = POLLIN | POLLHUP | POLLOUT;
+
+ (void)sleep(1);
+ (void)poll(&pfd, 1, INFTIM);
+ (void)printf("child2 exit\n");
+}
+
+static void
+child3(void)
+{
+ struct pollfd pfd;
+
+ (void)sleep(5);
+
+ pfd.fd = desc;
+ pfd.events = POLLIN | POLLHUP | POLLOUT;
+
+ (void)poll(&pfd, 1, INFTIM);
+ (void)printf("child3 exit\n");
+}
+
+ATF_TC(poll_3way);
+ATF_TC_HEAD(poll_3way, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "15");
+ atf_tc_set_md_var(tc, "descr",
+ "Check for 3-way collision for descriptor. First child comes "
+ "and polls on descriptor, second child comes and polls, first "
+ "child times out and exits, third child comes and polls. When "
+ "the wakeup event happens, the two remaining children should "
+ "both be awaken. (kern/17517)");
+}
+
+ATF_TC_BODY(poll_3way, tc)
+{
+ int pf[2];
+ int status, i;
+ pid_t pid;
+
+ pipe(pf);
+ desc = pf[0];
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ (void)close(pf[1]);
+ child1();
+ _exit(0);
+ /* NOTREACHED */
+ }
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ (void)close(pf[1]);
+ child2();
+ _exit(0);
+ /* NOTREACHED */
+ }
+
+ pid = fork();
+ ATF_REQUIRE( pid >= 0);
+
+ if (pid == 0) {
+ (void)close(pf[1]);
+ child3();
+ _exit(0);
+ /* NOTREACHED */
+ }
+
+ (void)sleep(10);
+
+ (void)printf("parent write\n");
+
+ ATF_REQUIRE(write(pf[1], "konec\n", 6) == 6);
+
+ for(i = 0; i < 3; ++i)
+ (void)wait(&status);
+
+ (void)printf("parent terminated\n");
+}
+
+ATF_TC(poll_basic);
+ATF_TC_HEAD(poll_basic, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "10");
+ atf_tc_set_md_var(tc, "descr",
+ "Basis functionality test for poll(2)");
+}
+
+ATF_TC_BODY(poll_basic, tc)
+{
+ int fds[2];
+ struct pollfd pfds[2];
+ int ret;
+
+ ATF_REQUIRE_EQ(pipe(fds), 0);
+
+ pfds[0].fd = fds[0];
+ pfds[0].events = POLLIN;
+ pfds[1].fd = fds[1];
+ pfds[1].events = POLLOUT;
+
+ /*
+ * Check that we get a timeout waiting for data on the read end
+ * of our pipe.
+ */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[0], 1, 1), 0,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents);
+
+ /* Check that the write end of the pipe as reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[1], 1, 1), 1,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\
+ pfds[1].revents);
+
+ /* Check that only the write end of the pipe as reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 1,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
+ pfds[1].revents);
+
+ /* Write data to our pipe. */
+ ATF_REQUIRE_EQ(write(fds[1], "", 1), 1);
+
+ /* Check that both ends of our pipe are reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 2,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d",
+ pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
+ pfds[1].revents);
+
+ ATF_REQUIRE_EQ(close(fds[0]), 0);
+ ATF_REQUIRE_EQ(close(fds[1]), 0);
+}
+
+ATF_TC(poll_err);
+ATF_TC_HEAD(poll_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check errors from poll(2)");
+}
+
+ATF_TC_BODY(poll_err, tc)
+{
+ struct pollfd pfd;
+ int fd = 0;
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, poll((struct pollfd *)-1, 1, -1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, poll(&pfd, 1, -2) == -1);
+}
+
+#ifndef __FreeBSD__
+ATF_TC(pollts_basic);
+ATF_TC_HEAD(pollts_basic, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "10");
+ atf_tc_set_md_var(tc, "descr",
+ "Basis functionality test for pollts(2)");
+}
+
+ATF_TC_BODY(pollts_basic, tc)
+{
+ int fds[2];
+ struct pollfd pfds[2];
+ struct timespec timeout;
+ int ret;
+
+ ATF_REQUIRE_EQ(pipe(fds), 0);
+
+ pfds[0].fd = fds[0];
+ pfds[0].events = POLLIN;
+ pfds[1].fd = fds[1];
+ pfds[1].events = POLLOUT;
+
+ /* Use a timeout of 1 second. */
+ timeout.tv_sec = 1;
+ timeout.tv_nsec = 0;
+
+ /*
+ * Check that we get a timeout waiting for data on the read end
+ * of our pipe.
+ */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[0], 1, &timeout, NULL), 0,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents);
+
+ /* Check that the write end of the pipe as reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[1], 1, &timeout, NULL), 1,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\
+ pfds[1].revents);
+
+ /* Check that only the write end of the pipe as reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 1,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
+ pfds[1].revents);
+
+ /* Write data to our pipe. */
+ ATF_REQUIRE_EQ(write(fds[1], "", 1), 1);
+
+ /* Check that both ends of our pipe are reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 2,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d",
+ pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
+ pfds[1].revents);
+
+ ATF_REQUIRE_EQ(close(fds[0]), 0);
+ ATF_REQUIRE_EQ(close(fds[1]), 0);
+}
+
+ATF_TC(pollts_err);
+ATF_TC_HEAD(pollts_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check errors from pollts(2)");
+}
+
+ATF_TC_BODY(pollts_err, tc)
+{
+ struct timespec timeout;
+ struct pollfd pfd;
+ int fd = 0;
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ timeout.tv_sec = 1;
+ timeout.tv_nsec = 0;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, pollts((void *)-1, 1, &timeout, NULL) == -1);
+
+ timeout.tv_sec = -1;
+ timeout.tv_nsec = -1;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, pollts(&pfd, 1, &timeout, NULL) == -1);
+}
+
+ATF_TC(pollts_sigmask);
+ATF_TC_HEAD(pollts_sigmask, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "10");
+ atf_tc_set_md_var(tc, "descr",
+ "Check that pollts(2) restores the signal mask (PR kern/44986)");
+}
+
+ATF_TC_BODY(pollts_sigmask, tc)
+{
+ int fd;
+ struct pollfd pfd;
+ struct timespec timeout;
+ sigset_t mask;
+ int ret;
+
+ fd = open(_PATH_DEVNULL, O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ /* Use a timeout of 1 second. */
+ timeout.tv_sec = 1;
+ timeout.tv_nsec = 0;
+
+ /* Unblock all signals. */
+ ATF_REQUIRE_EQ(sigfillset(&mask), 0);
+ ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0);
+
+ /*
+ * Check that pollts(2) immediately returns. We block *all*
+ * signals during pollts(2).
+ */
+ ATF_REQUIRE_EQ_MSG(ret = pollts(&pfd, 1, &timeout, &mask), 1,
+ "got: %d", ret);
+
+ /* Check that signals are now longer blocked. */
+ ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0);
+ ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0,
+ "signal mask was changed.");
+
+ ATF_REQUIRE_EQ(close(fd), 0);
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, poll_3way);
+ ATF_TP_ADD_TC(tp, poll_basic);
+ ATF_TP_ADD_TC(tp, poll_err);
+#ifndef __FreeBSD__
+ ATF_TP_ADD_TC(tp, pollts_basic);
+ ATF_TP_ADD_TC(tp, pollts_err);
+ ATF_TP_ADD_TC(tp, pollts_sigmask);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c b/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c
new file mode 100644
index 0000000..da4e746
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c
@@ -0,0 +1,165 @@
+/* $NetBSD: t_posix_fadvise.c,v 1.1 2011/10/15 06:10:26 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by YAMAMOTO Takashi.
+ *
+ * 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 (c)2005 YAMAMOTO Takashi,
+ * 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 AUTHOR 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 AUTHOR 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_posix_fadvise.c,v 1.1 2011/10/15 06:10:26 jruoho Exp $");
+
+#include <sys/fcntl.h>
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "../../../h_macros.h"
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+ATF_TC(posix_fadvise);
+ATF_TC_HEAD(posix_fadvise, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks posix_fadvise(2)");
+}
+
+ATF_TC(posix_fadvise_reg);
+ATF_TC_HEAD(posix_fadvise_reg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks posix_fadvise(2) "
+ "for regular files");
+}
+
+ATF_TC_BODY(posix_fadvise, tc)
+{
+ int fd;
+ int pipe_fds[2];
+ int badfd = 10;
+ int ret;
+
+ RL(fd = open("/dev/null", O_RDWR));
+
+ (void)close(badfd);
+ RL(pipe(pipe_fds));
+
+ /*
+ * it's hard to check if posix_fadvise is working properly.
+ * only check return values here.
+ */
+
+ /* posix_fadvise shouldn't affect errno. */
+
+#define CE(x, exp) \
+ do { \
+ int save = errno; \
+ errno = 999; \
+ ATF_CHECK_EQ_MSG(ret = (x), exp, "got: %d", ret); \
+ ATF_CHECK_EQ_MSG(errno, 999, "got: %s", strerror(errno)); \
+ errno = save; \
+ } while (0);
+
+ CE(posix_fadvise(fd, 0, 0, -1), EINVAL);
+ CE(posix_fadvise(pipe_fds[0], 0, 0, POSIX_FADV_NORMAL), ESPIPE);
+ CE(posix_fadvise(badfd, 0, 0, POSIX_FADV_NORMAL), EBADF);
+ CE(posix_fadvise(fd, 0, 0, POSIX_FADV_NORMAL), 0);
+ CE(posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL), 0);
+ CE(posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM), 0);
+ CE(posix_fadvise(fd, 0, 0, POSIX_FADV_WILLNEED), 0);
+ CE(posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED), 0);
+ CE(posix_fadvise(fd, 0, 0, POSIX_FADV_NOREUSE), 0);
+}
+
+ATF_TC_BODY(posix_fadvise_reg, tc)
+{
+ int rfd, ret;
+
+ rump_init();
+ RL(rfd = rump_sys_open("/a_file", O_CREAT, 0666));
+
+ CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_NORMAL), 0);
+ CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_SEQUENTIAL), 0);
+ CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_RANDOM), 0);
+ CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_WILLNEED), 0);
+ CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_NOREUSE), 0);
+
+ CE(rump_sys_posix_fadvise(rfd,
+ INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_NORMAL), 0);
+ CE(rump_sys_posix_fadvise(rfd,
+ INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_SEQUENTIAL), 0);
+ CE(rump_sys_posix_fadvise(rfd,
+ INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_RANDOM), 0);
+ CE(rump_sys_posix_fadvise(rfd,
+ INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_WILLNEED), 0);
+ CE(rump_sys_posix_fadvise(rfd,
+ INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_NOREUSE), 0);
+
+ //atf_tc_expect_signal(-1, "http://mail-index.netbsd.org/source-changes-d/2010/11/11/msg002508.html");
+ CE(rump_sys_posix_fadvise(rfd,
+ INT64_MAX-getpagesize(), getpagesize(), POSIX_FADV_DONTNEED), 0);
+ CE(rump_sys_posix_fadvise(rfd, 0, 0, POSIX_FADV_DONTNEED), 0);
+#undef CE
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, posix_fadvise);
+ ATF_TP_ADD_TC(tp, posix_fadvise_reg);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c b/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c
new file mode 100644
index 0000000..76bc7dd
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c
@@ -0,0 +1,161 @@
+/* $NetBSD: t_recvmmsg.c,v 1.1 2012/06/22 18:45:23 christos Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jared McNeill and Christos Zoulas.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 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/cdefs.h>
+__RCSID("$NetBSD: t_recvmmsg.c,v 1.1 2012/06/22 18:45:23 christos Exp $");
+
+#include <atf-c.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#include <string.h>
+#include <time.h>
+#include <stdint.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sched.h>
+
+#define BUFSIZE 65536
+#define NPKTS 50
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+static int debug;
+
+
+ATF_TC(recvmmsg_basic);
+ATF_TC_HEAD(recvmmsg_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of recvmmsg(2)");
+}
+
+ATF_TC_BODY(recvmmsg_basic, tc)
+{
+ int fd[2], error, i, cnt;
+ uint8_t *buf;
+ struct mmsghdr *mmsghdr;
+ struct iovec *iov;
+ unsigned int mmsgcnt, n;
+ int status;
+ off_t off;
+ uint8_t DGRAM[1316] = { 0, 2, 3, 4, 5, 6, 7, 8, 9, };
+
+ error = socketpair(AF_UNIX, SOCK_DGRAM, 0, fd);
+ ATF_REQUIRE_MSG(error != -1, "socketpair failed (%s)", strerror(errno));
+
+ buf = malloc(BUFSIZE);
+ ATF_REQUIRE_MSG(buf != NULL, "malloc failed (%s)", strerror(errno));
+
+ mmsgcnt = BUFSIZE / sizeof(DGRAM);
+ mmsghdr = malloc(sizeof(*mmsghdr) * mmsgcnt);
+ ATF_REQUIRE_MSG(mmsghdr != NULL, "malloc failed (%s)", strerror(errno));
+ iov = malloc(sizeof(*iov) * mmsgcnt);
+ ATF_REQUIRE_MSG(iov != NULL, "malloc failed (%s)", strerror(errno));
+
+ for (off = 0, n = 0; n < mmsgcnt; n++) {
+ iov[n].iov_base = buf + off;
+ iov[n].iov_len = sizeof(DGRAM);
+ off += iov[n].iov_len;
+ mmsghdr[n].msg_hdr.msg_iov = &iov[n];
+ mmsghdr[n].msg_hdr.msg_iovlen = 1;
+ mmsghdr[n].msg_hdr.msg_name = NULL;
+ mmsghdr[n].msg_hdr.msg_namelen = 0;
+ }
+
+ switch (fork()) {
+ case -1:
+ ATF_REQUIRE_MSG(0, "fork failed (%s)", strerror(errno));
+ break;
+
+ case 0:
+ n = NPKTS;
+ if (debug)
+ printf("waiting for %u messages (max %u per syscall)\n", n,
+ mmsgcnt);
+ while (n > 0) {
+ struct timespec ts = { 1, 0 };
+ cnt = recvmmsg(fd[1], mmsghdr, min(mmsgcnt, n),
+ MSG_WAITALL, &ts);
+ ATF_REQUIRE_MSG(cnt != -1, "recvmmsg failed (%s)",
+ strerror(errno));
+ ATF_REQUIRE_MSG(cnt != 0, "recvmmsg timeout");
+ if (debug)
+ printf("recvmmsg: got %u messages\n", cnt);
+ for (i = 0; i < cnt; i++) {
+ ATF_CHECK_EQ_MSG(mmsghdr[i].msg_len,
+ sizeof(DGRAM), "packet length");
+ ATF_CHECK_EQ_MSG(
+ ((uint8_t *)iov[i].iov_base)[0],
+ NPKTS - n + i, "packet contents");
+ }
+ n -= cnt;
+ }
+ if (debug)
+ printf("done!\n");
+ exit(0);
+ /*NOTREACHED*/
+ default:
+ sched_yield();
+
+ for (n = 0; n < NPKTS; n++) {
+ if (debug)
+ printf("sending packet %u/%u...\n", (n+1),
+ NPKTS);
+ do {
+ DGRAM[0] = n;
+ error = send(fd[0], DGRAM, sizeof(DGRAM), 0);
+ } while (error == -1 && errno == ENOBUFS);
+ if (error == -1)
+ ATF_REQUIRE_MSG(error != -1, "send failed (%s)",
+ strerror(errno));
+ }
+ error = wait(&status);
+ ATF_REQUIRE_MSG(error != -1, "wait failed (%s)",
+ strerror(errno));
+ break;
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, recvmmsg_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_revoke.c b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c
new file mode 100644
index 0000000..926d2740
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c
@@ -0,0 +1,195 @@
+/* $NetBSD: t_revoke.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_revoke.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $");
+
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char path[] = "revoke";
+
+ATF_TC_WITH_CLEANUP(revoke_basic);
+ATF_TC_HEAD(revoke_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of revoke(2)");
+}
+
+ATF_TC_BODY(revoke_basic, tc)
+{
+ struct rlimit res;
+ char tmp[10];
+ size_t i, n;
+ int *buf;
+
+#ifdef __FreeBSD__
+ atf_tc_skip("revoke(2) is only implemented for devfs(5).");
+#endif
+ (void)memset(&res, 0, sizeof(struct rlimit));
+ (void)getrlimit(RLIMIT_NOFILE, &res);
+
+ if ((n = res.rlim_cur / 10) == 0)
+ n = 10;
+
+ buf = calloc(n, sizeof(int));
+ ATF_REQUIRE(buf != NULL);
+
+ buf[0] = open(path, O_RDWR | O_CREAT, 0600);
+ ATF_REQUIRE(buf[0] >= 0);
+
+ for (i = 1; i < n; i++) {
+ buf[i] = open(path, O_RDWR);
+ ATF_REQUIRE(buf[i] >= 0);
+ }
+
+ ATF_REQUIRE(revoke(path) == 0);
+
+ for (i = 0; i < n; i++) {
+
+ ATF_REQUIRE(read(buf[i], tmp, sizeof(tmp)) == -1);
+
+ (void)close(buf[i]);
+ }
+
+ free(buf);
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(revoke_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(revoke_err);
+ATF_TC_HEAD(revoke_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from revoke(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(revoke_err, tc)
+{
+ char buf[1024 + 1]; /* XXX: From the manual page... */
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, revoke((char *)-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, revoke(buf) == -1);
+
+#ifdef __FreeBSD__
+ atf_tc_skip("revoke(2) is only implemented for devfs(5).");
+#endif
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EPERM, revoke("/etc/passwd") == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, revoke("/etc/xxx/yyy") == -1);
+}
+
+ATF_TC_WITH_CLEANUP(revoke_perm);
+ATF_TC_HEAD(revoke_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions revoke(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(revoke_perm, tc)
+{
+ struct passwd *pw;
+ int fd, sta;
+ pid_t pid;
+
+#ifdef __FreeBSD__
+ atf_tc_skip("revoke(2) is only implemented for devfs(5).");
+#endif
+ pw = getpwnam("nobody");
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(pw != NULL);
+ ATF_REQUIRE(revoke(path) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (setuid(pw->pw_uid) != 0)
+ _exit(EXIT_FAILURE);
+
+ errno = 0;
+
+ if (revoke(path) == 0)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EACCES)
+ _exit(EXIT_FAILURE);
+
+ if (close(fd) != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("revoke(2) did not obey permissions");
+
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(revoke_perm, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, revoke_basic);
+ ATF_TP_ADD_TC(tp, revoke_err);
+ ATF_TP_ADD_TC(tp, revoke_perm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_select.c b/contrib/netbsd-tests/lib/libc/sys/t_select.c
new file mode 100644
index 0000000..7af725a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_select.c
@@ -0,0 +1,223 @@
+/* $NetBSD: t_select.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundatiom
+ * by Christos Zoulas.
+ *
+ * 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 <assert.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+#include <err.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <atf-c.h>
+
+static sig_atomic_t keep_going = 1;
+
+static void
+#ifdef __FreeBSD__
+sig_handler(int signum __unused)
+#else
+sig_handler(int signum)
+#endif
+{
+ keep_going = 0;
+}
+
+static void
+#ifdef __FreeBSD__
+sigchld(int signum __unused)
+#else
+sigchld(int signum)
+#endif
+{
+}
+
+static char
+xtoa(uint8_t n)
+{
+ static const char xarray[] = "0123456789abcdef";
+ assert(n < sizeof(xarray));
+ return xarray[n];
+}
+
+static const char *
+prmask(const sigset_t *m, char *buf, size_t len)
+{
+ size_t j = 2;
+ assert(len >= 3 + sizeof(*m));
+ buf[0] = '0';
+ buf[1] = 'x';
+#define N(p, a) (((p) >> ((a) * 4)) & 0xf)
+ for (size_t i = __arraycount(m->__bits); i > 0; i--) {
+ uint32_t p = m->__bits[i - 1];
+ for (size_t k = sizeof(p); k > 0; k--)
+ buf[j++] = xtoa(N(p, k - 1));
+ }
+ buf[j] = '\0';
+ return buf;
+}
+
+static void
+child(const struct timespec *ts)
+{
+ struct sigaction sa;
+ sigset_t set, oset, nset;
+ char obuf[sizeof(oset) + 3], nbuf[sizeof(nset) + 3];
+ int fd;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = sig_handler;
+ if ((fd = open("/dev/null", O_RDONLY)) == -1)
+ err(1, "open");
+
+ if (sigaction(SIGTERM, &sa, NULL) == -1)
+ err(1, "sigaction");
+
+ sigfillset(&set);
+ if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
+ err(1, "sigprocmask");
+
+ if (sigprocmask(SIG_BLOCK, NULL, &oset) == -1)
+ err(1, "sigprocmask");
+
+ sigemptyset(&set);
+
+ for (;;) {
+ fd_set rset;
+ FD_ZERO(&rset);
+ FD_SET(fd, &rset);
+ if (pselect(1, &rset, NULL, NULL, ts, &set) == -1) {
+ if(errno == EINTR) {
+ if (!keep_going)
+ break;
+ }
+ }
+ if (ts)
+ break;
+ }
+ if (sigprocmask(SIG_BLOCK, NULL, &nset) == -1)
+ err(1, "sigprocmask");
+ if (memcmp(&oset, &nset, sizeof(oset)) != 0)
+ atf_tc_fail("pselect() masks don't match "
+ "after timeout %s != %s",
+ prmask(&nset, nbuf, sizeof(nbuf)),
+ prmask(&oset, obuf, sizeof(obuf)));
+}
+
+ATF_TC(pselect_sigmask);
+ATF_TC_HEAD(pselect_sigmask, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask "
+ "setting when a signal is received (PR lib/43625)");
+}
+
+ATF_TC_BODY(pselect_sigmask, tc)
+{
+ pid_t pid;
+ int status;
+
+ signal(SIGCHLD, sigchld);
+
+ switch (pid = fork()) {
+ case 0:
+ child(NULL);
+ case -1:
+ err(1, "fork");
+ default:
+ sleep(1);
+ if (kill(pid, SIGTERM) == -1)
+ err(1, "kill");
+ sleep(1);
+ switch (waitpid(pid, &status, WNOHANG)) {
+ case -1:
+ err(1, "wait");
+ case 0:
+ if (kill(pid, SIGKILL) == -1)
+ err(1, "kill");
+ atf_tc_fail("pselect() did not receive signal");
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+ATF_TC(pselect_timeout);
+ATF_TC_HEAD(pselect_timeout, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask "
+ "setting when a timeout occurs");
+}
+
+ATF_TC_BODY(pselect_timeout, tc)
+{
+ pid_t pid;
+ int status;
+ static const struct timespec zero = { 0, 0 };
+
+ signal(SIGCHLD, sigchld);
+
+ switch (pid = fork()) {
+ case 0:
+ child(&zero);
+ break;
+ case -1:
+ err(1, "fork");
+ default:
+ sleep(1);
+ switch (waitpid(pid, &status, WNOHANG)) {
+ case -1:
+ err(1, "wait");
+ case 0:
+ if (kill(pid, SIGKILL) == -1)
+ err(1, "kill");
+ atf_tc_fail("pselect() did not receive signal");
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, pselect_sigmask);
+ ATF_TP_ADD_TC(tp, pselect_timeout);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c
new file mode 100644
index 0000000..72175e4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c
@@ -0,0 +1,532 @@
+/* $NetBSD: t_setrlimit.c,v 1.4 2012/06/12 23:56:19 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_setrlimit.c,v 1.4 2012/06/12 23:56:19 christos Exp $");
+
+#include <sys/resource.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#ifdef __NetBSD__
+#include <lwp.h>
+#endif
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static void sighandler(int);
+static const char path[] = "setrlimit";
+
+static const int rlimit[] = {
+ RLIMIT_AS,
+ RLIMIT_CORE,
+ RLIMIT_CPU,
+ RLIMIT_DATA,
+ RLIMIT_FSIZE,
+ RLIMIT_MEMLOCK,
+ RLIMIT_NOFILE,
+ RLIMIT_NPROC,
+ RLIMIT_RSS,
+ RLIMIT_SBSIZE,
+ RLIMIT_STACK
+};
+
+ATF_TC(setrlimit_basic);
+ATF_TC_HEAD(setrlimit_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic soft limit test");
+}
+
+ATF_TC_BODY(setrlimit_basic, tc)
+{
+ struct rlimit res;
+ int *buf, lim;
+ size_t i;
+
+ buf = calloc(__arraycount(rlimit), sizeof(int));
+
+ if (buf == NULL)
+ atf_tc_fail("initialization failed");
+
+ for (i = lim = 0; i < __arraycount(rlimit); i++) {
+
+ (void)memset(&res, 0, sizeof(struct rlimit));
+
+ if (getrlimit(rlimit[i], &res) != 0)
+ continue;
+
+ if (res.rlim_cur == RLIM_INFINITY || res.rlim_cur == 0)
+ continue;
+
+ if (res.rlim_cur == res.rlim_max) /* An unprivileged run. */
+ continue;
+
+ buf[i] = res.rlim_cur;
+ res.rlim_cur = res.rlim_cur - 1;
+
+ if (setrlimit(rlimit[i], &res) != 0) {
+ lim = rlimit[i];
+ goto out;
+ }
+ }
+
+out:
+ for (i = 0; i < __arraycount(rlimit); i++) {
+
+ (void)memset(&res, 0, sizeof(struct rlimit));
+
+ if (buf[i] == 0)
+ continue;
+
+ if (getrlimit(rlimit[i], &res) != 0)
+ continue;
+
+ res.rlim_cur = buf[i];
+
+ (void)setrlimit(rlimit[i], &res);
+ }
+
+ if (lim != 0)
+ atf_tc_fail("failed to set limit (%d)", lim);
+}
+
+ATF_TC(setrlimit_current);
+ATF_TC_HEAD(setrlimit_current, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "setrlimit(3) with current limits");
+}
+
+ATF_TC_BODY(setrlimit_current, tc)
+{
+ struct rlimit res;
+ size_t i;
+
+ for (i = 0; i < __arraycount(rlimit); i++) {
+
+ (void)memset(&res, 0, sizeof(struct rlimit));
+
+ ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0);
+ ATF_REQUIRE(setrlimit(rlimit[i], &res) == 0);
+ }
+}
+
+ATF_TC(setrlimit_err);
+ATF_TC_HEAD(setrlimit_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions");
+}
+
+ATF_TC_BODY(setrlimit_err, tc)
+{
+ struct rlimit res;
+ size_t i;
+
+ for (i = 0; i < __arraycount(rlimit); i++) {
+
+ errno = 0;
+
+ ATF_REQUIRE(getrlimit(rlimit[i], (void *)0) != 0);
+ ATF_REQUIRE(errno == EFAULT);
+ }
+
+ errno = 0;
+
+ ATF_REQUIRE(getrlimit(INT_MAX, &res) != 0);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+ATF_TC_WITH_CLEANUP(setrlimit_fsize);
+ATF_TC_HEAD(setrlimit_fsize, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_FSIZE");
+}
+
+ATF_TC_BODY(setrlimit_fsize, tc)
+{
+ struct rlimit res;
+ int fd, sta;
+ pid_t pid;
+
+ fd = open(path, O_RDWR | O_CREAT, 0700);
+
+ if (fd < 0)
+ atf_tc_fail("initialization failed");
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ res.rlim_cur = 2;
+ res.rlim_max = 2;
+
+ if (setrlimit(RLIMIT_FSIZE, &res) != 0)
+ _exit(EXIT_FAILURE);
+
+ if (signal(SIGXFSZ, sighandler) == SIG_ERR)
+ _exit(EXIT_FAILURE);
+
+ /*
+ * The third call should generate a SIGXFSZ.
+ */
+ (void)write(fd, "X", 1);
+ (void)write(fd, "X", 1);
+ (void)write(fd, "X", 1);
+
+ _exit(EXIT_FAILURE);
+ }
+
+ (void)close(fd);
+ (void)wait(&sta);
+ (void)unlink(path);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("RLIMIT_FSIZE not enforced");
+}
+
+ATF_TC_CLEANUP(setrlimit_fsize, tc)
+{
+ (void)unlink(path);
+}
+
+static void
+sighandler(int signo)
+{
+
+ if (signo != SIGXFSZ)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+}
+
+ATF_TC(setrlimit_memlock);
+ATF_TC_HEAD(setrlimit_memlock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_MEMLOCK");
+}
+
+ATF_TC_BODY(setrlimit_memlock, tc)
+{
+ struct rlimit res;
+ void *buf;
+ long page;
+ pid_t pid;
+ int sta;
+
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+ buf = malloc(page);
+ pid = fork();
+
+ if (buf == NULL || pid < 0)
+ atf_tc_fail("initialization failed");
+
+ if (pid == 0) {
+
+ /*
+ * Try to lock a page while
+ * RLIMIT_MEMLOCK is zero.
+ */
+ if (mlock(buf, page) != 0)
+ _exit(EXIT_FAILURE);
+
+ if (munlock(buf, page) != 0)
+ _exit(EXIT_FAILURE);
+
+ res.rlim_cur = 0;
+ res.rlim_max = 0;
+
+ if (setrlimit(RLIMIT_MEMLOCK, &res) != 0)
+ _exit(EXIT_FAILURE);
+
+ if (mlock(buf, page) != 0)
+ _exit(EXIT_SUCCESS);
+
+ (void)munlock(buf, page);
+
+ _exit(EXIT_FAILURE);
+ }
+
+ free(buf);
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("RLIMIT_MEMLOCK not enforced");
+}
+
+ATF_TC(setrlimit_nofile_1);
+ATF_TC_HEAD(setrlimit_nofile_1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #1");
+}
+
+ATF_TC_BODY(setrlimit_nofile_1, tc)
+{
+ struct rlimit res;
+ int fd, i, rv, sta;
+ pid_t pid;
+
+ res.rlim_cur = 0;
+ res.rlim_max = 0;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * Close all descriptors, set RLIMIT_NOFILE
+ * to zero, and try to open a random file.
+ * This should fail with EMFILE.
+ */
+ for (i = 0; i < 1024; i++)
+ (void)close(i);
+
+ rv = setrlimit(RLIMIT_NOFILE, &res);
+
+ if (rv != 0)
+ _exit(EXIT_FAILURE);
+
+ errno = 0;
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd >= 0 || errno != EMFILE)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("RLIMIT_NOFILE not enforced");
+}
+
+ATF_TC(setrlimit_nofile_2);
+ATF_TC_HEAD(setrlimit_nofile_2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #2");
+}
+
+ATF_TC_BODY(setrlimit_nofile_2, tc)
+{
+ static const rlim_t lim = 12;
+ struct rlimit res;
+ int fd, i, rv, sta;
+ pid_t pid;
+
+ /*
+ * See that an arbitrary limit on
+ * open files is being enforced.
+ */
+ res.rlim_cur = lim;
+ res.rlim_max = lim;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ for (i = 0; i < 1024; i++)
+ (void)close(i);
+
+ rv = setrlimit(RLIMIT_NOFILE, &res);
+
+ if (rv != 0)
+ _exit(EXIT_FAILURE);
+
+ for (i = 0; i < (int)lim; i++) {
+
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd < 0)
+ _exit(EXIT_FAILURE);
+ }
+
+ /*
+ * After the limit has been reached,
+ * EMFILE should again follow.
+ */
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd >= 0 || errno != EMFILE)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("RLIMIT_NOFILE not enforced");
+}
+
+ATF_TC(setrlimit_nproc);
+ATF_TC_HEAD(setrlimit_nproc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NPROC");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(setrlimit_nproc, tc)
+{
+ struct rlimit res;
+ pid_t pid, cpid;
+ int sta;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * Set RLIMIT_NPROC to zero and try to fork.
+ */
+ res.rlim_cur = 0;
+ res.rlim_max = 0;
+
+ if (setrlimit(RLIMIT_NPROC, &res) != 0)
+ _exit(EXIT_FAILURE);
+
+ cpid = fork();
+
+ if (cpid < 0)
+ _exit(EXIT_SUCCESS);
+
+ _exit(EXIT_FAILURE);
+ }
+
+ (void)waitpid(pid, &sta, 0);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("RLIMIT_NPROC not enforced");
+}
+
+#ifdef __NetBSD__
+ATF_TC(setrlimit_nthr);
+ATF_TC_HEAD(setrlimit_nthr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NTHR");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+static void
+func(lwpid_t *id)
+{
+ printf("thread %d\n", *id);
+ fflush(stdout);
+ _lwp_exit();
+}
+
+ATF_TC_BODY(setrlimit_nthr, tc)
+{
+ struct rlimit res;
+ lwpid_t lwpid;
+ ucontext_t c;
+
+ /*
+ * Set RLIMIT_NTHR to zero and try to create a thread.
+ */
+ res.rlim_cur = 0;
+ res.rlim_max = 0;
+ ATF_REQUIRE(setrlimit(RLIMIT_NTHR, &res) == 0);
+ ATF_REQUIRE(getcontext(&c) == 0);
+ c.uc_link = NULL;
+ sigemptyset(&c.uc_sigmask);
+ c.uc_stack.ss_flags = 0;
+ c.uc_stack.ss_size = 4096;
+ ATF_REQUIRE((c.uc_stack.ss_sp = malloc(c.uc_stack.ss_size)) != NULL);
+ makecontext(&c, func, 1, &lwpid);
+ ATF_CHECK_ERRNO(EAGAIN, _lwp_create(&c, 0, &lwpid) == -1);
+}
+#endif
+
+ATF_TC(setrlimit_perm);
+ATF_TC_HEAD(setrlimit_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2) for EPERM");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(setrlimit_perm, tc)
+{
+ struct rlimit res;
+ size_t i;
+
+ /*
+ * Try to raise the maximum limits as an user.
+ */
+ for (i = 0; i < __arraycount(rlimit); i++) {
+
+ ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0);
+
+#ifdef __FreeBSD__
+ if (res.rlim_max == INT64_MAX) /* Overflow. */
+#else
+ if (res.rlim_max == UINT64_MAX) /* Overflow. */
+#endif
+ continue;
+
+ errno = 0;
+ res.rlim_max = res.rlim_max + 1;
+
+ ATF_CHECK_ERRNO(EPERM, setrlimit(rlimit[i], &res) != 0);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, setrlimit_basic);
+ ATF_TP_ADD_TC(tp, setrlimit_current);
+ ATF_TP_ADD_TC(tp, setrlimit_err);
+ ATF_TP_ADD_TC(tp, setrlimit_fsize);
+ ATF_TP_ADD_TC(tp, setrlimit_memlock);
+ ATF_TP_ADD_TC(tp, setrlimit_nofile_1);
+ ATF_TP_ADD_TC(tp, setrlimit_nofile_2);
+ ATF_TP_ADD_TC(tp, setrlimit_nproc);
+ ATF_TP_ADD_TC(tp, setrlimit_perm);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, setrlimit_nthr);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_setuid.c b/contrib/netbsd-tests/lib/libc/sys/t_setuid.c
new file mode 100644
index 0000000..d2bf523
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_setuid.c
@@ -0,0 +1,122 @@
+/* $NetBSD: t_setuid.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_setuid.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+ATF_TC(setuid_perm);
+ATF_TC_HEAD(setuid_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setuid(0) as normal user");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(setuid_perm, tc)
+{
+ errno = 0;
+
+ ATF_REQUIRE(setuid(0) == -1);
+ ATF_REQUIRE(errno == EPERM);
+}
+
+ATF_TC(setuid_real);
+ATF_TC_HEAD(setuid_real, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setuid(2) with real UID");
+}
+
+ATF_TC_BODY(setuid_real, tc)
+{
+ uid_t uid = getuid();
+
+ ATF_REQUIRE(setuid(uid) == 0);
+
+ ATF_REQUIRE(getuid() == uid);
+ ATF_REQUIRE(geteuid() == uid);
+}
+
+ATF_TC(setuid_root);
+ATF_TC_HEAD(setuid_root, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of setuid(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(setuid_root, tc)
+{
+ struct passwd *pw;
+ int rv, sta;
+ pid_t pid;
+ uid_t uid;
+
+ while ((pw = getpwent()) != NULL) {
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ rv = setuid(pw->pw_uid);
+
+ if (rv != 0)
+ _exit(EXIT_FAILURE);
+
+ uid = getuid();
+
+ if (uid != pw->pw_uid)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("failed to change UID to %u", pw->pw_uid);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, setuid_perm);
+ ATF_TP_ADD_TC(tp, setuid_real);
+ ATF_TP_ADD_TC(tp, setuid_root);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c b/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c
new file mode 100644
index 0000000..23ca36a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c
@@ -0,0 +1,165 @@
+/* $NetBSD: t_sigaction.c,v 1.3 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * 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 <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2010\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_sigaction.c,v 1.3 2014/11/04 00:20:19 justin Exp $");
+
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#ifdef __NetBSD__
+#include "../../../h_macros.h"
+#else
+#include "h_macros.h"
+#endif
+
+static bool handler_called = false;
+
+static void
+#ifdef __FreeBSD__
+handler(int signo __unused)
+#else
+handler(int signo)
+#endif
+{
+ handler_called = true;
+}
+
+static void
+sa_resethand_child(const int flags)
+{
+ struct sigaction sa;
+
+ sa.sa_flags = flags;
+ sa.sa_handler = &handler;
+ sigemptyset(&sa.sa_mask);
+
+ sigaction(SIGUSR1, &sa, NULL);
+ kill(getpid(), SIGUSR1);
+ exit(handler_called ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+static void
+wait_and_check_child(const pid_t pid, const char *fail_message)
+{
+ int status;
+
+ (void)waitpid(pid, &status, 0);
+
+ if (WIFEXITED(status))
+ ATF_CHECK_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+ else
+ atf_tc_fail("%s; raw exit status was %d", fail_message, status);
+}
+
+static void
+#ifdef __FreeBSD__
+catch(int sig __unused)
+#else
+catch(int sig)
+#endif
+{
+ return;
+}
+
+ATF_TC(sigaction_basic);
+ATF_TC_HEAD(sigaction_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks for correct I&D cache"
+ "synchronization after copying out the trampoline code.");
+}
+
+ATF_TC_BODY(sigaction_basic, tc)
+{
+ static struct sigaction sa;
+
+ sa.sa_handler = catch;
+
+ sigaction(SIGUSR1, &sa, 0);
+ kill(getpid(), SIGUSR1);
+ atf_tc_pass();
+}
+
+ATF_TC(sigaction_noflags);
+ATF_TC_HEAD(sigaction_noflags, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks programming a signal with "
+ "sigaction(2) but without any flags");
+}
+
+ATF_TC_BODY(sigaction_noflags, tc)
+{
+ const pid_t pid = fork();
+ if (pid == -1)
+ atf_tc_fail_errno("fork(2) failed");
+ else if (pid == 0)
+ sa_resethand_child(0);
+ else
+ wait_and_check_child(pid, "Child process did not exit cleanly;"
+ " it failed to process the signal");
+}
+
+ATF_TC(sigaction_resethand);
+ATF_TC_HEAD(sigaction_resethand, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that SA_RESETHAND works");
+}
+
+ATF_TC_BODY(sigaction_resethand, tc)
+{
+ const pid_t pid = fork();
+ if (pid == -1)
+ atf_tc_fail_errno("fork(2) failed");
+ else if (pid == 0)
+ sa_resethand_child(SA_RESETHAND);
+ else {
+ wait_and_check_child(pid, "Child process did not exit cleanly;"
+ " it either failed to process the signal or SA_RESETHAND"
+ " is broken");
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sigaction_basic);
+ ATF_TP_ADD_TC(tp, sigaction_noflags);
+ ATF_TP_ADD_TC(tp, sigaction_resethand);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c
new file mode 100644
index 0000000..6686f02
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c
@@ -0,0 +1,115 @@
+/* $NetBSD: t_sigqueue.c,v 1.4 2011/07/07 16:31:11 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_sigqueue.c,v 1.4 2011/07/07 16:31:11 jruoho Exp $");
+
+
+#include <atf-c.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <unistd.h>
+
+static void handler(int, siginfo_t *, void *);
+
+#define VALUE (int)0xc001dad1
+static int value;
+
+static void
+#ifdef __FreeBSD__
+handler(int signo __unused, siginfo_t *info __unused, void *data __unused)
+#else
+handler(int signo, siginfo_t *info, void *data)
+#endif
+{
+ value = info->si_value.sival_int;
+ kill(0, SIGINFO);
+}
+
+ATF_TC(sigqueue_basic);
+ATF_TC_HEAD(sigqueue_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks sigqueue(3) sigval delivery");
+}
+
+ATF_TC_BODY(sigqueue_basic, tc)
+{
+ struct sigaction sa;
+ union sigval sv;
+
+ sa.sa_sigaction = handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+
+ if (sigaction(SIGUSR1, &sa, NULL) != 0)
+ atf_tc_fail("sigaction failed");
+
+ sv.sival_int = VALUE;
+
+#ifdef __FreeBSD__
+ /*
+ * From kern_sig.c:
+ * Specification says sigqueue can only send signal to single process.
+ */
+ if (sigqueue(getpid(), SIGUSR1, sv) != 0)
+#else
+ if (sigqueue(0, SIGUSR1, sv) != 0)
+#endif
+ atf_tc_fail("sigqueue failed");
+
+ sched_yield();
+ ATF_REQUIRE_EQ(sv.sival_int, value);
+}
+
+ATF_TC(sigqueue_err);
+ATF_TC_HEAD(sigqueue_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from sigqueue(3)");
+}
+
+ATF_TC_BODY(sigqueue_err, tc)
+{
+ union sigval sv;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, sigqueue(getpid(), -1, sv) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sigqueue_basic);
+ ATF_TP_ADD_TC(tp, sigqueue_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c b/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c
new file mode 100644
index 0000000..64b68d9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c
@@ -0,0 +1,126 @@
+/* $NetBSD: t_sigtimedwait.c,v 1.2 2013/03/08 23:18:00 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 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/cdefs.h>
+__RCSID("$NetBSD: t_sigtimedwait.c,v 1.2 2013/03/08 23:18:00 martin Exp $");
+
+#include <sys/time.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <atf-c.h>
+
+
+ATF_TC(sigtimedwait_all0timeout);
+
+ATF_TC_HEAD(sigtimedwait_all0timeout, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "10");
+ atf_tc_set_md_var(tc, "descr", "Test for PR kern/47625: sigtimedwait"
+ " with a timeout value of all zero should return imediately");
+}
+
+ATF_TC_BODY(sigtimedwait_all0timeout, tc)
+{
+ sigset_t block;
+ struct timespec ts, before, after, len;
+ siginfo_t info;
+ int r;
+
+ sigemptyset(&block);
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ clock_gettime(CLOCK_MONOTONIC, &before);
+ r = sigtimedwait(&block, &info, &ts);
+ clock_gettime(CLOCK_MONOTONIC, &after);
+ ATF_REQUIRE(r == -1);
+ ATF_REQUIRE_ERRNO(EAGAIN, errno);
+ timespecsub(&after, &before, &len);
+ ATF_REQUIRE(len.tv_sec < 1);
+}
+
+ATF_TC(sigtimedwait_NULL_timeout);
+
+ATF_TC_HEAD(sigtimedwait_NULL_timeout, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "10");
+ atf_tc_set_md_var(tc, "descr", "Test sigtimedwait() without timeout");
+}
+
+ATF_TC_BODY(sigtimedwait_NULL_timeout, tc)
+{
+ sigset_t sig;
+ siginfo_t info;
+ struct itimerval it;
+ int r;
+
+ /* arrange for a SIGALRM signal in a few seconds */
+ memset(&it, 0, sizeof it);
+ it.it_value.tv_sec = 5;
+ ATF_REQUIRE(setitimer(ITIMER_REAL, &it, NULL) == 0);
+
+ /* wait without timeout */
+ sigemptyset(&sig);
+ sigaddset(&sig, SIGALRM);
+ r = sigtimedwait(&sig, &info, NULL);
+ ATF_REQUIRE(r == SIGALRM);
+}
+
+ATF_TC(sigtimedwait_small_timeout);
+
+ATF_TC_HEAD(sigtimedwait_small_timeout, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "15");
+ atf_tc_set_md_var(tc, "descr", "Test sigtimedwait with a small "
+ "timeout");
+}
+
+ATF_TC_BODY(sigtimedwait_small_timeout, tc)
+{
+ sigset_t block;
+ struct timespec ts;
+ siginfo_t info;
+ int r;
+
+ sigemptyset(&block);
+ ts.tv_sec = 5;
+ ts.tv_nsec = 0;
+ r = sigtimedwait(&block, &info, &ts);
+ ATF_REQUIRE(r == -1);
+ ATF_REQUIRE_ERRNO(EAGAIN, errno);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, sigtimedwait_all0timeout);
+ ATF_TP_ADD_TC(tp, sigtimedwait_NULL_timeout);
+ ATF_TP_ADD_TC(tp, sigtimedwait_small_timeout);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c b/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c
new file mode 100644
index 0000000..9da7861
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c
@@ -0,0 +1,141 @@
+/* $NetBSD: t_socketpair.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 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/cdefs.h>
+__RCSID("$NetBSD: t_socketpair.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $");
+
+#include <atf-c.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+
+static void
+connected(int fd)
+{
+ struct sockaddr_un addr;
+ socklen_t len = (socklen_t)sizeof(addr);
+ ATF_REQUIRE(getpeername(fd, (struct sockaddr*)(void *)&addr,
+ &len) == 0);
+}
+
+static void
+run(int flags)
+{
+ int fd[2], i;
+
+ while ((i = open("/", O_RDONLY)) < 3)
+ ATF_REQUIRE(i != -1);
+
+#ifdef __FreeBSD__
+ closefrom(3);
+#else
+ ATF_REQUIRE(fcntl(3, F_CLOSEM) != -1);
+#endif
+
+ ATF_REQUIRE(socketpair(AF_UNIX, SOCK_DGRAM | flags, 0, fd) == 0);
+
+ ATF_REQUIRE(fd[0] == 3);
+ ATF_REQUIRE(fd[1] == 4);
+
+ connected(fd[0]);
+ connected(fd[1]);
+
+ if (flags & SOCK_CLOEXEC) {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0);
+ } else {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0);
+ }
+
+ if (flags & SOCK_NONBLOCK) {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0);
+ } else {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0);
+ }
+
+ ATF_REQUIRE(close(fd[0]) != -1);
+ ATF_REQUIRE(close(fd[1]) != -1);
+}
+
+ATF_TC(socketpair_basic);
+ATF_TC_HEAD(socketpair_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of socketpair(2)");
+}
+
+ATF_TC_BODY(socketpair_basic, tc)
+{
+ run(0);
+}
+
+ATF_TC(socketpair_nonblock);
+ATF_TC_HEAD(socketpair_nonblock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A non-blocking test of socketpair(2)");
+}
+
+ATF_TC_BODY(socketpair_nonblock, tc)
+{
+ run(SOCK_NONBLOCK);
+}
+
+ATF_TC(socketpair_cloexec);
+ATF_TC_HEAD(socketpair_cloexec, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A close-on-exec of socketpair(2)");
+}
+
+ATF_TC_BODY(socketpair_cloexec, tc)
+{
+ run(SOCK_CLOEXEC);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, socketpair_basic);
+ ATF_TP_ADD_TC(tp, socketpair_nonblock);
+ ATF_TP_ADD_TC(tp, socketpair_cloexec);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_stat.c b/contrib/netbsd-tests/lib/libc/sys/t_stat.c
new file mode 100644
index 0000000..5e1d17e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_stat.c
@@ -0,0 +1,421 @@
+/* $NetBSD: t_stat.c,v 1.4 2012/03/17 08:37:08 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_stat.c,v 1.4 2012/03/17 08:37:08 jruoho Exp $");
+
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <arpa/inet.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fts.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <stdio.h>
+
+#ifdef __FreeBSD__
+#include <netinet/in.h>
+#endif
+
+static const char *path = "stat";
+
+ATF_TC_WITH_CLEANUP(stat_chflags);
+ATF_TC_HEAD(stat_chflags, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test chflags(2) with stat(2)");
+}
+
+ATF_TC_BODY(stat_chflags, tc)
+{
+ struct stat sa, sb;
+ int fd;
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ fd = open(path, O_RDONLY | O_CREAT);
+
+ ATF_REQUIRE(fd != -1);
+ ATF_REQUIRE(stat(path, &sa) == 0);
+ ATF_REQUIRE(chflags(path, UF_NODUMP) == 0);
+ ATF_REQUIRE(stat(path, &sb) == 0);
+
+ if (sa.st_flags == sb.st_flags)
+ atf_tc_fail("stat(2) did not detect chflags(2)");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(stat_chflags, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(stat_dir);
+ATF_TC_HEAD(stat_dir, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test stat(2) with directories");
+}
+
+ATF_TC_BODY(stat_dir, tc)
+{
+ const short depth = 2;
+ struct stat sa, sb;
+ char *argv[2];
+ FTSENT *ftse;
+ FTS *fts;
+ int ops;
+
+ argv[1] = NULL;
+ argv[0] = __UNCONST("/");
+
+ ops = FTS_NOCHDIR;
+ ops |= FTS_PHYSICAL;
+
+ fts = fts_open(argv, ops, NULL);
+ ATF_REQUIRE(fts != NULL);
+
+ while ((ftse = fts_read(fts)) != NULL) {
+
+ if (ftse->fts_level < 1)
+ continue;
+
+ if (ftse->fts_level > depth) {
+ (void)fts_set(fts, ftse, FTS_SKIP);
+ continue;
+ }
+
+ switch(ftse->fts_info) {
+
+ case FTS_DP:
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(stat(ftse->fts_parent->fts_path,&sa) == 0);
+ ATF_REQUIRE(chdir(ftse->fts_path) == 0);
+ ATF_REQUIRE(stat(".", &sb) == 0);
+
+ /*
+ * The previous two stat(2) calls
+ * should be for the same directory.
+ */
+ if (sa.st_dev != sb.st_dev || sa.st_ino != sb.st_ino)
+ atf_tc_fail("inconsistent stat(2)");
+
+ /*
+ * Check that fts(3)'s stat(2)
+ * call equals the manual one.
+ */
+ if (sb.st_ino != ftse->fts_statp->st_ino)
+ atf_tc_fail("stat(2) and fts(3) differ");
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ (void)fts_close(fts);
+}
+
+ATF_TC(stat_err);
+ATF_TC_HEAD(stat_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from the stat(2) family");
+}
+
+ATF_TC_BODY(stat_err, tc)
+{
+ char buf[NAME_MAX + 1];
+ struct stat st;
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fstat(-1, &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, stat(buf, &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, lstat(buf, &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, stat((void *)-1, &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, lstat((void *)-1, &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, stat("/etc/passwd", (void *)-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, lstat("/etc/passwd", (void *)-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, stat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, lstat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1);
+}
+
+ATF_TC_WITH_CLEANUP(stat_mtime);
+ATF_TC_HEAD(stat_mtime, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test modification times with stat(2)");
+}
+
+ATF_TC_BODY(stat_mtime, tc)
+{
+ struct stat sa, sb;
+ int fd[3];
+ size_t i;
+
+ for (i = 0; i < __arraycount(fd); i++) {
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ fd[i] = open(path, O_WRONLY | O_CREAT);
+
+ ATF_REQUIRE(fd[i] != -1);
+ ATF_REQUIRE(write(fd[i], "X", 1) == 1);
+ ATF_REQUIRE(stat(path, &sa) == 0);
+
+ (void)sleep(1);
+
+ ATF_REQUIRE(write(fd[i], "X", 1) == 1);
+ ATF_REQUIRE(stat(path, &sb) == 0);
+
+ ATF_REQUIRE(close(fd[i]) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+
+ if (sa.st_mtime == sb.st_mtime)
+ atf_tc_fail("mtimes did not change");
+ }
+}
+
+ATF_TC_CLEANUP(stat_mtime, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(stat_perm);
+ATF_TC_HEAD(stat_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with stat(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(stat_perm, tc)
+{
+ struct stat sa, sb;
+ gid_t gid;
+ uid_t uid;
+ int fd;
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ uid = getuid();
+ gid = getgid();
+
+ fd = open(path, O_RDONLY | O_CREAT);
+
+ ATF_REQUIRE(fd != -1);
+ ATF_REQUIRE(fstat(fd, &sa) == 0);
+ ATF_REQUIRE(stat(path, &sb) == 0);
+
+ if (gid != sa.st_gid || sa.st_gid != sb.st_gid)
+ atf_tc_fail("invalid GID");
+
+ if (uid != sa.st_uid || sa.st_uid != sb.st_uid)
+ atf_tc_fail("invalid UID");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(stat_perm, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(stat_size);
+ATF_TC_HEAD(stat_size, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test file sizes with stat(2)");
+}
+
+ATF_TC_BODY(stat_size, tc)
+{
+ struct stat sa, sb, sc;
+ const size_t n = 10;
+ size_t i;
+ int fd;
+
+ fd = open(path, O_WRONLY | O_CREAT);
+ ATF_REQUIRE(fd >= 0);
+
+ for (i = 0; i < n; i++) {
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+ (void)memset(&sc, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(fstat(fd, &sa) == 0);
+ ATF_REQUIRE(write(fd, "X", 1) == 1);
+ ATF_REQUIRE(fstat(fd, &sb) == 0);
+ ATF_REQUIRE(stat(path, &sc) == 0);
+
+ if (sa.st_size + 1 != sb.st_size)
+ atf_tc_fail("invalid file size");
+
+ if (sb.st_size != sc.st_size)
+ atf_tc_fail("stat(2) and fstat(2) mismatch");
+ }
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(stat_size, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(stat_socket);
+ATF_TC_HEAD(stat_socket, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test fstat(2) with "
+ "a socket (PR kern/46077)");
+}
+
+ATF_TC_BODY(stat_socket, tc)
+{
+ struct sockaddr_in addr;
+ struct stat st;
+ uint32_t iaddr;
+ int fd, flags;
+
+ (void)memset(&st, 0, sizeof(struct stat));
+ (void)memset(&addr, 0, sizeof(struct sockaddr_in));
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ ATF_REQUIRE(fd >= 0);
+
+ flags = fcntl(fd, F_GETFL);
+
+ ATF_REQUIRE(flags != -1);
+ ATF_REQUIRE(fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1);
+ ATF_REQUIRE(inet_pton(AF_INET, "127.0.0.1", &iaddr) == 1);
+
+ addr.sin_port = htons(42);
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = iaddr;
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EINPROGRESS,
+ connect(fd, (struct sockaddr *)&addr,
+ sizeof(struct sockaddr_in)) == -1);
+
+ errno = 0;
+
+ if (fstat(fd, &st) != 0 || errno != 0)
+ atf_tc_fail("fstat(2) failed for a EINPROGRESS socket");
+
+ (void)close(fd);
+}
+
+ATF_TC_WITH_CLEANUP(stat_symlink);
+ATF_TC_HEAD(stat_symlink, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test symbolic links with stat(2)");
+}
+
+ATF_TC_BODY(stat_symlink, tc)
+{
+ const char *pathlink = "pathlink";
+ struct stat sa, sb;
+ int fd;
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ fd = open(path, O_WRONLY | O_CREAT);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(symlink(path, pathlink) == 0);
+ ATF_REQUIRE(stat(pathlink, &sa) == 0);
+ ATF_REQUIRE(lstat(pathlink, &sb) == 0);
+
+ if (S_ISLNK(sa.st_mode) != 0)
+ atf_tc_fail("stat(2) detected symbolic link");
+
+ if (S_ISLNK(sb.st_mode) == 0)
+ atf_tc_fail("lstat(2) did not detect symbolic link");
+
+ if (sa.st_mode == sb.st_mode)
+ atf_tc_fail("inconsistencies between stat(2) and lstat(2)");
+
+ ATF_REQUIRE(unlink(path) == 0);
+ ATF_REQUIRE(unlink(pathlink) == 0);
+}
+
+ATF_TC_CLEANUP(stat_symlink, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, stat_chflags);
+ ATF_TP_ADD_TC(tp, stat_dir);
+ ATF_TP_ADD_TC(tp, stat_err);
+ ATF_TP_ADD_TC(tp, stat_mtime);
+ ATF_TP_ADD_TC(tp, stat_perm);
+ ATF_TP_ADD_TC(tp, stat_size);
+ ATF_TP_ADD_TC(tp, stat_socket);
+ ATF_TP_ADD_TC(tp, stat_symlink);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c b/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c
new file mode 100644
index 0000000..de36c88
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c
@@ -0,0 +1,133 @@
+/* $NetBSD: t_swapcontext.c,v 1.3 2013/05/05 10:28:11 skrll Exp $ */
+
+/*
+ * Copyright (c) 2012 Emmanuel Dreyfus. 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/cdefs.h>
+__RCSID("$NetBSD");
+
+#include <ucontext.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <lwp.h>
+
+#include <atf-c.h>
+
+#define STACKSIZE 65536
+
+char stack[STACKSIZE];
+ucontext_t nctx;
+ucontext_t octx;
+void *otls;
+void *ntls;
+int val1, val2;
+int alter_tlsbase;
+
+/* ARGSUSED0 */
+static void
+swapfunc(void *arg)
+{
+ ntls = _lwp_getprivate();
+ printf("after swapcontext TLS pointer = %p\n", ntls);
+
+ if (alter_tlsbase) {
+ ATF_REQUIRE_EQ(ntls, &val1);
+ printf("TLS pointer modified by swapcontext()\n");
+ } else {
+ ATF_REQUIRE_EQ(ntls, &val2);
+ printf("TLS pointer left untouched by swapcontext()\n");
+ }
+
+ /* Go back in main */
+ ATF_REQUIRE(swapcontext(&nctx, &octx));
+
+ /* NOTREACHED */
+ return;
+}
+
+static void
+mainfunc(void)
+{
+ printf("Testing if swapcontext() alters TLS pointer if _UC_TLSBASE "
+ "is %s\n", (alter_tlsbase) ? "left set" : "cleared");
+
+ _lwp_setprivate(&val1);
+ printf("before swapcontext TLS pointer = %p\n", &val1);
+
+ ATF_REQUIRE(getcontext(&nctx) == 0);
+
+ nctx.uc_stack.ss_sp = stack;
+ nctx.uc_stack.ss_size = sizeof(stack);
+
+#ifndef _UC_TLSBASE
+ ATF_REQUIRE_MSG(0, "_UC_TLSBASE is not defined");
+#else /* _UC_TLSBASE */
+ ATF_REQUIRE(nctx.uc_flags & _UC_TLSBASE);
+ if (!alter_tlsbase)
+ nctx.uc_flags &= ~_UC_TLSBASE;
+#endif /* _UC_TLSBASE */
+
+ makecontext(&nctx, swapfunc, 0);
+
+ _lwp_setprivate(&val2);
+ otls = _lwp_getprivate();
+ printf("before swapcontext TLS pointer = %p\n", otls);
+ ATF_REQUIRE(swapcontext(&octx, &nctx) == 0);
+
+ printf("Test completed\n");
+}
+
+
+ATF_TC(swapcontext1);
+ATF_TC_HEAD(swapcontext1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can let "
+ "TLS pointer untouched");
+}
+ATF_TC_BODY(swapcontext1, tc)
+{
+ alter_tlsbase = 0;
+ mainfunc();
+}
+
+ATF_TC(swapcontext2);
+ATF_TC_HEAD(swapcontext2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() can "
+ "modify TLS pointer");
+}
+ATF_TC_BODY(swapcontext2, tc)
+{
+ alter_tlsbase = 1;
+ mainfunc();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, swapcontext1);
+ ATF_TP_ADD_TC(tp, swapcontext2);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c
new file mode 100644
index 0000000..cc85307
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c
@@ -0,0 +1,211 @@
+/* $NetBSD: t_timer_create.c,v 1.4 2012/03/18 07:00:52 jruoho Exp $ */
+
+/*-
+ * 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.h>
+#include <errno.h>
+#include <stdio.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+static timer_t t;
+static bool fail = true;
+
+static void
+#ifdef __FreeBSD__
+timer_signal_handler(int signo, siginfo_t *si, void *osi __unused)
+#else
+timer_signal_handler(int signo, siginfo_t *si, void *osi)
+#endif
+{
+ timer_t *tp;
+
+ tp = si->si_value.sival_ptr;
+
+ if (*tp == t && signo == SIGALRM)
+ fail = false;
+
+ (void)fprintf(stderr, "%s: %s\n", __func__, strsignal(signo));
+}
+
+static void
+timer_signal_create(clockid_t cid, bool expire)
+{
+ struct itimerspec tim;
+ struct sigaction act;
+ struct sigevent evt;
+ sigset_t set;
+
+ t = 0;
+ fail = true;
+
+ (void)memset(&evt, 0, sizeof(struct sigevent));
+ (void)memset(&act, 0, sizeof(struct sigaction));
+ (void)memset(&tim, 0, sizeof(struct itimerspec));
+
+ /*
+ * Set handler.
+ */
+ act.sa_flags = SA_SIGINFO;
+ act.sa_sigaction = timer_signal_handler;
+
+ ATF_REQUIRE(sigemptyset(&set) == 0);
+ ATF_REQUIRE(sigemptyset(&act.sa_mask) == 0);
+
+ /*
+ * Block SIGALRM while configuring the timer.
+ */
+ ATF_REQUIRE(sigaction(SIGALRM, &act, NULL) == 0);
+ ATF_REQUIRE(sigaddset(&set, SIGALRM) == 0);
+ ATF_REQUIRE(sigprocmask(SIG_SETMASK, &set, NULL) == 0);
+
+ /*
+ * Create the timer (SIGEV_SIGNAL).
+ */
+ evt.sigev_signo = SIGALRM;
+ evt.sigev_value.sival_ptr = &t;
+ evt.sigev_notify = SIGEV_SIGNAL;
+
+ ATF_REQUIRE(timer_create(cid, &evt, &t) == 0);
+
+ /*
+ * Start the timer. After this, unblock the signal.
+ */
+ tim.it_value.tv_sec = expire ? 5 : 1;
+ tim.it_value.tv_nsec = 0;
+
+ ATF_REQUIRE(timer_settime(t, 0, &tim, NULL) == 0);
+
+ (void)sigprocmask(SIG_UNBLOCK, &set, NULL);
+ (void)sleep(2);
+
+ if (expire) {
+ if (!fail)
+ atf_tc_fail("timer fired too soon");
+ } else {
+ if (fail)
+ atf_tc_fail("timer failed to fire");
+ }
+
+ ATF_REQUIRE(timer_delete(t) == 0);
+}
+
+ATF_TC(timer_create_err);
+ATF_TC_HEAD(timer_create_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Check errors from timer_create(2) (PR lib/42434");
+}
+
+ATF_TC_BODY(timer_create_err, tc)
+{
+ struct sigevent ev;
+
+ (void)memset(&ev, 0, sizeof(struct sigevent));
+
+ errno = 0;
+ ev.sigev_signo = -1;
+ ev.sigev_notify = SIGEV_SIGNAL;
+
+ ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1);
+
+ errno = 0;
+ ev.sigev_signo = SIGUSR1;
+ ev.sigev_notify = SIGEV_THREAD + 100;
+
+ ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1);
+}
+
+ATF_TC(timer_create_real);
+ATF_TC_HEAD(timer_create_real, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), "
+ "SIGEV_SIGNAL");
+}
+
+ATF_TC_BODY(timer_create_real, tc)
+{
+ timer_signal_create(CLOCK_REALTIME, false);
+}
+
+ATF_TC(timer_create_mono);
+ATF_TC_HEAD(timer_create_mono, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), "
+ "SIGEV_SIGNAL");
+}
+
+ATF_TC_BODY(timer_create_mono, tc)
+{
+ timer_signal_create(CLOCK_MONOTONIC, false);
+}
+
+ATF_TC(timer_create_real_expire);
+ATF_TC_HEAD(timer_create_real_expire, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), "
+ "SIGEV_SIGNAL, with expiration");
+}
+
+ATF_TC_BODY(timer_create_real_expire, tc)
+{
+ timer_signal_create(CLOCK_REALTIME, true);
+}
+
+ATF_TC(timer_create_mono_expire);
+ATF_TC_HEAD(timer_create_mono_expire, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), "
+ "SIGEV_SIGNAL, with expiration");
+}
+
+ATF_TC_BODY(timer_create_mono_expire, tc)
+{
+ timer_signal_create(CLOCK_MONOTONIC, true);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, timer_create_err);
+ ATF_TP_ADD_TC(tp, timer_create_real);
+ ATF_TP_ADD_TC(tp, timer_create_mono);
+ ATF_TP_ADD_TC(tp, timer_create_real_expire);
+ ATF_TP_ADD_TC(tp, timer_create_mono_expire);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_truncate.c b/contrib/netbsd-tests/lib/libc/sys/t_truncate.c
new file mode 100644
index 0000000..59193a9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_truncate.c
@@ -0,0 +1,188 @@
+/* $NetBSD: t_truncate.c,v 1.2 2011/08/18 19:48:03 dholland Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_truncate.c,v 1.2 2011/08/18 19:48:03 dholland Exp $");
+
+#include <sys/stat.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+static const char path[] = "truncate";
+static const size_t sizes[] = { 8, 16, 512, 1024, 2048, 4094, 3000, 30 };
+
+ATF_TC_WITH_CLEANUP(ftruncate_basic);
+ATF_TC_HEAD(ftruncate_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of ftruncate(2)");
+}
+
+ATF_TC_BODY(ftruncate_basic, tc)
+{
+ struct stat st;
+ size_t i;
+ int fd;
+
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+ ATF_REQUIRE(fd >= 0);
+
+ for (i = 0; i < __arraycount(sizes); i++) {
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(ftruncate(fd, sizes[i]) == 0);
+ ATF_REQUIRE(fstat(fd, &st) == 0);
+
+ (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]);
+
+ if (sizes[i] != (size_t)st.st_size)
+ atf_tc_fail("ftruncate(2) did not truncate");
+ }
+
+ (void)close(fd);
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(ftruncate_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(ftruncate_err);
+ATF_TC_HEAD(ftruncate_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from ftruncate(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(ftruncate_err, tc)
+{
+ int fd;
+
+ fd = open("/etc/passwd", O_RDONLY, 0400);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, ftruncate(-1, 999) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, ftruncate(fd, 999) == -1);
+
+ (void)close(fd);
+}
+
+ATF_TC_WITH_CLEANUP(truncate_basic);
+ATF_TC_HEAD(truncate_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of truncate(2)");
+}
+
+ATF_TC_BODY(truncate_basic, tc)
+{
+ struct stat st;
+ size_t i;
+ int fd;
+
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+ ATF_REQUIRE(fd >= 0);
+
+ for (i = 0; i < __arraycount(sizes); i++) {
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(truncate(path, sizes[i]) == 0);
+ ATF_REQUIRE(fstat(fd, &st) == 0);
+
+ (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]);
+
+ if (sizes[i] != (size_t)st.st_size)
+ atf_tc_fail("truncate(2) did not truncate");
+ }
+
+ (void)close(fd);
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(truncate_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(truncate_err);
+ATF_TC_HEAD(truncate_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from truncate(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(truncate_err, tc)
+{
+#ifndef __NetBSD__
+ char buf[PATH_MAX];
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, truncate((void *)-1, 999) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EISDIR, truncate("/etc", 999) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, truncate("/a/b/c/d/e/f/g", 999) == -1);
+
+ errno = 0;
+#ifdef __NetBSD__
+ ATF_REQUIRE_ERRNO(EACCES, truncate("/usr/bin/fpr", 999) == -1);
+#else
+ snprintf(buf, sizeof(buf), "%s/truncate_test.root_owned",
+ atf_tc_get_config_var(tc, "srcdir"));
+ ATF_REQUIRE_ERRNO(EACCES, truncate(buf, 999) == -1);
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, ftruncate_basic);
+ ATF_TP_ADD_TC(tp, ftruncate_err);
+ ATF_TP_ADD_TC(tp, truncate_basic);
+ ATF_TP_ADD_TC(tp, truncate_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c b/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c
new file mode 100644
index 0000000..27d6740
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c
@@ -0,0 +1,76 @@
+/* $NetBSD: t_ucontext.c,v 1.1 2011/10/15 06:54:52 jruoho Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_ucontext.c,v 1.1 2011/10/15 06:54:52 jruoho Exp $");
+
+#include <atf-c.h>
+#include <stdio.h>
+#include <ucontext.h>
+
+ATF_TC(ucontext_basic);
+ATF_TC_HEAD(ucontext_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks {get,set}context(2)");
+}
+
+ATF_TC_BODY(ucontext_basic, tc)
+{
+ ucontext_t u, v, w;
+ volatile int x, y;
+
+ x = 0;
+ y = 0;
+
+ printf("Start\n");
+
+ getcontext(&u);
+ y++;
+
+ printf("x == %d\n", x);
+
+ getcontext(&v);
+
+ if ( x < 20 ) {
+ x++;
+ getcontext(&w);
+ setcontext(&u);
+ }
+
+ printf("End, y = %d\n", y);
+ ATF_REQUIRE_EQ(y, 21);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, ucontext_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_umask.c b/contrib/netbsd-tests/lib/libc/sys/t_umask.c
new file mode 100644
index 0000000..748cbdc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_umask.c
@@ -0,0 +1,205 @@
+/* $NetBSD: t_umask.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_umask.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $");
+
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char path[] = "umask";
+static const mode_t mask[] = {
+ S_IRWXU,
+ S_IRUSR,
+ S_IWUSR,
+ S_IXUSR,
+ S_IRWXG,
+ S_IRGRP,
+ S_IWGRP,
+ S_IXGRP,
+ S_IRWXO,
+ S_IROTH,
+ S_IWOTH,
+ S_IXOTH
+};
+
+ATF_TC_WITH_CLEANUP(umask_fork);
+ATF_TC_HEAD(umask_fork, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check that umask(2) is inherited");
+}
+
+ATF_TC_BODY(umask_fork, tc)
+{
+ mode_t mode;
+ pid_t pid;
+ size_t i;
+ int sta;
+
+ for (i = 0; i < __arraycount(mask) - 1; i++) {
+
+ (void)umask(mask[i] | mask[i + 1]);
+
+ pid = fork();
+
+ if (pid < 0)
+ continue;
+
+ if (pid == 0) {
+
+ mode = umask(mask[i]);
+
+ if (mode != (mask[i] | mask[i + 1]))
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ goto fail;
+ }
+
+ return;
+
+fail:
+ (void)umask(S_IWGRP | S_IWOTH);
+
+ atf_tc_fail("umask(2) was not inherited");
+}
+
+ATF_TC_CLEANUP(umask_fork, tc)
+{
+ (void)umask(S_IWGRP | S_IWOTH);
+}
+
+ATF_TC_WITH_CLEANUP(umask_open);
+ATF_TC_HEAD(umask_open, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of open(2) and umask(2)");
+}
+
+ATF_TC_BODY(umask_open, tc)
+{
+ const char *str = NULL;
+ struct stat st;
+ size_t i;
+ int fd;
+
+ for (i = 0; i < __arraycount(mask); i++) {
+
+ (void)umask(mask[i]);
+
+ fd = open(path, O_RDWR | O_CREAT, 0777);
+
+ if (fd < 0)
+ continue;
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ if (stat(path, &st) != 0) {
+ str = "failed to stat(2)";
+ goto out;
+ }
+
+ if ((st.st_mode & mask[i]) != 0) {
+ str = "invalid umask(2)";
+ goto out;
+ }
+
+ if (unlink(path) != 0) {
+ str = "failed to unlink(2)";
+ goto out;
+ }
+
+ }
+
+out:
+ (void)umask(S_IWGRP | S_IWOTH);
+
+ if (str != NULL)
+ atf_tc_fail("%s", str);
+}
+
+ATF_TC_CLEANUP(umask_open, tc)
+{
+ (void)umask(S_IWGRP | S_IWOTH);
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(umask_previous);
+ATF_TC_HEAD(umask_previous, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test the return value from umask(2)");
+}
+
+ATF_TC_BODY(umask_previous, tc)
+{
+ mode_t mode;
+ size_t i;
+
+ for (i = 0; i < __arraycount(mask); i++) {
+
+ mode = umask(mask[i]);
+ mode = umask(mask[i]);
+
+ if (mode != mask[i])
+ goto fail;
+ }
+
+ return;
+
+fail:
+ (void)umask(S_IWGRP | S_IWOTH);
+
+ atf_tc_fail("umask(2) did not return the previous mask");
+}
+
+ATF_TC_CLEANUP(umask_previous, tc)
+{
+ (void)umask(S_IWGRP | S_IWOTH);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, umask_fork);
+ ATF_TP_ADD_TC(tp, umask_open);
+ ATF_TP_ADD_TC(tp, umask_previous);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_unlink.c b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c
new file mode 100644
index 0000000..8d94668
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c
@@ -0,0 +1,162 @@
+/* $NetBSD: t_unlink.c,v 1.2 2014/04/21 18:05:17 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_unlink.c,v 1.2 2014/04/21 18:05:17 martin Exp $");
+
+#include <sys/stat.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+
+static char path[] = "unlink";
+
+ATF_TC_WITH_CLEANUP(unlink_basic);
+ATF_TC_HEAD(unlink_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of unlink(2)");
+}
+
+ATF_TC_BODY(unlink_basic, tc)
+{
+ const size_t n = 512;
+ size_t i;
+ int fd;
+
+ for (i = 0; i < n; i++) {
+
+ fd = open(path, O_RDWR | O_CREAT, 0666);
+
+ ATF_REQUIRE(fd != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1);
+ }
+}
+
+ATF_TC_CLEANUP(unlink_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(unlink_err);
+ATF_TC_HEAD(unlink_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of unlink(2)");
+}
+
+ATF_TC_BODY(unlink_err, tc)
+{
+ char buf[PATH_MAX + 1];
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ errno = 0;
+#ifdef __FreeBSD__
+ ATF_REQUIRE_ERRNO(EISDIR, unlink("/") == -1);
+#else
+ ATF_REQUIRE_ERRNO(EBUSY, unlink("/") == -1);
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, unlink(buf) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, unlink("/a/b/c/d/e/f/g/h/i/j/k/l/m") == -1);
+}
+
+ATF_TC_CLEANUP(unlink_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(unlink_fifo);
+ATF_TC_HEAD(unlink_fifo, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test unlink(2) for a FIFO");
+}
+
+ATF_TC_BODY(unlink_fifo, tc)
+{
+
+ ATF_REQUIRE(mkfifo(path, 0666) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1);
+}
+
+ATF_TC_CLEANUP(unlink_fifo, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(unlink_perm);
+ATF_TC_HEAD(unlink_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with unlink(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(unlink_perm, tc)
+{
+ int rv;
+
+ errno = 0;
+ rv = unlink("/etc");
+ ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM),
+ "unlinking a directory did not fail with EPERM or EACCESS; "
+ "unlink() returned %d, errno %d", rv, errno);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EACCES, unlink("/root/.profile") == -1);
+}
+
+ATF_TC_CLEANUP(unlink_perm, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, unlink_basic);
+ ATF_TP_ADD_TC(tp, unlink_err);
+ ATF_TP_ADD_TC(tp, unlink_fifo);
+ ATF_TP_ADD_TC(tp, unlink_perm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_write.c b/contrib/netbsd-tests/lib/libc/sys/t_write.c
new file mode 100644
index 0000000..a3783cb
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_write.c
@@ -0,0 +1,236 @@
+/* $NetBSD: t_write.c,v 1.2 2011/10/19 16:19:30 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2001, 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_write.c,v 1.2 2011/10/19 16:19:30 jruoho Exp $");
+
+#include <sys/uio.h>
+#ifdef __NetBSD__
+#include <sys/syslimits.h>
+#endif
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+static void sighandler(int);
+
+static bool fail = false;
+static const char *path = "write";
+
+static void
+#ifdef __FreeBSD__
+sighandler(int signo __unused)
+#else
+sighandler(int signo)
+#endif
+{
+ fail = false;
+}
+
+ATF_TC_WITH_CLEANUP(write_err);
+ATF_TC_HEAD(write_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks errors from write(2)");
+}
+
+ATF_TC_BODY(write_err, tc)
+{
+ char rbuf[3] = { 'a', 'b', 'c' };
+ char wbuf[3] = { 'x', 'y', 'z' };
+ int fd;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, write(-1, wbuf, sizeof(wbuf)) == -1);
+
+ fd = open(path, O_RDWR | O_CREAT);
+
+ if (fd >= 0) {
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(0, write(fd, wbuf, 3) == 3);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, write(fd, wbuf, SIZE_MAX) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, write(fd, (void *)-1, 1) == -1);
+
+ /*
+ * Check that the above bogus write(2)
+ * calls did not corrupt the file.
+ */
+ ATF_REQUIRE(lseek(fd, 0, SEEK_SET) == 0);
+ ATF_REQUIRE(read(fd, rbuf, 3) == 3);
+ ATF_REQUIRE(memcmp(rbuf, wbuf, 3) == 0);
+
+ (void)close(fd);
+ (void)unlink(path);
+ }
+}
+
+ATF_TC_CLEANUP(write_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(write_pipe);
+ATF_TC_HEAD(write_pipe, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks for EPIPE from write(2)");
+}
+
+ATF_TC_BODY(write_pipe, tc)
+{
+ int fds[2];
+
+ ATF_REQUIRE(pipe(fds) == 0);
+ ATF_REQUIRE(signal(SIGPIPE, sighandler) == 0);
+
+ ATF_REQUIRE(write(fds[1], "x", 1) != -1);
+ ATF_REQUIRE(close(fds[0]) == 0);
+
+ errno = 0;
+ fail = true;
+
+ if (write(fds[1], "x", 1) != -1 || errno != EPIPE)
+ atf_tc_fail_nonfatal("expected EPIPE but write(2) succeeded");
+
+ ATF_REQUIRE(close(fds[1]) == 0);
+
+ if (fail != false)
+ atf_tc_fail_nonfatal("SIGPIPE was not raised");
+}
+
+ATF_TC_WITH_CLEANUP(write_pos);
+ATF_TC_HEAD(write_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that write(2) "
+ "updates the file position");
+}
+
+ATF_TC_BODY(write_pos, tc)
+{
+ const size_t n = 123;
+ size_t i;
+ int fd;
+
+ fd = open(path, O_RDWR | O_CREAT);
+ ATF_REQUIRE(fd >= 0);
+
+ for (i = 0; i < n; i++) {
+ ATF_REQUIRE(write(fd, "x", 1) == 1);
+ ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == (off_t)(i + 1));
+ }
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(write_pos, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(write_ret);
+ATF_TC_HEAD(write_ret, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks return values from write(2)");
+}
+
+ATF_TC_BODY(write_ret, tc)
+{
+ const size_t n = 99;
+ char buf[123];
+ size_t i, j;
+ int fd;
+
+ fd = open(path, O_WRONLY | O_CREAT);
+ ATF_REQUIRE(fd >= 0);
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ for (i = j = 0; i < n; i++)
+ j += write(fd, buf, sizeof(buf));
+
+ if (j != n * 123)
+ atf_tc_fail("inconsistent return values from write(2)");
+
+ (void)close(fd);
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(write_ret, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(writev_iovmax);
+ATF_TC_HEAD(writev_iovmax, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "10");
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that file descriptor is properly FILE_UNUSE()d "
+ "when iovcnt is greater than IOV_MAX");
+}
+
+ATF_TC_BODY(writev_iovmax, tc)
+{
+ ssize_t retval;
+
+ (void)printf("Calling writev(2, NULL, IOV_MAX + 1)...\n");
+
+ errno = 0;
+ retval = writev(2, NULL, IOV_MAX + 1);
+
+ ATF_REQUIRE_EQ_MSG(retval, -1, "got: %zd", retval);
+ ATF_REQUIRE_EQ_MSG(errno, EINVAL, "got: %s", strerror(errno));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, write_err);
+ ATF_TP_ADD_TC(tp, write_pipe);
+ ATF_TP_ADD_TC(tp, write_pos);
+ ATF_TP_ADD_TC(tp, write_ret);
+ ATF_TP_ADD_TC(tp, writev_iovmax);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/t_cdb.c b/contrib/netbsd-tests/lib/libc/t_cdb.c
new file mode 100644
index 0000000..5e88e65
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/t_cdb.c
@@ -0,0 +1,158 @@
+/* $NetBSD: t_cdb.c,v 1.1 2012/09/27 00:38:57 joerg Exp $ */
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_cdb.c,v 1.1 2012/09/27 00:38:57 joerg Exp $");
+
+#include <atf-c.h>
+#include <assert.h>
+#include <cdbr.h>
+#include <cdbw.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define MAXKEYS 16384
+
+static const char database_name[] = "test.cdb";
+
+uint32_t keys[MAXKEYS];
+
+static int
+cmp_keys(const void *a_, const void *b_)
+{
+ uint32_t a = *(const uint32_t *)a_;
+ uint32_t b = *(const uint32_t *)b_;
+
+ return a > b ? 1 : (a < b ? 1 : 0);
+}
+
+static void
+init_keys(size_t len)
+{
+ uint32_t sorted_keys[MAXKEYS];
+ size_t i;
+
+ assert(len <= MAXKEYS);
+
+ if (len == 0)
+ return;
+
+ do {
+ for (i = 0; i < len; ++i)
+ sorted_keys[i] = keys[i] = arc4random();
+
+ qsort(sorted_keys, len, sizeof(*sorted_keys), cmp_keys);
+ for (i = 1; i < len; ++i) {
+ if (sorted_keys[i - 1] == sorted_keys[i])
+ break;
+ }
+ } while (i != len);
+}
+
+static void
+write_database(size_t len)
+{
+ struct cdbw *db;
+ int fd;
+ size_t i;
+ uint32_t buf[2];
+
+ ATF_REQUIRE((db = cdbw_open()) != NULL);
+ ATF_REQUIRE((fd = creat(database_name, S_IRUSR|S_IWUSR)) != -1);
+ for (i = 0; i < len; ++i) {
+ buf[0] = i;
+ buf[1] = keys[i];
+ ATF_REQUIRE(cdbw_put(db, &keys[i], sizeof(keys[i]),
+ buf, sizeof(buf)) == 0);
+ }
+ ATF_REQUIRE(cdbw_output(db, fd, "test database", arc4random) == 0);
+ cdbw_close(db);
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+static void
+check_database(size_t len)
+{
+ struct cdbr *db;
+ size_t i, data_len;
+ const void *data;
+ uint32_t buf[2];
+
+ ATF_REQUIRE((db = cdbr_open(database_name, CDBR_DEFAULT)) != NULL);
+ ATF_REQUIRE_EQ(cdbr_entries(db), len);
+ for (i = 0; i < len; ++i) {
+ ATF_REQUIRE(cdbr_find(db, &keys[i], sizeof(keys[i]),
+ &data, &data_len) != -1);
+ ATF_REQUIRE_EQ(data_len, sizeof(buf));
+ memcpy(buf, data, sizeof(buf));
+ ATF_REQUIRE_EQ(buf[0], i);
+ ATF_REQUIRE_EQ(buf[1], keys[i]);
+ }
+ cdbr_close(db);
+}
+
+ATF_TC_WITH_CLEANUP(cdb);
+
+ATF_TC_HEAD(cdb, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test cdb(5) reading and writing");
+}
+
+ATF_TC_BODY(cdb, tc)
+{
+ size_t i, sizes[] = { 0, 16, 64, 1024, 2048 };
+ for (i = 0; i < __arraycount(sizes); ++i) {
+ init_keys(sizes[i]);
+ write_database(sizes[i]);
+ check_database(sizes[i]);
+ unlink(database_name);
+ }
+}
+
+ATF_TC_CLEANUP(cdb, tc)
+{
+
+ unlink(database_name);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, cdb);
+
+ return atf_no_error();
+}
+
diff --git a/contrib/netbsd-tests/lib/libc/t_convfp.c b/contrib/netbsd-tests/lib/libc/t_convfp.c
new file mode 100644
index 0000000..de68690
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/t_convfp.c
@@ -0,0 +1,155 @@
+/* $NetBSD: t_convfp.c,v 1.7 2011/06/14 11:58:22 njoly Exp $ */
+
+/*-
+ * Copyright (c) 2003 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 <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * This value is representable as an unsigned int, but not as an int.
+ * According to ISO C it must survive the convsion back from a double
+ * to an unsigned int (everything > -1 and < UINT_MAX+1 has to)
+ */
+#define UINT_TESTVALUE (INT_MAX+42U)
+
+/* The same for unsigned long */
+#define ULONG_TESTVALUE (LONG_MAX+42UL)
+
+
+ATF_TC(conv_uint);
+ATF_TC_HEAD(conv_uint, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "test conversions to unsigned int");
+}
+
+ATF_TC_BODY(conv_uint, tc)
+{
+ unsigned int ui;
+ double d;
+
+ /* unsigned int test */
+ d = UINT_TESTVALUE;
+ ui = (unsigned int)d;
+
+ if (ui != UINT_TESTVALUE)
+ atf_tc_fail("FAILED: unsigned int %u (0x%x) != %u (0x%x)",
+ ui, ui, UINT_TESTVALUE, UINT_TESTVALUE);
+}
+
+ATF_TC(conv_ulong);
+
+ATF_TC_HEAD(conv_ulong, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "test conversions to unsigned long");
+}
+
+ATF_TC_BODY(conv_ulong, tc)
+{
+ unsigned long ul;
+ long double dt;
+ double d;
+
+ /* unsigned long vs. {long} double test */
+ if (sizeof(d) > sizeof(ul)) {
+ d = ULONG_TESTVALUE;
+ ul = (unsigned long)d;
+ printf("testing double vs. long\n");
+ } else if (sizeof(dt) > sizeof(ul)) {
+ dt = ULONG_TESTVALUE;
+ ul = (unsigned long)dt;
+ printf("testing long double vs. long\n");
+ } else {
+ printf("sizeof(long) = %zu, sizeof(double) = %zu, "
+ "sizeof(long double) = %zu\n",
+ sizeof(ul), sizeof(d), sizeof(dt));
+ atf_tc_skip("no suitable {long} double type found");
+ }
+
+ if (ul != ULONG_TESTVALUE)
+ atf_tc_fail("unsigned long %lu (0x%lx) != %lu (0x%lx)",
+ ul, ul, ULONG_TESTVALUE, ULONG_TESTVALUE);
+}
+
+ATF_TC(cast_ulong);
+
+ATF_TC_HEAD(cast_ulong, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "test double to unsigned long cast");
+}
+
+ATF_TC_BODY(cast_ulong, tc)
+{
+ double nv;
+ unsigned long uv;
+
+ nv = 5.6;
+ uv = (unsigned long)nv;
+
+ ATF_CHECK_EQ_MSG(uv, 5,
+ "%.3f casted to unsigned long is %lu", nv, uv);
+}
+
+ATF_TC(cast_ulong2);
+
+ATF_TC_HEAD(cast_ulong2, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "test double/long double casts to unsigned long");
+}
+
+ATF_TC_BODY(cast_ulong2, tc)
+{
+ double dv = 1.9;
+ long double ldv = dv;
+ unsigned long l1 = dv;
+ unsigned long l2 = ldv;
+
+ ATF_CHECK_EQ_MSG(l1, 1,
+ "double 1.9 casted to unsigned long should be 1, but is %lu", l1);
+
+ ATF_CHECK_EQ_MSG(l2, 1,
+ "long double 1.9 casted to unsigned long should be 1, but is %lu",
+ l2);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, conv_uint);
+ ATF_TP_ADD_TC(tp, conv_ulong);
+ ATF_TP_ADD_TC(tp, cast_ulong);
+ ATF_TP_ADD_TC(tp, cast_ulong2);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/t_gdtoa.c b/contrib/netbsd-tests/lib/libc/t_gdtoa.c
new file mode 100644
index 0000000..e040603
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/t_gdtoa.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 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/cdefs.h>
+__RCSID("$NetBSD: t_gdtoa.c,v 1.4 2012/09/27 08:19:18 martin Exp $");
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* reported by Maksymilian Arciemowicz */
+
+ATF_TC(long_format);
+
+ATF_TC_HEAD(long_format, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test printf with %%1.262159f format");
+}
+
+ATF_TC_BODY(long_format, tc)
+{
+ char *buf;
+ ATF_REQUIRE_EQ(262161, asprintf(&buf, "%1.262159f", 1.1));
+ free(buf);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, long_format);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c b/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c
new file mode 100644
index 0000000..66b1735
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c
@@ -0,0 +1,87 @@
+/* $NetBSD: t_tcsetpgrp.c,v 1.3 2012/03/18 07:14:08 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_tcsetpgrp.c,v 1.3 2012/03/18 07:14:08 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+ATF_TC(tcsetpgrp_err);
+ATF_TC_HEAD(tcsetpgrp_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from tcsetpgrp(3)"
+ " (PR lib/41673)");
+}
+
+ATF_TC_BODY(tcsetpgrp_err, tc)
+{
+ int rv, sta;
+ pid_t pid;
+
+ if (isatty(STDIN_FILENO) == 0)
+ return;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * The child process ID doesn't match any active
+ * process group ID, so the following call should
+ * fail with EPERM (and not EINVAL).
+ */
+ errno = 0;
+ rv = tcsetpgrp(STDIN_FILENO, getpid());
+
+ if (rv == 0 || errno != EPERM)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("wrong errno");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, tcsetpgrp_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/time/t_mktime.c b/contrib/netbsd-tests/lib/libc/time/t_mktime.c
new file mode 100644
index 0000000..8092361
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/time/t_mktime.c
@@ -0,0 +1,155 @@
+/* $NetBSD: t_mktime.c,v 1.5 2012/03/18 07:33:58 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 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 <err.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+
+ATF_TC(localtime_r_gmt);
+ATF_TC_HEAD(localtime_r_gmt, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that localtime_r(3) "
+ "returns localtime, not GMT (PR lib/28324)");
+}
+
+ATF_TC_BODY(localtime_r_gmt, tc)
+{
+ struct tm *t;
+ struct tm tt;
+ time_t x;
+
+ x = time(NULL);
+ localtime_r(&x, &tt);
+ t = localtime(&x);
+
+ if (t->tm_sec != tt.tm_sec || t->tm_min != tt.tm_min ||
+ t->tm_hour != tt.tm_hour || t->tm_mday != tt.tm_mday)
+ atf_tc_fail("inconsistencies between "
+ "localtime(3) and localtime_r(3)");
+}
+
+ATF_TC(mktime_negyear);
+ATF_TC_HEAD(mktime_negyear, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mktime(3) with negative year");
+}
+
+ATF_TC_BODY(mktime_negyear, tc)
+{
+ struct tm tms;
+ time_t t;
+
+ (void)memset(&tms, 0, sizeof(tms));
+ tms.tm_year = ~0;
+
+ errno = 0;
+ t = mktime(&tms);
+ ATF_REQUIRE_ERRNO(0, t != (time_t)-1);
+}
+
+ATF_TC(timegm_epoch);
+ATF_TC_HEAD(timegm_epoch, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test timegm(3) close to the epoch");
+}
+
+ATF_TC_BODY(timegm_epoch, tc)
+{
+ struct tm tms;
+ time_t t;
+
+ /* midnight on 1 Jan 1970 */
+ (void)memset(&tms, 0, sizeof(tms));
+ errno = 0;
+ tms.tm_year = 1970 - 1900;
+ tms.tm_mday = 1;
+ t = timegm(&tms);
+ ATF_REQUIRE_ERRNO(0, t == (time_t)0);
+
+ /* one second after midnight on 1 Jan 1970 */
+ (void)memset(&tms, 0, sizeof(tms));
+ errno = 0;
+ tms.tm_year = 1970 - 1900;
+ tms.tm_mday = 1;
+ tms.tm_sec = 1;
+ t = timegm(&tms);
+ ATF_REQUIRE_ERRNO(0, t == (time_t)1);
+
+ /*
+ * 1969-12-31 23:59:59 = one second before the epoch.
+ * Result should be -1 with errno = 0.
+ */
+ (void)memset(&tms, 0, sizeof(tms));
+ errno = 0;
+ tms.tm_year = 1969 - 1900;
+ tms.tm_mon = 12 - 1;
+ tms.tm_mday = 31;
+ tms.tm_hour = 23;
+ tms.tm_min = 59;
+ tms.tm_sec = 59;
+ t = timegm(&tms);
+ ATF_REQUIRE_ERRNO(0, t == (time_t)-1);
+
+ /*
+ * Another way of getting one second before the epoch:
+ * Set date to 1 Jan 1970, and time to -1 second.
+ */
+ (void)memset(&tms, 0, sizeof(tms));
+ errno = 0;
+ tms.tm_year = 1970 - 1900;
+ tms.tm_mday = 1;
+ tms.tm_sec = -1;
+ t = timegm(&tms);
+ ATF_REQUIRE_ERRNO(0, t == (time_t)-1);
+
+ /*
+ * Two seconds before the epoch.
+ */
+ (void)memset(&tms, 0, sizeof(tms));
+ errno = 0;
+ tms.tm_year = 1970 - 1900;
+ tms.tm_mday = 1;
+ tms.tm_sec = -2;
+ t = timegm(&tms);
+ ATF_REQUIRE_ERRNO(0, t == (time_t)-2);
+
+}
+
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, localtime_r_gmt);
+ ATF_TP_ADD_TC(tp, mktime_negyear);
+ ATF_TP_ADD_TC(tp, timegm_epoch);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/time/t_strptime.c b/contrib/netbsd-tests/lib/libc/time/t_strptime.c
new file mode 100644
index 0000000..99871ff
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/time/t_strptime.c
@@ -0,0 +1,281 @@
+/* $NetBSD: t_strptime.c,v 1.1 2011/01/13 00:14:10 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by David Laight.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_strptime.c,v 1.1 2011/01/13 00:14:10 pgoyette Exp $");
+
+#include <time.h>
+
+#include <atf-c.h>
+
+static void
+h_pass(const char *buf, const char *fmt, int len,
+ int tm_sec, int tm_min, int tm_hour, int tm_mday,
+ int tm_mon, int tm_year, int tm_wday, int tm_yday)
+{
+ struct tm tm = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL };
+ const char *ret, *exp;
+
+ exp = buf + len;
+ ret = strptime(buf, fmt, &tm);
+
+#ifdef __FreeBSD__
+ ATF_CHECK_MSG(ret == exp,
+ "strptime(\"%s\", \"%s\", tm): incorrect return code: "
+ "expected: %p, got: %p", buf, fmt, exp, ret);
+
+#define H_REQUIRE_FIELD(field) \
+ ATF_CHECK_MSG(tm.field == field, \
+ "strptime(\"%s\", \"%s\", tm): incorrect %s: " \
+ "expected: %d, but got: %d", buf, fmt, \
+ ___STRING(field), field, tm.field)
+#else
+ ATF_REQUIRE_MSG(ret == exp,
+ "strptime(\"%s\", \"%s\", tm): incorrect return code: "
+ "expected: %p, got: %p", buf, fmt, exp, ret);
+
+#define H_REQUIRE_FIELD(field) \
+ ATF_REQUIRE_MSG(tm.field == field, \
+ "strptime(\"%s\", \"%s\", tm): incorrect %s: " \
+ "expected: %d, but got: %d", buf, fmt, \
+ ___STRING(field), field, tm.field)
+#endif
+
+ H_REQUIRE_FIELD(tm_sec);
+ H_REQUIRE_FIELD(tm_min);
+ H_REQUIRE_FIELD(tm_hour);
+ H_REQUIRE_FIELD(tm_mday);
+ H_REQUIRE_FIELD(tm_mon);
+ H_REQUIRE_FIELD(tm_year);
+ H_REQUIRE_FIELD(tm_wday);
+ H_REQUIRE_FIELD(tm_yday);
+
+#undef H_REQUIRE_FIELD
+}
+
+static void
+h_fail(const char *buf, const char *fmt)
+{
+ struct tm tm = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL };
+
+#ifdef __FreeBSD__
+ ATF_CHECK_MSG(strptime(buf, fmt, &tm) == NULL, "strptime(\"%s\", "
+ "\"%s\", &tm) should fail, but it didn't", buf, fmt);
+#else
+ ATF_REQUIRE_MSG(strptime(buf, fmt, &tm) == NULL, "strptime(\"%s\", "
+ "\"%s\", &tm) should fail, but it didn't", buf, fmt);
+#endif
+}
+
+ATF_TC(common);
+
+ATF_TC_HEAD(common, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks strptime(3): various checks");
+}
+
+ATF_TC_BODY(common, tc)
+{
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("There are various issues with strptime on FreeBSD");
+#endif
+
+ h_pass("Tue Jan 20 23:27:46 1998", "%a %b %d %T %Y",
+ 24, 46, 27, 23, 20, 0, 98, 2, -1);
+ h_pass("Tue Jan 20 23:27:46 1998", "%a %b %d %H:%M:%S %Y",
+ 24, 46, 27, 23, 20, 0, 98, 2, -1);
+ h_pass("Tue Jan 20 23:27:46 1998", "%c",
+ 24, 46, 27, 23, 20, 0, 98, 2, -1);
+ h_pass("Fri Mar 4 20:05:34 2005", "%a %b %e %H:%M:%S %Y",
+ 24, 34, 5, 20, 4, 2, 105, 5, -1);
+ h_pass("5\t3 4 8pm:05:34 2005", "%w%n%m%t%d%n%k%p:%M:%S %Y",
+ 21, 34, 5, 20, 4, 2, 105, 5, -1);
+ h_pass("Fri Mar 4 20:05:34 2005", "%c",
+ 24, 34, 5, 20, 4, 2, 105, 5, -1);
+
+ h_pass("x20y", "x%Cy", 4, -1, -1, -1, -1, -1, 100, -1, -1);
+ h_pass("x84y", "x%yy", 4, -1, -1, -1, -1, -1, 84, -1, -1);
+ h_pass("x2084y", "x%C%yy", 6, -1, -1, -1, -1, -1, 184, -1, -1);
+ h_pass("x8420y", "x%y%Cy", 6, -1, -1, -1, -1, -1, 184, -1, -1);
+ h_pass("%20845", "%%%C%y5", 6, -1, -1, -1, -1, -1, 184, -1, -1);
+ h_fail("%", "%E%");
+
+ h_pass("1980", "%Y", 4, -1, -1, -1, -1, -1, 80, -1, -1);
+ h_pass("1980", "%EY", 4, -1, -1, -1, -1, -1, 80, -1, -1);
+
+ h_pass("0", "%S", 1, 0, -1, -1, -1, -1, -1, -1, -1);
+ h_pass("59", "%S", 2, 59, -1, -1, -1, -1, -1, -1, -1);
+ h_pass("60", "%S", 2, 60, -1, -1, -1, -1, -1, -1, -1);
+ h_pass("61", "%S", 2, 61, -1, -1, -1, -1, -1, -1, -1);
+ h_fail("62", "%S");
+}
+
+ATF_TC(day);
+
+ATF_TC_HEAD(day, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks strptime(3): day names");
+}
+
+ATF_TC_BODY(day, tc)
+{
+
+ h_pass("Sun", "%a", 3, -1, -1, -1, -1, -1, -1, 0, -1);
+ h_pass("Sunday", "%a", 6, -1, -1, -1, -1, -1, -1, 0, -1);
+ h_pass("Mon", "%a", 3, -1, -1, -1, -1, -1, -1, 1, -1);
+ h_pass("Monday", "%a", 6, -1, -1, -1, -1, -1, -1, 1, -1);
+ h_pass("Tue", "%a", 3, -1, -1, -1, -1, -1, -1, 2, -1);
+ h_pass("Tuesday", "%a", 7, -1, -1, -1, -1, -1, -1, 2, -1);
+ h_pass("Wed", "%a", 3, -1, -1, -1, -1, -1, -1, 3, -1);
+ h_pass("Wednesday", "%a", 9, -1, -1, -1, -1, -1, -1, 3, -1);
+ h_pass("Thu", "%a", 3, -1, -1, -1, -1, -1, -1, 4, -1);
+ h_pass("Thursday", "%a", 8, -1, -1, -1, -1, -1, -1, 4, -1);
+ h_pass("Fri", "%a", 3, -1, -1, -1, -1, -1, -1, 5, -1);
+ h_pass("Friday", "%a", 6, -1, -1, -1, -1, -1, -1, 5, -1);
+ h_pass("Sat", "%a", 3, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_pass("Saturday", "%a", 8, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_pass("Saturn", "%a", 3, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_fail("Moon", "%a");
+ h_pass("Sun", "%A", 3, -1, -1, -1, -1, -1, -1, 0, -1);
+ h_pass("Sunday", "%A", 6, -1, -1, -1, -1, -1, -1, 0, -1);
+ h_pass("Mon", "%A", 3, -1, -1, -1, -1, -1, -1, 1, -1);
+ h_pass("Monday", "%A", 6, -1, -1, -1, -1, -1, -1, 1, -1);
+ h_pass("Tue", "%A", 3, -1, -1, -1, -1, -1, -1, 2, -1);
+ h_pass("Tuesday", "%A", 7, -1, -1, -1, -1, -1, -1, 2, -1);
+ h_pass("Wed", "%A", 3, -1, -1, -1, -1, -1, -1, 3, -1);
+ h_pass("Wednesday", "%A", 9, -1, -1, -1, -1, -1, -1, 3, -1);
+ h_pass("Thu", "%A", 3, -1, -1, -1, -1, -1, -1, 4, -1);
+ h_pass("Thursday", "%A", 8, -1, -1, -1, -1, -1, -1, 4, -1);
+ h_pass("Fri", "%A", 3, -1, -1, -1, -1, -1, -1, 5, -1);
+ h_pass("Friday", "%A", 6, -1, -1, -1, -1, -1, -1, 5, -1);
+ h_pass("Sat", "%A", 3, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_pass("Saturday", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_pass("Saturn", "%A", 3, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_fail("Moon", "%A");
+
+ h_pass("mon", "%a", 3, -1, -1, -1, -1, -1, -1, 1, -1);
+ h_pass("tueSDay", "%A", 7, -1, -1, -1, -1, -1, -1, 2, -1);
+ h_pass("sunday", "%A", 6, -1, -1, -1, -1, -1, -1, 0, -1);
+#ifdef __NetBSD__
+ h_fail("sunday", "%EA");
+#else
+ h_pass("Sunday", "%EA", 6, -1, -1, -1, -1, -1, -1, 0, -1);
+#endif
+ h_pass("SaturDay", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1);
+#ifdef __NetBSD__
+ h_fail("SaturDay", "%OA");
+#else
+ h_pass("SaturDay", "%OA", 8, -1, -1, -1, -1, -1, -1, 6, -1);
+#endif
+}
+
+ATF_TC(month);
+
+ATF_TC_HEAD(month, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks strptime(3): month names");
+}
+
+ATF_TC_BODY(month, tc)
+{
+
+ h_pass("Jan", "%b", 3, -1, -1, -1, -1, 0, -1, -1, -1);
+ h_pass("January", "%b", 7, -1, -1, -1, -1, 0, -1, -1, -1);
+ h_pass("Feb", "%b", 3, -1, -1, -1, -1, 1, -1, -1, -1);
+ h_pass("February", "%b", 8, -1, -1, -1, -1, 1, -1, -1, -1);
+ h_pass("Mar", "%b", 3, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_pass("March", "%b", 5, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_pass("Apr", "%b", 3, -1, -1, -1, -1, 3, -1, -1, -1);
+ h_pass("April", "%b", 5, -1, -1, -1, -1, 3, -1, -1, -1);
+ h_pass("May", "%b", 3, -1, -1, -1, -1, 4, -1, -1, -1);
+ h_pass("Jun", "%b", 3, -1, -1, -1, -1, 5, -1, -1, -1);
+ h_pass("June", "%b", 4, -1, -1, -1, -1, 5, -1, -1, -1);
+ h_pass("Jul", "%b", 3, -1, -1, -1, -1, 6, -1, -1, -1);
+ h_pass("July", "%b", 4, -1, -1, -1, -1, 6, -1, -1, -1);
+ h_pass("Aug", "%b", 3, -1, -1, -1, -1, 7, -1, -1, -1);
+ h_pass("August", "%b", 6, -1, -1, -1, -1, 7, -1, -1, -1);
+ h_pass("Sep", "%b", 3, -1, -1, -1, -1, 8, -1, -1, -1);
+ h_pass("September", "%b", 9, -1, -1, -1, -1, 8, -1, -1, -1);
+ h_pass("Oct", "%b", 3, -1, -1, -1, -1, 9, -1, -1, -1);
+ h_pass("October", "%b", 7, -1, -1, -1, -1, 9, -1, -1, -1);
+ h_pass("Nov", "%b", 3, -1, -1, -1, -1, 10, -1, -1, -1);
+ h_pass("November", "%b", 8, -1, -1, -1, -1, 10, -1, -1, -1);
+ h_pass("Dec", "%b", 3, -1, -1, -1, -1, 11, -1, -1, -1);
+ h_pass("December", "%b", 8, -1, -1, -1, -1, 11, -1, -1, -1);
+ h_pass("Mayor", "%b", 3, -1, -1, -1, -1, 4, -1, -1, -1);
+ h_pass("Mars", "%b", 3, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_fail("Rover", "%b");
+ h_pass("Jan", "%B", 3, -1, -1, -1, -1, 0, -1, -1, -1);
+ h_pass("January", "%B", 7, -1, -1, -1, -1, 0, -1, -1, -1);
+ h_pass("Feb", "%B", 3, -1, -1, -1, -1, 1, -1, -1, -1);
+ h_pass("February", "%B", 8, -1, -1, -1, -1, 1, -1, -1, -1);
+ h_pass("Mar", "%B", 3, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_pass("March", "%B", 5, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_pass("Apr", "%B", 3, -1, -1, -1, -1, 3, -1, -1, -1);
+ h_pass("April", "%B", 5, -1, -1, -1, -1, 3, -1, -1, -1);
+ h_pass("May", "%B", 3, -1, -1, -1, -1, 4, -1, -1, -1);
+ h_pass("Jun", "%B", 3, -1, -1, -1, -1, 5, -1, -1, -1);
+ h_pass("June", "%B", 4, -1, -1, -1, -1, 5, -1, -1, -1);
+ h_pass("Jul", "%B", 3, -1, -1, -1, -1, 6, -1, -1, -1);
+ h_pass("July", "%B", 4, -1, -1, -1, -1, 6, -1, -1, -1);
+ h_pass("Aug", "%B", 3, -1, -1, -1, -1, 7, -1, -1, -1);
+ h_pass("August", "%B", 6, -1, -1, -1, -1, 7, -1, -1, -1);
+ h_pass("Sep", "%B", 3, -1, -1, -1, -1, 8, -1, -1, -1);
+ h_pass("September", "%B", 9, -1, -1, -1, -1, 8, -1, -1, -1);
+ h_pass("Oct", "%B", 3, -1, -1, -1, -1, 9, -1, -1, -1);
+ h_pass("October", "%B", 7, -1, -1, -1, -1, 9, -1, -1, -1);
+ h_pass("Nov", "%B", 3, -1, -1, -1, -1, 10, -1, -1, -1);
+ h_pass("November", "%B", 8, -1, -1, -1, -1, 10, -1, -1, -1);
+ h_pass("Dec", "%B", 3, -1, -1, -1, -1, 11, -1, -1, -1);
+ h_pass("December", "%B", 8, -1, -1, -1, -1, 11, -1, -1, -1);
+ h_pass("Mayor", "%B", 3, -1, -1, -1, -1, 4, -1, -1, -1);
+ h_pass("Mars", "%B", 3, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_fail("Rover", "%B");
+
+ h_pass("september", "%b", 9, -1, -1, -1, -1, 8, -1, -1, -1);
+ h_pass("septembe", "%B", 3, -1, -1, -1, -1, 8, -1, -1, -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, common);
+ ATF_TP_ADD_TC(tp, day);
+ ATF_TP_ADD_TC(tp, month);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c
new file mode 100644
index 0000000..6c913a4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c
@@ -0,0 +1,62 @@
+/* $NetBSD: h_tls_dlopen.c,v 1.5 2013/10/21 19:14:16 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: h_tls_dlopen.c,v 1.5 2013/10/21 19:14:16 joerg Exp $");
+
+#include <atf-c.h>
+#include <unistd.h>
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+extern __thread int var1;
+extern __thread int var2;
+extern __thread int *var3;
+__thread int var5 = 1;
+static __thread pid_t (*local_var)(void) = getpid;
+
+void testf_dso_helper(int x, int y);
+
+void
+testf_dso_helper(int x, int y)
+{
+ var1 = x;
+ var2 = y;
+ var3 = &optind;
+ ATF_CHECK_EQ(local_var, getpid);
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c
new file mode 100644
index 0000000..a268068
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c
@@ -0,0 +1,115 @@
+/* $NetBSD: t_tls_dlopen.c,v 1.3 2012/01/17 20:34:57 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_tls_dlopen.c,v 1.3 2012/01/17 20:34:57 joerg Exp $");
+
+#include <atf-c.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+ATF_TC(t_tls_dlopen);
+
+ATF_TC_HEAD(t_tls_dlopen, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test (un)initialized TLS variables and dlopen");
+}
+
+void (*testf_helper)(int, int);
+
+__thread int var1 = 1;
+__thread int var2;
+__thread int *var3 = &optind;
+int var4_helper;
+__thread int *var4 = &var4_helper;
+
+static void *
+testf(void *dummy)
+{
+ ATF_CHECK_EQ(var1, 1);
+ ATF_CHECK_EQ(var2, 0);
+ ATF_CHECK_EQ(var3, &optind);
+ ATF_CHECK_EQ(var4, &var4_helper);
+ testf_helper(2, 2);
+ ATF_CHECK_EQ(var1, 2);
+ ATF_CHECK_EQ(var2, 2);
+ testf_helper(3, 3);
+ ATF_CHECK_EQ(var1, 3);
+ ATF_CHECK_EQ(var2, 3);
+ ATF_CHECK_EQ(var3, &optind);
+
+ return NULL;
+}
+
+ATF_TC_BODY(t_tls_dlopen, tc)
+{
+ void *handle;
+ pthread_t t;
+
+#ifdef __HAVE_NO___THREAD
+ atf_tc_skip("no TLS support on this platform");
+#endif
+
+ handle = dlopen("h_tls_dlopen.so", RTLD_NOW | RTLD_LOCAL);
+ ATF_REQUIRE(handle != NULL);
+
+ testf_helper = dlsym(handle, "testf_dso_helper");
+ ATF_REQUIRE(testf_helper != NULL);
+
+ testf(NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+
+ dlclose(handle);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_tls_dlopen);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c
new file mode 100644
index 0000000..1982a9b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c
@@ -0,0 +1,107 @@
+/* $NetBSD: t_tls_dynamic.c,v 1.3 2012/01/17 20:34:57 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_tls_dynamic.c,v 1.3 2012/01/17 20:34:57 joerg Exp $");
+
+#include <atf-c.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+ATF_TC(t_tls_dynamic);
+
+ATF_TC_HEAD(t_tls_dynamic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test (un)initialized TLS variables in dynamic binaries");
+}
+
+void testf_dso_helper(int, int);
+
+extern __thread int var1;
+extern __thread int var2;
+extern __thread pid_t (*dso_var1)(void);
+
+__thread int *var3 = &optind;
+int var4_helper;
+__thread int *var4 = &var4_helper;
+
+static void *
+testf(void *dummy)
+{
+ ATF_CHECK_EQ(var1, 1);
+ ATF_CHECK_EQ(var2, 0);
+ testf_dso_helper(2, 2);
+ ATF_CHECK_EQ(var1, 2);
+ ATF_CHECK_EQ(var2, 2);
+ testf_dso_helper(3, 3);
+ ATF_CHECK_EQ(var1, 3);
+ ATF_CHECK_EQ(var2, 3);
+ ATF_CHECK_EQ(var3, &optind);
+ ATF_CHECK_EQ(var4, &var4_helper);
+ ATF_CHECK_EQ(dso_var1, getpid);
+
+ return NULL;
+}
+
+ATF_TC_BODY(t_tls_dynamic, tc)
+{
+ pthread_t t;
+
+#ifdef __HAVE_NO___THREAD
+ atf_tc_skip("no TLS support on this platform");
+#endif
+
+ testf(NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_tls_dynamic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c
new file mode 100644
index 0000000..db0ff16
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c
@@ -0,0 +1,95 @@
+/* $NetBSD: t_tls_static.c,v 1.2 2012/01/17 20:34:57 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_tls_static.c,v 1.2 2012/01/17 20:34:57 joerg Exp $");
+
+#include <atf-c.h>
+#include <pthread.h>
+
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+ATF_TC(t_tls_static);
+
+ATF_TC_HEAD(t_tls_static, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test (un)initialized TLS variables in static binaries");
+}
+
+void testf_helper(void);
+
+__thread int var1 = 1;
+__thread int var2;
+
+static void *
+testf(void *dummy)
+{
+ ATF_CHECK_EQ(var1, 1);
+ ATF_CHECK_EQ(var2, 0);
+ testf_helper();
+ ATF_CHECK_EQ(var1, -1);
+ ATF_CHECK_EQ(var2, -1);
+
+ return NULL;
+}
+
+ATF_TC_BODY(t_tls_static, tc)
+{
+ pthread_t t;
+
+#ifdef __HAVE_NO___THREAD
+ atf_tc_skip("no TLS support on this platform");
+#endif
+
+ testf(NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_tls_static);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c
new file mode 100644
index 0000000..841b2bf
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c
@@ -0,0 +1,55 @@
+/* $NetBSD: t_tls_static_helper.c,v 1.2 2012/01/17 20:34:57 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_tls_static_helper.c,v 1.2 2012/01/17 20:34:57 joerg Exp $");
+
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+extern __thread int var1;
+extern __thread int var2;
+
+void testf_helper(void);
+
+void
+testf_helper(void)
+{
+ var1 = -1;
+ var2 = -1;
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c
new file mode 100644
index 0000000..a5e78ff
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c
@@ -0,0 +1,58 @@
+/* $NetBSD: h_tls_dynamic.c,v 1.5 2013/10/21 19:11:17 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: h_tls_dynamic.c,v 1.5 2013/10/21 19:11:17 joerg Exp $");
+
+#include <unistd.h>
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+__thread int var1 = 1;
+__thread int var2;
+
+__thread pid_t (*dso_var1)(void) = getpid;
+
+void testf_dso_helper(int x, int y);
+
+void
+testf_dso_helper(int x, int y)
+{
+ var1 = x;
+ var2 = y;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c b/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c
new file mode 100644
index 0000000..5346898
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c
@@ -0,0 +1,174 @@
+/* $NetBSD: t_ptm.c,v 1.1 2011/01/13 03:19:57 pgoyette Exp $ */
+
+/*
+ * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_ptm.c,v 1.1 2011/01/13 03:19:57 pgoyette Exp $");
+
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#define REQUIRE_ERRNO(x, v) \
+ ATF_REQUIRE_MSG(x != v, "%s: %s", #x, strerror(errno))
+
+ATF_TC(ptm);
+
+ATF_TC_HEAD(ptm, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks /dev/ptm device");
+}
+
+ATF_TC_BODY(ptm, tc)
+{
+ struct stat stm, sts;
+ struct ptmget ptm;
+ int fdm;
+ struct group *gp;
+
+ if ((fdm = open("/dev/ptm", O_RDWR)) == -1) {
+ if (errno == ENOENT || errno == ENODEV)
+ atf_tc_skip("/dev/ptm: %s", strerror(errno));
+ atf_tc_fail("/dev/ptm: %s", strerror(errno));
+ }
+
+ REQUIRE_ERRNO(fstat(fdm, &stm), -1);
+ ATF_REQUIRE_EQ(major(stm.st_rdev), 165);
+ REQUIRE_ERRNO(ioctl(fdm, TIOCPTMGET, &ptm), -1);
+
+ ATF_REQUIRE_MSG(strncmp(ptm.cn, "/dev/pty", 8) == 0
+ || strncmp(ptm.cn, "/dev/null", 9) == 0,
+ "bad master name: %s", ptm.cn);
+
+ ATF_REQUIRE_MSG(strncmp(ptm.sn, "/dev/tty", 8) == 0
+ || strncmp(ptm.sn, "/dev/pts/", 9) == 0,
+ "bad slave name: %s", ptm.sn);
+
+ if (strncmp(ptm.cn, "/dev/null", 9) != 0) {
+ REQUIRE_ERRNO(fstat(ptm.cfd, &stm), -1);
+ REQUIRE_ERRNO(stat(ptm.cn, &sts), -1);
+ ATF_REQUIRE_EQ(stm.st_rdev, sts.st_rdev);
+ }
+
+ REQUIRE_ERRNO(fstat(ptm.sfd, &stm), -1);
+ REQUIRE_ERRNO(stat(ptm.sn, &sts), -1);
+ ATF_REQUIRE_EQ(stm.st_rdev, sts.st_rdev);
+
+ ATF_REQUIRE_EQ_MSG(sts.st_uid, getuid(), "bad slave uid");
+
+ ATF_REQUIRE_MSG((gp = getgrnam("tty")) != NULL,
+ "cannot find `tty' group");
+ ATF_REQUIRE_EQ_MSG(sts.st_gid, gp->gr_gid, "bad slave grid");
+
+ (void)close(ptm.sfd);
+ (void)close(ptm.cfd);
+ (void)close(fdm);
+}
+
+/*
+ * On NetBSD /dev/ptyp0 == /dev/pts/0 so we can check for major
+ * and minor device numbers. This check is non-portable. This
+ * check is now disabled because we might not have /dev/ptyp0
+ * at all.
+ */
+
+/*
+ * #define PTY_DEVNO_CHECK
+ */
+
+ATF_TC(ptmx);
+
+ATF_TC_HEAD(ptmx, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks /dev/ptmx device");
+}
+
+ATF_TC_BODY(ptmx, tc)
+{
+ struct stat stm, sts;
+ char *pty;
+ int fdm, fds;
+ struct group *gp;
+
+ if ((fdm = posix_openpt(O_RDWR|O_NOCTTY)) == -1) {
+ if (errno == ENOENT || errno == ENODEV)
+ atf_tc_skip("/dev/ptmx: %s", strerror(errno));
+
+ atf_tc_fail("/dev/ptmx: %s", strerror(errno));
+ }
+
+ REQUIRE_ERRNO(fstat(fdm, &stm), -1);
+
+#ifdef PTY_DEVNO_CHECK
+ REQUIRE_ERRNO(stat("/dev/ptyp0", &sts), -1);
+
+ ATF_REQUIRE_EQ_MSG(major(stm.st_rdev), major(sts.st_rdev),
+ "bad master major number");
+#endif
+
+ REQUIRE_ERRNO(grantpt(fdm), -1);
+ REQUIRE_ERRNO(unlockpt(fdm), -1);
+ REQUIRE_ERRNO((pty = ptsname(fdm)), NULL);
+
+ REQUIRE_ERRNO((fds = open(pty, O_RDWR|O_NOCTTY)), -1);
+ REQUIRE_ERRNO(fstat(fds, &sts), -1);
+
+#ifdef PTY_DEVNO_CHECK
+ ATF_REQUIRE_EQ_MSG(minor(stm.st_rdev), minor(sts.st_rdev),
+ "bad slave minor number");
+#endif
+
+ ATF_REQUIRE_EQ_MSG(sts.st_uid, getuid(), "bad slave uid");
+ ATF_REQUIRE_MSG((gp = getgrnam("tty")) != NULL,
+ "cannot find `tty' group");
+
+ ATF_REQUIRE_EQ_MSG(sts.st_gid, gp->gr_gid, "bad slave gid");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, ptm);
+ ATF_TP_ADD_TC(tp, ptmx);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c b/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c
new file mode 100644
index 0000000..5a5ec0f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c
@@ -0,0 +1,163 @@
+/* $NetBSD: t_ttyio.c,v 1.2 2011/04/19 20:07:53 martin Exp $ */
+
+/*
+ * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andrew Brown.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_ttyio.c,v 1.2 2011/04/19 20:07:53 martin Exp $");
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+
+#if defined(__NetBSD__)
+#include <util.h>
+#elif defined(__bsdi__)
+int openpty(int *, int *, char *, struct termios *, struct winsize *);
+#elif defined(__FreeBSD__)
+#include <libutil.h>
+#else
+#error where openpty?
+#endif
+
+#include <atf-c.h>
+
+#define REQUIRE_ERRNO(x, v) ATF_REQUIRE_MSG(x != v, "%s: %s", #x, strerror(errno))
+
+ATF_TC(ioctl);
+ATF_TC_HEAD(ioctl, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that ioctl calls are restarted "
+ "properly after being interrupted");
+}
+
+/* ARGSUSED */
+static void
+sigchld(int nsig)
+{
+ REQUIRE_ERRNO(wait(NULL), -1);
+}
+
+ATF_TC_BODY(ioctl, tc)
+{
+ int m, s, rc;
+ char name[128], buf[128];
+ struct termios term;
+ struct sigaction sa;
+
+ /* unbuffer stdout */
+ setbuf(stdout, NULL);
+
+ /*
+ * Create default termios settings for later use
+ */
+ memset(&term, 0, sizeof(term));
+ term.c_iflag = TTYDEF_IFLAG;
+ term.c_oflag = TTYDEF_OFLAG;
+ term.c_cflag = TTYDEF_CFLAG;
+ term.c_lflag = TTYDEF_LFLAG;
+ cfsetspeed(&term, TTYDEF_SPEED);
+
+ /* get a tty */
+ REQUIRE_ERRNO(openpty(&m, &s, name, &term, NULL), -1);
+
+ switch (fork()) {
+ case -1:
+ atf_tc_fail("fork(): %s", strerror(errno));
+ /* NOTREACHED */
+ case 0:
+ /* wait for parent to get set up */
+ (void)sleep(1);
+ (void)printf("child1: exiting\n");
+ exit(0);
+ /* NOTREACHED */
+ default:
+ (void)printf("parent: spawned child1\n");
+ break;
+ }
+
+ switch (fork()) {
+ case -1:
+ atf_tc_fail("fork(): %s", strerror(errno));
+ /* NOTREACHED */
+ case 0:
+ /* wait for parent to get upset */
+ (void)sleep(2);
+ /* drain the tty q */
+ if (read(m, buf, sizeof(buf)) == -1)
+ err(1, "read");
+ (void)printf("child2: exiting\n");
+ exit(0);
+ /* NOTREACHED */
+ default:
+ (void)printf("parent: spawned child2\n");
+ break;
+ }
+
+ /* set up a restarting signal handler */
+ (void)sigemptyset(&sa.sa_mask);
+ sa.sa_handler = sigchld;
+ sa.sa_flags = SA_RESTART;
+ REQUIRE_ERRNO(sigaction(SIGCHLD, &sa, NULL), -1);
+
+ /* put something in the output q */
+ REQUIRE_ERRNO(write(s, "Hello world\n", 12), -1);
+
+ /* ask for output to drain but don't drain it */
+ rc = 0;
+ if (tcsetattr(s, TCSADRAIN, &term) == -1) {
+ (void)printf("parent: tcsetattr: %s\n", strerror(errno));
+ rc = 1;
+ }
+
+ /* wait for last child */
+ sa.sa_handler = SIG_DFL;
+ REQUIRE_ERRNO(sigaction(SIGCHLD, &sa, NULL), -1);
+ (void) wait(NULL);
+
+ ATF_REQUIRE_EQ(rc, 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, ioctl);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libcrypt/t_crypt.c b/contrib/netbsd-tests/lib/libcrypt/t_crypt.c
new file mode 100644
index 0000000..1a192cb
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcrypt/t_crypt.c
@@ -0,0 +1,145 @@
+/* $NetBSD: t_crypt.c,v 1.3 2011/12/28 22:07:40 christos Exp $ */
+
+/*
+ * This version is derived from the original implementation of FreeSec
+ * (release 1.1) by David Burren. I've reviewed the changes made in
+ * OpenBSD (as of 2.7) and modified the original code in a similar way
+ * where applicable. I've also made it reentrant and made a number of
+ * other changes.
+ * - Solar Designer <solar at openwall.com>
+ */
+
+/*
+ * FreeSec: libcrypt for NetBSD
+ *
+ * Copyright (c) 1994 David Burren
+ * 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.
+ * 3. Neither the name of the author nor the names of other contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Owl: Owl/packages/glibc/crypt_freesec.c,v 1.6 2010/02/20 14:45:06 solar Exp $
+ * Id: crypt.c,v 1.15 1994/09/13 04:58:49 davidb Exp
+ *
+ * This is an original implementation of the DES and the crypt(3) interfaces
+ * by David Burren <davidb at werj.com.au>.
+ *
+ * An excellent reference on the underlying algorithm (and related
+ * algorithms) is:
+ *
+ * B. Schneier, Applied Cryptography: protocols, algorithms,
+ * and source code in C, John Wiley & Sons, 1994.
+ *
+ * Note that in that book's description of DES the lookups for the initial,
+ * pbox, and final permutations are inverted (this has been brought to the
+ * attention of the author). A list of errata for this book has been
+ * posted to the sci.crypt newsgroup by the author and is available for FTP.
+ *
+ * ARCHITECTURE ASSUMPTIONS:
+ * This code used to have some nasty ones, but these have been removed
+ * by now. The code requires a 32-bit integer type, though.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_crypt.c,v 1.3 2011/12/28 22:07:40 christos Exp $");
+
+#include <atf-c.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static const struct {
+ const char *hash;
+ const char *pw;
+} tests[] = {
+/* "new"-style */
+/* 0 */ { "_J9..CCCCXBrJUJV154M", "U*U*U*U*" },
+/* 1 */ { "_J9..CCCCXUhOBTXzaiE", "U*U***U" },
+/* 2 */ { "_J9..CCCC4gQ.mB/PffM", "U*U***U*" },
+/* 3 */ { "_J9..XXXXvlzQGqpPPdk", "*U*U*U*U" },
+/* 4 */ { "_J9..XXXXsqM/YSSP..Y", "*U*U*U*U*" },
+/* 5 */ { "_J9..XXXXVL7qJCnku0I", "*U*U*U*U*U*U*U*U" },
+/* 6 */ { "_J9..XXXXAj8cFbP5scI", "*U*U*U*U*U*U*U*U*" },
+/* 7 */ { "_J9..SDizh.vll5VED9g", "ab1234567" },
+/* 8 */ { "_J9..SDizRjWQ/zePPHc", "cr1234567" },
+/* 9 */ { "_J9..SDizxmRI1GjnQuE", "zxyDPWgydbQjgq" },
+/* 10 */ { "_K9..SaltNrQgIYUAeoY", "726 even" },
+/* 11 */ { "_J9..SDSD5YGyRCr4W4c", "" },
+/* "old"-style, valid salts */
+/* 12 */ { "CCNf8Sbh3HDfQ", "U*U*U*U*" },
+/* 13 */ { "CCX.K.MFy4Ois", "U*U***U" },
+/* 14 */ { "CC4rMpbg9AMZ.", "U*U***U*" },
+/* 15 */ { "XXxzOu6maQKqQ", "*U*U*U*U" },
+/* 16 */ { "SDbsugeBiC58A", "" },
+/* 17 */ { "./xZjzHv5vzVE", "password" },
+/* 18 */ { "0A2hXM1rXbYgo", "password" },
+/* 19 */ { "A9RXdR23Y.cY6", "password" },
+/* 20 */ { "ZziFATVXHo2.6", "password" },
+/* 21 */ { "zZDDIZ0NOlPzw", "password" },
+/* "old"-style, "reasonable" invalid salts, UFC-crypt behavior expected */
+/* 22 */ { "\001\002wyd0KZo65Jo", "password" },
+/* 23 */ { "a_C10Dk/ExaG.", "password" },
+/* 24 */ { "~\377.5OTsRVjwLo", "password" },
+/* The below are erroneous inputs, so NULL return is expected/required */
+/* 25 */ { "", "" }, /* no salt */
+/* 26 */ { " ", "" }, /* setting string is too short */
+/* 27 */ { "a:", "" }, /* unsafe character */
+/* 28 */ { "\na", "" }, /* unsafe character */
+/* 29 */ { "_/......", "" }, /* setting string is too short for its type */
+/* 30 */ { "_........", "" }, /* zero iteration count */
+/* 31 */ { "_/!......", "" }, /* invalid character in count */
+/* 32 */ { "_/......!", "" }, /* invalid character in salt */
+/* 33 */ { NULL, NULL }
+};
+
+ATF_TC(crypt_salts);
+
+ATF_TC_HEAD(crypt_salts, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "crypt(3) salt consistency checks");
+}
+
+ATF_TC_BODY(crypt_salts, tc)
+{
+ for (size_t i = 0; tests[i].hash; i++) {
+ char *hash = crypt(tests[i].pw, tests[i].hash);
+ if (!hash) {
+ ATF_CHECK_MSG(0, "Test %zu NULL\n", i);
+ continue;
+ }
+ if (strcmp(hash, "*0") == 0 && strlen(tests[i].hash) < 13)
+ continue; /* expected failure */
+ if (strcmp(hash, tests[i].hash))
+ ATF_CHECK_MSG(0, "Test %zu %s != %s\n",
+ i, hash, tests[i].hash);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, crypt_salts);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libcurses/atf.terminfo b/contrib/netbsd-tests/lib/libcurses/atf.terminfo
new file mode 100644
index 0000000..fcd34b6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/atf.terminfo
@@ -0,0 +1,44 @@
+# Based on xterm capabilities
+atf|atf automatic test frame pseudo terminal,
+ am, bce, ccc, km, mc5i, mir, msgr, npc, xenl,
+ colors#8, cols#80, it#8, lines#24, pairs#64,
+ acsc=++\,\,--..00``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
+ bel=bel, blink=blink, bold=bold, cbt=cbt, civis=civis, clear=clear,
+ cnorm=cnorm, cr=^M, csr=csr%i%p1%d;%p2%dX, cub=cub%p1%dX,
+ cub1=^H, cud=cud%p1%dX, cud1=^J, cuf=cuf%p1%dX, cuf1=,
+ cup=cup%i%p1%d;%p2%dX, cuu=cuu%p1%dX, cuu1=, cvvis=cvvis,
+ dch=dch%p1%dX, dch1=, dl=dl%p1%dX, dl1= , dim=dim, ech=ech%p1%dX,
+ ed=ed, el=el, el1=el1, enacs=enacs, flash=flash, home=home,
+ hpa=hpa%i%p1%dX, ht=^I, hts=hts, ich=ich%p1%dX, il=il%p1%dX,
+ il1=il1, ind=^M, indn=indn%p1%dX, invis=invis,
+ is2=is2, kDC=\E[3;2~, kEND=\E[1;2F, kHOM=\E[1;2H,
+ kIC=\E[2;2~, kLFT=\E[1;2D, kNXT=\E[6;2~, kPRV=\E[5;2~,
+ kRIT=\E[1;2C, kb2=\EOE, kbs=^H, kcbt=\E[Z, kcub1=\EOD, kcud1=\EOB,
+ kcuf1=\EOC, kcuu1=\EOA, kdch1=\E[3~, kend=\EOF, kent=\EOM,
+ kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf13=\E[1;2P,
+ kf14=\E[1;2Q, kf15=\E[1;2R, kf16=\E[1;2S, kf17=\E[15;2~,
+ kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ, kf20=\E[19;2~,
+ kf21=\E[20;2~, kf22=\E[21;2~, kf23=\E[23;2~, kf24=\E[24;2~,
+ kf25=\E[1;5P, kf26=\E[1;5Q, kf27=\E[1;5R, kf28=\E[1;5S,
+ kf29=\E[15;5~, kf3=\EOR, kf30=\E[17;5~, kf31=\E[18;5~,
+ kf32=\E[19;5~, kf33=\E[20;5~, kf34=\E[21;5~, kf35=\E[23;5~,
+ kf36=\E[24;5~, kf37=\E[1;6P, kf38=\E[1;6Q, kf39=\E[1;6R, kf4=\EOS,
+ kf40=\E[1;6S, kf41=\E[15;6~, kf42=\E[17;6~, kf43=\E[18;6~,
+ kf44=\E[19;6~, kf45=\E[20;6~, kf46=\E[21;6~, kf47=\E[23;6~,
+ kf48=\E[24;6~, kf49=\E[1;3P, kf5=\E[15~, kf50=\E[1;3Q,
+ kf51=\E[1;3R, kf52=\E[1;3S, kf53=\E[15;3~, kf54=\E[17;3~,
+ kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~, kf58=\E[21;3~,
+ kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~, kf61=\E[1;4P,
+ kf62=\E[1;4Q, kf63=\E[1;4R, kf7=\E[18~, kf8=\E[19~, kf9=\E[20~,
+ khome=\EOH, kich1=\E[2~, kind=\E[1;2B, kmous=\E[M, knp=\E[6~,
+ kpp=\E[5~, kri=\E[1;2A, mc0=mc0, mc4=mc4, mc5=mc5,
+ op=op, rc=rc, rev=rev, ri=ri, rin=rin%p1%dX, rmacs=rmacs,
+ rmam=rmam, rmcup=rmcup, rmir=rmir, rmkx=rmkx,
+ rmm=rmm, rmso=rmso, rmul=rmul, rs1=rs1,
+ rs2=rs2, sc=sc, setab=setab%p1%dX,
+ setaf=setaf%p1%dX, setb=setb%p1%dX, setf=setf%p1%dX,
+ sgr=sgr%p1%d;%p2%d;%p3%d;%p4%d;%p5%d;%p6%d;%p7%d;%p8;%d;%p9%dX,
+ sgr0=sgr0, smacs=smacs, smam=smam, smcup=smcup,
+ smir=smir, smkx=smkx, smm=smm, smso=smso, smul=smul,
+ tbc=tbc, u6=u6%d;%dX, u7=u7, u8=u8, u9=u9,
+ vpa=vpa%p1%dX
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/addch.chk b/contrib/netbsd-tests/lib/libcurses/check_files/addch.chk
new file mode 100644
index 0000000..3e2c6bb
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/addch.chk
@@ -0,0 +1 @@
+smsotrmso \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/addchstr.chk b/contrib/netbsd-tests/lib/libcurses/check_files/addchstr.chk
new file mode 100644
index 0000000..42286d0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/addchstr.chk
@@ -0,0 +1 @@
+revabcdehomesgr0 \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/addstr.chk b/contrib/netbsd-tests/lib/libcurses/check_files/addstr.chk
new file mode 100644
index 0000000..6a81654
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/addstr.chk
@@ -0,0 +1 @@
+abcde \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/attributes.chk b/contrib/netbsd-tests/lib/libcurses/check_files/attributes.chk
new file mode 100644
index 0000000..be35b56
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/attributes.chk
@@ -0,0 +1 @@
+smsoblinkhellormsosgr0 \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background1.chk
new file mode 100644
index 0000000..e52e439
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/background1.chk
@@ -0,0 +1 @@
+smulAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup2;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup3;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup4;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup5;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup6;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup7;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup8;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup9;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup10;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup11;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup12;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup13;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup14;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup15;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup16;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup17;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup18;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup19;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup20;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup21;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup22;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup23;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup24;1XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcup1;1Xrmul \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background2.chk
new file mode 100644
index 0000000..55a2163
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/background2.chk
@@ -0,0 +1 @@
+smula test stringrmul \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background3.chk
new file mode 100644
index 0000000..732f4cc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/background3.chk
@@ -0,0 +1 @@
+cup3;6X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background4.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background4.chk
new file mode 100644
index 0000000..05698e2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/background4.chk
@@ -0,0 +1,6 @@
+cup1;14Xcup3;6Xrevwindow
+B1BBBB
+BBBBBB
+BBBBBB
+BBBBBB
+BBBBBBcup4;8Xsgr0 \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/background5.chk b/contrib/netbsd-tests/lib/libcurses/check_files/background5.chk
new file mode 100644
index 0000000..6c37975
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/background5.chk
@@ -0,0 +1,3 @@
+cup1;14Xcup4;8Xrevhell
+o worl
+dsgr0 \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/bell.chk b/contrib/netbsd-tests/lib/libcurses/check_files/bell.chk
new file mode 100644
index 0000000..f4d3c21
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/bell.chk
@@ -0,0 +1 @@
+bel \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/box_standout.chk b/contrib/netbsd-tests/lib/libcurses/check_files/box_standout.chk
new file mode 100644
index 0000000..5bd91e1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/box_standout.chk
@@ -0,0 +1,5 @@
+revsmacsqqqqrmacs
+sgr0smsosmacsxrmacssmacsxrmacs
+smacsxrmacssmacsxrmacs
+smacsxrmacssmacsxrmacs
+smacsxrmacssmacsxrmacscup8;7Xrmsorevsmacsqqqqrmacscup3;6Xsgr0 \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/chgat1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/chgat1.chk
new file mode 100644
index 0000000..e9b8b58
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/chgat1.chk
@@ -0,0 +1 @@
+setaf7Xsetab0Xdsetaf3Xsetab6Xrev homesgr0 \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/chgat2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/chgat2.chk
new file mode 100644
index 0000000..cadfb37
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/chgat2.chk
@@ -0,0 +1 @@
+setaf7Xsetab0Xeop \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/chgat3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/chgat3.chk
new file mode 100644
index 0000000..7d57a90
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/chgat3.chk
@@ -0,0 +1 @@
+homesetaf3Xsetab6Xsmulde cup1;1Xrmulop \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear1.chk
new file mode 100644
index 0000000..9c7d34f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear1.chk
@@ -0,0 +1 @@
+clear \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear10.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear10.chk
new file mode 100644
index 0000000..1baa2a5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear10.chk
@@ -0,0 +1 @@
+cup7;7X EEEEE \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear2.chk
new file mode 100644
index 0000000..f25000b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear2.chk
@@ -0,0 +1 @@
+cup6;6Xabcdecup21;6Xfghijcup11;6X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear3.chk
new file mode 100644
index 0000000..dfdd90d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear3.chk
@@ -0,0 +1 @@
+cup21;6Xelcup11;6X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear4.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear4.chk
new file mode 100644
index 0000000..abe5be8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear4.chk
@@ -0,0 +1 @@
+elhome \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear5.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear5.chk
new file mode 100644
index 0000000..d9df62d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear5.chk
@@ -0,0 +1,23 @@
+homeel
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+el
+elhome \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear6.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear6.chk
new file mode 100644
index 0000000..ff815d3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear6.chk
@@ -0,0 +1 @@
+abccup7;7Xefgcup4;6X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear7.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear7.chk
new file mode 100644
index 0000000..8b392c3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear7.chk
@@ -0,0 +1 @@
+cup7;7Xelcup4;6X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear8.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear8.chk
new file mode 100644
index 0000000..9c9354e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear8.chk
@@ -0,0 +1,6 @@
+cup4;6X
+EEEEE
+EEEEE
+EEEEE
+EEEEE
+EEEEE cup3;6X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/clear9.chk b/contrib/netbsd-tests/lib/libcurses/check_files/clear9.chk
new file mode 100644
index 0000000..c5834a1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/clear9.chk
@@ -0,0 +1,6 @@
+cup3;6X
+EEEEE
+EEEEE
+EEEEE
+EEEEE
+EEEEE cup3;6X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_blank_draw.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_blank_draw.chk
new file mode 100644
index 0000000..42ad0e2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_blank_draw.chk
@@ -0,0 +1,24 @@
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xel
+opsetaf7Xsetab0Xelhomeop \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_blue_back.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_blue_back.chk
new file mode 100644
index 0000000..5c02e4d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_blue_back.chk
@@ -0,0 +1,24 @@
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xel
+opopsetab4Xelhome \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_default.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_default.chk
new file mode 100644
index 0000000..d23ddaf
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_default.chk
@@ -0,0 +1,24 @@
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopel
+opopelhomeop \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_red_fore.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_red_fore.chk
new file mode 100644
index 0000000..3ad4513
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_red_fore.chk
@@ -0,0 +1,24 @@
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xel
+opopsetaf1Xelhomeop \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_set.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_set.chk
new file mode 100644
index 0000000..d8363b7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_set.chk
@@ -0,0 +1 @@
+setaf1Xsetab2Xtestingop \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/color_start.chk b/contrib/netbsd-tests/lib/libcurses/check_files/color_start.chk
new file mode 100644
index 0000000..d314d07
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/color_start.chk
@@ -0,0 +1 @@
+op \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin1.chk
new file mode 100644
index 0000000..826062a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin1.chk
@@ -0,0 +1 @@
+cup11;15X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin10.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin10.chk
new file mode 100644
index 0000000..d5c8ea5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin10.chk
@@ -0,0 +1 @@
+cup11;15Xt s i cup12;15Xg e t cup13;15Xn t s cup14;15X n t scup15;15Xt n t cup16;15X t n t \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin11.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin11.chk
new file mode 100644
index 0000000..9315b76
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin11.chk
@@ -0,0 +1,4 @@
+cup3;6Xel
+ el
+ elcup6;7Xel
+ elcup8;7Xelcup3;6Xcup11;15Xelcup12;15Xelcup13;15Xelcup14;16Xelcup15;15Xelcup16;16Xelcup11;15X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin12.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin12.chk
new file mode 100644
index 0000000..bc1a526
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin12.chk
@@ -0,0 +1,4 @@
+cup3;6Xt s i
+ g e t
+ n t scup6;7Xn t s
+ t n tcup8;7Xt n tcup8;11X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin13.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin13.chk
new file mode 100644
index 0000000..f2a8913
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin13.chk
@@ -0,0 +1 @@
+cup11;16Xe t ncup12;16Xt s icup13;16Xg e tcup14;15Xi g ecup15;16Xi g ecup16;15Xs i g \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin14.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin14.chk
new file mode 100644
index 0000000..e7fd505
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin14.chk
@@ -0,0 +1 @@
+cup11;15Xtesticup12;15Xgtestcup13;15Xngtescup14;16Xngtescup15;15Xtingtcup16;16Xtingt \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin2.chk
new file mode 100644
index 0000000..aac0671
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin2.chk
@@ -0,0 +1,6 @@
+cup3;6Xtestin
+ gtesti
+ ngtest
+ ingtes
+ tingte
+ stingtcup8;11X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin3.chk
new file mode 100644
index 0000000..317cd93
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin3.chk
@@ -0,0 +1 @@
+cup12;16Xtestincup13;16Xgtesticup14;16Xngtestcup15;16Xingtescup16;16Xtingtecup17;16Xstingt \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin4.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin4.chk
new file mode 100644
index 0000000..4fa78a9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin4.chk
@@ -0,0 +1,6 @@
+cup3;6Xel
+ el
+ el
+ el
+ el
+ elcup12;16Xelcup13;16Xelcup14;16Xelcup15;16Xelcup16;16Xelcup17;16Xelcup11;15X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin5.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin5.chk
new file mode 100644
index 0000000..4f0d7da
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin5.chk
@@ -0,0 +1 @@
+testingtecup12;15Xstingtestcup13;15Xingtestincup14;15Xgtestingtcup15;15Xestingtescup16;15Xtingtesticup16;23X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin6.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin6.chk
new file mode 100644
index 0000000..314dac8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin6.chk
@@ -0,0 +1,6 @@
+cup3;6Xtestin
+ stingt
+ ingtes
+ gtesti
+ esting
+ tingtecup8;11X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin7.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin7.chk
new file mode 100644
index 0000000..d10a7c2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin7.chk
@@ -0,0 +1,6 @@
+cup3;6Xel
+ el
+ el
+ el
+ el
+ elcup11;15Xelcup12;15Xelcup13;15Xelcup14;15Xelcup15;15Xelcup16;15Xel \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin8.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin8.chk
new file mode 100644
index 0000000..bc1a526
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin8.chk
@@ -0,0 +1,4 @@
+cup3;6Xt s i
+ g e t
+ n t scup6;7Xn t s
+ t n tcup8;7Xt n tcup8;11X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/copywin9.chk b/contrib/netbsd-tests/lib/libcurses/check_files/copywin9.chk
new file mode 100644
index 0000000..f2a8913
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/copywin9.chk
@@ -0,0 +1 @@
+cup11;16Xe t ncup12;16Xt s icup13;16Xg e tcup14;15Xi g ecup15;16Xi g ecup16;15Xs i g \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curs_set1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set1.chk
new file mode 100644
index 0000000..81a818c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set1.chk
@@ -0,0 +1 @@
+civis \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curs_set2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set2.chk
new file mode 100644
index 0000000..7682463
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set2.chk
@@ -0,0 +1 @@
+cnorm \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curs_set3.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set3.chk
new file mode 100644
index 0000000..0f3e744
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/curs_set3.chk
@@ -0,0 +1 @@
+cvvis \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/curses_start.chk b/contrib/netbsd-tests/lib/libcurses/check_files/curses_start.chk
new file mode 100644
index 0000000..7c4f92c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/curses_start.chk
@@ -0,0 +1 @@
+enacsenacssmcupcnormclearclear \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/fill.chk b/contrib/netbsd-tests/lib/libcurses/check_files/fill.chk
new file mode 100644
index 0000000..2d89374
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/fill.chk
@@ -0,0 +1,23 @@
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEhome
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/home.chk b/contrib/netbsd-tests/lib/libcurses/check_files/home.chk
new file mode 100644
index 0000000..0247178
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/home.chk
@@ -0,0 +1 @@
+home \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/timeout.chk b/contrib/netbsd-tests/lib/libcurses/check_files/timeout.chk
new file mode 100644
index 0000000..6463b1e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/timeout.chk
@@ -0,0 +1 @@
+asmkx
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wborder.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wborder.chk
new file mode 100644
index 0000000..50857fa
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/wborder.chk
@@ -0,0 +1,6 @@
+smacslqqqqkrmacs
+ smacsxrmacs smacsxrmacs
+ smacsxrmacs smacsxrmacs
+ smacsxrmacs smacsxrmacs
+ smacsxrmacs smacsxrmacs
+ smacsmqqqqjrmacscup3;6X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wborder_refresh.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wborder_refresh.chk
new file mode 100644
index 0000000..0247178
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/wborder_refresh.chk
@@ -0,0 +1 @@
+home \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr.chk
new file mode 100644
index 0000000..770eab4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr.chk
@@ -0,0 +1 @@
+input \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr_refresh.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr_refresh.chk
new file mode 100644
index 0000000..e8bbed5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/wgetstr_refresh.chk
@@ -0,0 +1,2 @@
+
+ \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/window.chk b/contrib/netbsd-tests/lib/libcurses/check_files/window.chk
new file mode 100644
index 0000000..732f4cc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/window.chk
@@ -0,0 +1 @@
+cup3;6X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wprintw_refresh.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wprintw_refresh.chk
new file mode 100644
index 0000000..53794ad
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/wprintw_refresh.chk
@@ -0,0 +1 @@
+cup3;6Xhellocup3;10X \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wscrl1.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl1.chk
new file mode 100644
index 0000000..627141d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl1.chk
@@ -0,0 +1 @@
+cup4;7Xxxxxhome \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/check_files/wscrl2.chk b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl2.chk
new file mode 100644
index 0000000..ee36e55
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/check_files/wscrl2.chk
@@ -0,0 +1 @@
+cup4;7Xelcup6;7Xxxxxhome \ No newline at end of file
diff --git a/contrib/netbsd-tests/lib/libcurses/director/director.c b/contrib/netbsd-tests/lib/libcurses/director/director.c
new file mode 100644
index 0000000..c73ddae
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/director/director.c
@@ -0,0 +1,279 @@
+/* $NetBSD: director.c,v 1.10 2012/06/03 23:19:11 joerg Exp $ */
+
+/*-
+ * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
+ *
+ * All rights reserved.
+ *
+ * This code has been donated to The NetBSD Foundation by the Author.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/param.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <termios.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <util.h>
+#include <err.h>
+#include "returns.h"
+
+void yyparse(void);
+#define DEF_TERMPATH "."
+#define DEF_TERM "atf"
+#define DEF_SLAVE "./slave"
+
+const char *def_check_path = "./"; /* default check path */
+const char *def_include_path = "./"; /* default include path */
+
+extern size_t nvars; /* In testlang_conf.y */
+saved_data_t saved_output; /* In testlang_conf.y */
+int cmdpipe[2]; /* command pipe between director and slave */
+int slvpipe[2]; /* reply pipe back from slave */
+int master; /* pty to the slave */
+int verbose; /* control verbosity of tests */
+const char *check_path; /* path to prepend to check files for output
+ validation */
+const char *include_path; /* path to prepend to include files */
+char *cur_file; /* name of file currently being read */
+
+void init_parse_variables(int); /* in testlang_parse.y */
+
+/*
+ * Handle the slave exiting unexpectedly, try to recover the exit message
+ * and print it out.
+ */
+static void
+slave_died(int param)
+{
+ char last_words[256];
+ size_t count;
+
+ fprintf(stderr, "ERROR: Slave has exited\n");
+ if (saved_output.count > 0) {
+ fprintf(stderr, "output from slave: ");
+ for (count = 0; count < saved_output.count; count ++) {
+ if (isprint((unsigned char)saved_output.data[count]))
+ fprintf(stderr, "%c", saved_output.data[count]);
+ }
+ fprintf(stderr, "\n");
+ }
+
+ if ((count = read(master, &last_words, 255)) > 0) {
+ last_words[count] = '\0';
+ fprintf(stderr, "slave exited with message \"%s\"\n",
+ last_words);
+ }
+
+ exit(2);
+}
+
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s [-v] [-I include-path] [-C check-path] "
+ "[-T terminfo-file] [-s pathtoslave] [-t term] "
+ "commandfile\n", getprogname());
+ fprintf(stderr, " where:\n");
+ fprintf(stderr, " -v enables verbose test output\n");
+ fprintf(stderr, " -T is a directory containing the terminfo.cdb "
+ "file, or a file holding the terminfo description n");
+ fprintf(stderr, " -s is the path to the slave executable\n");
+ fprintf(stderr, " -t is value to set TERM to for the test\n");
+ fprintf(stderr, " -I is the directory to include files\n");
+ fprintf(stderr, " -C is the directory for config files\n");
+ fprintf(stderr, " commandfile is a file of test directives\n");
+ exit(1);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ extern char *optarg;
+ extern int optind;
+ const char *termpath, *term, *slave;
+ int ch;
+ pid_t slave_pid;
+ extern FILE *yyin;
+ char *arg1, *arg2, *arg3, *arg4;
+ struct termios term_attr;
+ struct stat st;
+
+ termpath = term = slave = NULL;
+ verbose = 0;
+
+ while ((ch = getopt(argc, argv, "vC:I:p:s:t:T:")) != -1) {
+ switch(ch) {
+ case 'I':
+ include_path = optarg;
+ break;
+ case 'C':
+ check_path = optarg;
+ break;
+ case 'T':
+ termpath = optarg;
+ break;
+ case 'p':
+ termpath = optarg;
+ break;
+ case 's':
+ slave = optarg;
+ break;
+ case 't':
+ term = optarg;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ break;
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ if (argc < 1)
+ usage();
+
+ if (termpath == NULL)
+ termpath = DEF_TERMPATH;
+
+ if (slave == NULL)
+ slave = DEF_SLAVE;
+
+ if (term == NULL)
+ term = DEF_TERM;
+
+ if (check_path == NULL)
+ check_path = getenv("CHECK_PATH");
+ if ((check_path == NULL) || (check_path[0] == '\0')) {
+ warn("$CHECK_PATH not set, defaulting to %s", def_check_path);
+ check_path = def_check_path;
+ }
+
+ if (include_path == NULL)
+ include_path = getenv("INCLUDE_PATH");
+ if ((include_path == NULL) || (include_path[0] == '\0')) {
+ warn("$INCLUDE_PATH not set, defaulting to %s",
+ def_include_path);
+ include_path = def_include_path;
+ }
+
+ signal(SIGCHLD, slave_died);
+
+ if (setenv("TERM", term, 1) != 0)
+ err(2, "Failed to set TERM variable");
+
+ if (stat(termpath, &st) == -1)
+ err(1, "Cannot stat %s", termpath);
+
+ if (S_ISDIR(st.st_mode)) {
+ char tinfo[MAXPATHLEN];
+ int l = snprintf(tinfo, sizeof(tinfo), "%s/%s", termpath,
+ "terminfo.cdb");
+ if (stat(tinfo, &st) == -1)
+ err(1, "Cannot stat `%s'", tinfo);
+ if (l >= 4)
+ tinfo[l - 4] = '\0';
+ if (setenv("TERMINFO", tinfo, 1) != 0)
+ err(1, "Failed to set TERMINFO variable");
+ } else {
+ int fd;
+ char *tinfo;
+ if ((fd = open(termpath, O_RDONLY)) == -1)
+ err(1, "Cannot open `%s'", termpath);
+ if ((tinfo = mmap(NULL, (size_t)st.st_size, PROT_READ, MAP_FILE,
+ fd, 0)) == MAP_FAILED)
+ err(1, "Cannot map `%s'", termpath);
+ if (setenv("TERMINFO", tinfo, 1) != 0)
+ err(1, "Failed to set TERMINFO variable");
+ close(fd);
+ munmap(tinfo, (size_t)st.st_size);
+ }
+
+ if (pipe(cmdpipe) < 0)
+ err(1, "Command pipe creation failed");
+
+ if (pipe(slvpipe) < 0)
+ err(1, "Slave pipe creation failed");
+
+ /*
+ * Create default termios settings for later use
+ */
+ memset(&term_attr, 0, sizeof(term_attr));
+ term_attr.c_iflag = TTYDEF_IFLAG;
+ term_attr.c_oflag = TTYDEF_OFLAG;
+ term_attr.c_cflag = TTYDEF_CFLAG;
+ term_attr.c_lflag = TTYDEF_LFLAG;
+ cfsetspeed(&term_attr, TTYDEF_SPEED);
+ term_attr.c_cc[VERASE] = '\b';
+ term_attr.c_cc[VKILL] = '\025'; /* ^U */
+
+ if ((slave_pid = forkpty(&master, NULL, &term_attr, NULL)) < 0)
+ err(1, "Fork of pty for slave failed\n");
+
+ if (slave_pid == 0) {
+ /* slave side, just exec the slave process */
+ if (asprintf(&arg1, "%d", cmdpipe[0]) < 0)
+ err(1, "arg1 conversion failed");
+
+ if (asprintf(&arg2, "%d", cmdpipe[1]) < 0)
+ err(1, "arg2 conversion failed");
+
+ if (asprintf(&arg3, "%d", slvpipe[0]) < 0)
+ err(1, "arg3 conversion failed");
+
+ if (asprintf(&arg4, "%d", slvpipe[1]) < 0)
+ err(1, "arg4 conversion failed");
+
+ if (execl(slave, slave, arg1, arg2, arg3, arg4, NULL) < 0)
+ err(1, "Exec of slave %s failed", slave);
+
+ /* NOT REACHED */
+ }
+
+ fcntl(master, F_SETFL, O_NONBLOCK);
+
+ if ((yyin = fopen(argv[0], "r")) == NULL)
+ err(1, "Cannot open command file %s", argv[0]);
+
+ if ((cur_file = strdup(argv[0])) == NULL)
+ err(2, "Failed to alloc memory for test file name");
+
+ init_parse_variables(1);
+
+ yyparse();
+ fclose(yyin);
+
+ exit(0);
+}
diff --git a/contrib/netbsd-tests/lib/libcurses/director/returns.h b/contrib/netbsd-tests/lib/libcurses/director/returns.h
new file mode 100644
index 0000000..150e358
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/director/returns.h
@@ -0,0 +1,66 @@
+/* $NetBSD: returns.h,v 1.1 2011/04/10 09:55:09 blymn Exp $ */
+
+/*-
+ * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
+ *
+ * All rights reserved.
+ *
+ * This code has been donated to The NetBSD Foundation by the Author.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ *
+ */
+#ifndef CTF_RETURNS_H
+#define CTF_RETURNS_H 1
+
+
+typedef enum {
+ ret_number = 1,
+ ret_string,
+ ret_byte,
+ ret_err,
+ ret_ok,
+ ret_null,
+ ret_nonnull,
+ ret_var,
+ ret_ref,
+ ret_count,
+ ret_slave_error
+} returns_enum_t;
+
+typedef struct {
+ returns_enum_t return_type;
+ void *return_value; /* used if return_type is ret_num or
+ or ret_byte or ret_string */
+ size_t return_len; /* number of bytes in return_value iff
+ return_type is ret_byte */
+ int return_index; /* index into var array for return
+ if return_type is ret_var */
+} returns_t;
+
+typedef struct {
+ size_t count;
+ size_t allocated;
+ size_t readp;
+ char *data;
+} saved_data_t;
+
+#endif /* CTF_RETURNS_H */
diff --git a/contrib/netbsd-tests/lib/libcurses/director/testlang_conf.l b/contrib/netbsd-tests/lib/libcurses/director/testlang_conf.l
new file mode 100644
index 0000000..a732afc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/director/testlang_conf.l
@@ -0,0 +1,437 @@
+%{
+/* $NetBSD: testlang_conf.l,v 1.7 2013/11/21 11:06:04 blymn Exp $ */
+
+/*-
+ * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
+ *
+ * All rights reserved.
+ *
+ * This code has been donated to The NetBSD Foundation by the Author.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <curses.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <err.h>
+#include "returns.h"
+#include "testlang_parse.h"
+
+#define MAX_INCLUDES 32 /* limit for the number of nested includes */
+
+int yylex(void);
+
+extern size_t line;
+extern char *include_path; /* from director.c */
+extern char *cur_file; /* from director.c */
+
+static int include_stack[MAX_INCLUDES];
+static char *include_files[MAX_INCLUDES];
+static int include_ptr = 0;
+
+static char *
+dequote(const char *s, size_t *len)
+{
+ const unsigned char *p;
+ char *buf, *q;
+
+ *len = 0;
+ p = (const unsigned char *)s;
+ while (*p) {
+ if (*p == '\\' && *(p+1)) {
+ if (isdigit(*(p+1)) && *(p+2) && isdigit(*(p+2)) &&
+ *(p+3) && isdigit(*(p+3)))
+ p += 3;
+ else
+ ++p;
+ }
+ ++(*len);
+ ++p;
+ }
+
+ buf = malloc(*len + 1);
+ if (buf == NULL)
+ return NULL;
+
+ p = (const unsigned char *)s;
+ q = buf;
+ while (*p) {
+ if (*p == '\\' && *(p+1)) {
+ ++p;
+ if (isdigit(*p)) {
+ if (*(p+1) && isdigit(*(p+1)) && *(p+2) &&
+ isdigit(*(p+2))) {
+ *q++ = ((*p - '0') * 8 + (*(p+1) - '0')) * 8 + (*(p+2) - '0');
+ p += 3;
+ } else {
+ *q++ = *p++;
+ }
+ } else {
+ switch (*p) {
+ case 'e':
+ /* escape */
+ *q++ = '\e';
+ p++;
+ break;
+
+ case 'n':
+ /* newline */
+ *q++ = '\n';
+ p++;
+ break;
+
+ case 'r':
+ /* carriage return */
+ *q++ = '\r';
+ p++;
+ break;
+
+ case 't':
+ /* tab */
+ *q++ = '\t';
+ p++;
+ break;
+
+ case '\\':
+ /* backslash */
+ *q++ = '\\';
+ p++;
+ break;
+
+ default:
+ *q++ = *p++;
+ }
+ }
+ } else
+ *q++ = *p++;
+ }
+ *q++ = '\0';
+
+ return buf;
+}
+%}
+
+HEX 0[xX][0-9a-zA-Z]+
+STRING [0-9a-z!#-&(-^ \t%._\\]+
+numeric [-0-9]+
+PCHAR (\\.|[^ \t\n])
+ASSIGN [aA][sS][sS][iI][gG][nN]
+CALL2 [cC][aA][lL][lL]2
+CALL3 [cC][aA][lL][lL]3
+CALL4 [cC][aA][lL][lL]4
+CALL [cC][aA][lL][lL]
+CHECK [cC][hH][eE][cC][kK]
+DELAY [dD][eE][lL][aA][yY]
+INPUT [iI][nN][pP][uU][tT]
+NOINPUT [nN][oO][iI][nN][pP][uU][tT]
+OK_RET [oO][kK]
+ERR_RET [eE][rR][rR]
+COMPARE [cC][oO][mM][pP][aA][rR][eE]
+COMPAREND [cC][oO][mM][pP][aA][rR][eE][Nn][Dd]
+FILENAME [A-Za-z0-9.][A-Za-z0-9./_-]+
+VARNAME [A-Za-z][A-Za-z0-9_-]+
+NULL_RET NULL
+NON_NULL NON_NULL
+BYTE BYTE
+OR \|
+LHB \(
+RHB \)
+
+%x incl
+%option noinput nounput
+
+%%
+
+include BEGIN(incl);
+
+<incl>[ \t]* /* eat the whitespace */
+<incl>[^ \t\n]+ { /* got the include file name */
+ char inc_file[MAXPATHLEN];
+
+ if (include_ptr > MAX_INCLUDES) {
+ fprintf(stderr,
+ "Maximum number of nested includes exceeded "
+ "at line %zu of file %s\n", line, cur_file);
+ exit(2);
+ }
+
+ if (yytext[0] != '/') {
+ if (strlcpy(inc_file, include_path, sizeof(inc_file))
+ >= sizeof(inc_file))
+ err(2, "CHECK_PATH too long");
+ if ((include_path[strlen(include_path) - 1] != '/') &&
+ ((strlcat(inc_file, "/", sizeof(inc_file))
+ >= sizeof(inc_file))))
+ err(2, "Could not append / to include file path");
+ } else {
+ inc_file[0] = '\0';
+ }
+
+ if (strlcat(inc_file, yytext, sizeof(inc_file))
+ >= sizeof(inc_file))
+ err(2, "Path to include file path overflowed");
+
+ yyin = fopen(inc_file, "r" );
+
+ if (!yyin)
+ err(1, "Error opening %s", inc_file);
+
+ yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
+
+ include_stack[include_ptr] = line;
+ include_files[include_ptr++] = cur_file;
+ cur_file = strdup(inc_file);
+ if (cur_file == NULL)
+ err(2, "Cannot allocate new include file string");
+ line = 0;
+ BEGIN(INITIAL);
+ }
+
+<<EOF>> {
+ yypop_buffer_state();
+
+ if ( !YY_CURRENT_BUFFER )
+ {
+ yyterminate();
+ }
+
+ if (--include_ptr < 0)
+ err(2, "Include stack underflow");
+
+ free(cur_file);
+ cur_file = include_files[include_ptr];
+ line = include_stack[include_ptr];
+ }
+
+{ASSIGN} {
+ return ASSIGN;
+ }
+
+{CALL2} {
+ return CALL2;
+ }
+
+{CALL3} {
+ return CALL3;
+ }
+
+{CALL4} {
+ return CALL4;
+ }
+
+{CALL} {
+ return CALL;
+ }
+
+{CHECK} {
+ return CHECK;
+ }
+
+{DELAY} {
+ return DELAY;
+ }
+
+{INPUT} {
+ return INPUT;
+ }
+
+{NOINPUT} {
+ return NOINPUT;
+ }
+
+{COMPARE} {
+ return COMPARE;
+ }
+
+{COMPAREND} {
+ return COMPAREND;
+ }
+
+{NON_NULL} {
+ return NON_NULL;
+ }
+
+{NULL_RET} {
+ return NULL_RET;
+ }
+
+{OK_RET} {
+ return OK_RET;
+ }
+
+{ERR_RET} {
+ return ERR_RET;
+ }
+
+{OR} {
+ return OR;
+ }
+
+{LHB} {
+ return LHB;
+ }
+
+{RHB} {
+ return RHB;
+ }
+
+{HEX} {
+ /* Hex value, convert to decimal and return numeric */
+ unsigned long val;
+
+ if (sscanf(yytext, "%lx", &val) != 1)
+ err(1, "Bad hex conversion");
+
+ asprintf(&yylval.string, "%ld", val);
+ return numeric;
+ }
+
+
+{numeric} {
+ if ((yylval.string = strdup(yytext)) == NULL)
+ err(1, "Cannot allocate numeric string");
+ return numeric;
+}
+
+{VARNAME} {
+ if ((yylval.string = strdup(yytext)) == NULL)
+ err(1, "Cannot allocate string for varname");
+ return VARNAME;
+ }
+
+{FILENAME} {
+ size_t len;
+
+ if ((yylval.string = dequote(yytext, &len)) == NULL)
+ err(1, "Cannot allocate filename string");
+ return FILENAME;
+ }
+
+ /* path */
+\/{PCHAR}+ {
+ size_t len;
+ if ((yylval.string = dequote(yytext, &len)) == NULL)
+ err(1, "Cannot allocate string");
+ return PATH;
+ }
+
+\'{STRING}\' {
+ char *p;
+ size_t len;
+
+ if ((yylval.retval = malloc(sizeof(returns_t))) == NULL)
+ err(1, "Cannot allocate return struct");
+ p = yytext;
+ p++; /* skip the leading ' */
+ if ((yylval.retval->return_value = dequote(p, &len))
+ == NULL)
+ err(1, "Cannot allocate string");
+
+ yylval.retval->return_type = ret_byte;
+ /* trim trailing ' */
+ yylval.retval->return_len = len - 1;
+ return BYTE;
+ }
+
+\`{STRING}\` {
+ char *p, *str;
+ size_t len, chlen;
+ size_t i;
+ chtype *rv;
+
+ if ((yylval.retval = malloc(sizeof(returns_t))) == NULL)
+ err(1, "Cannot allocate return struct");
+ p = yytext;
+ p++; /* skip the leading ' */
+ if ((str = dequote(p, &len)) == NULL)
+ err(1, "Cannot allocate string");
+ len--; /* trim trailing ` */
+ if ((len % 2) != 0)
+ len--;
+
+ chlen = ((len / 2) + 1) * sizeof(chtype);
+ if ((yylval.retval->return_value = malloc(chlen))
+ == NULL)
+ err(1, "Cannot allocate chtype array");
+
+ rv = yylval.retval->return_value;
+ for (i = 0; i < len; i += 2)
+ *rv++ = (str[i] << 8) | str[i+1];
+ *rv = __NORMAL | '\0'; /* terminates chtype array */
+ yylval.retval->return_type = ret_byte;
+ yylval.retval->return_len = chlen;
+ return BYTE;
+ }
+
+\"{STRING}\" {
+ char *p;
+ size_t len;
+
+ p = yytext;
+ p++; /* skip the leading " */
+ if ((yylval.string = dequote(p, &len)) == NULL)
+ err(1, "Cannot allocate string");
+
+ /* remove trailing " */
+ yylval.string[len - 1] = '\0';
+ return STRING;
+ }
+
+\${VARNAME} {
+ char *p;
+
+ p = yytext;
+ p++; /* skip $ before var name */
+ if ((yylval.string = strdup(p)) == NULL)
+ err(1, "Cannot allocate string for varname");
+ return VARIABLE;
+ }
+
+ /* comments, white-outs */
+[ \t\r] |
+#.* ;
+^#.*\n |
+#.*\n |
+\\\n |
+^\n {
+line++; }
+
+ /* eol on a line with data. need to process, return eol */
+\n {
+ line++;
+ return EOL;
+ }
+
+. {
+ }
+
+%%
+
+int
+yywrap(void)
+{
+ return 1;
+}
diff --git a/contrib/netbsd-tests/lib/libcurses/director/testlang_parse.y b/contrib/netbsd-tests/lib/libcurses/director/testlang_parse.y
new file mode 100644
index 0000000..37c813f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/director/testlang_parse.y
@@ -0,0 +1,1617 @@
+%{
+/* $NetBSD: testlang_parse.y,v 1.13 2012/09/19 11:51:56 blymn Exp $ */
+
+/*-
+ * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
+ *
+ * All rights reserved.
+ *
+ * This code has been donated to The NetBSD Foundation by the Author.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <assert.h>
+#include <curses.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <err.h>
+#include <unistd.h>
+#include <poll.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/syslimits.h>
+#include <time.h>
+#include <vis.h>
+#include <stdint.h>
+#include "returns.h"
+
+#define YYDEBUG 1
+
+extern int verbose;
+extern int cmdpipe[2];
+extern int slvpipe[2];
+extern int master;
+extern struct pollfd readfd;
+extern char *check_path;
+extern char *cur_file; /* from director.c */
+
+int yylex(void);
+
+size_t line;
+
+static int input_delay;
+
+/* time delay between inputs chars - default to 0.1ms minimum to prevent
+ * problems with input tests
+ */
+#define DELAY_MIN 0.1
+
+/* time delay after a function call - allows the slave time to
+ * run the function and output data before we do other actions.
+ * Set this to 50ms.
+ */
+#define POST_CALL_DELAY 50
+
+static struct timespec delay_spec = {0, 1000 * DELAY_MIN};
+static struct timespec delay_post_call = {0, 1000 * POST_CALL_DELAY};
+
+static char *input_str; /* string to feed in as input */
+static bool no_input; /* don't need more input */
+
+#define READ_PIPE 0
+#define WRITE_PIPE 1
+
+const char *returns_enum_names[] = {
+ "unused", "numeric", "string", "byte", "ERR", "OK", "NULL", "not NULL",
+ "variable", "reference", "returns count", "slave error"
+};
+
+typedef enum {
+ arg_static,
+ arg_byte,
+ arg_var,
+ arg_null
+} args_state_t;
+
+static const char *args_enum_names[] = {
+ "static", "byte", "var", "NULL"
+};
+
+typedef struct {
+ args_state_t arg_type;
+ size_t arg_len;
+ char *arg_string;
+ int var_index;
+} args_t;
+
+typedef struct {
+ char *function;
+ int nrets; /* number of returns */
+ returns_t *returns; /* array of expected returns */
+ int nargs; /* number of arguments */
+ args_t *args; /* arguments for the call */
+} cmd_line_t;
+
+static cmd_line_t command;
+
+typedef struct {
+ char *name;
+ size_t len;
+ returns_enum_t type;
+ void *value;
+} var_t;
+
+static size_t nvars; /* Number of declared variables */
+static var_t *vars; /* Variables defined during the test. */
+
+static int check_function_table(char *, const char *[], int);
+static int find_var_index(const char *);
+static void assign_arg(args_state_t, void *);
+static int assign_var(char *);
+void init_parse_variables(int);
+static void validate(int, void *);
+static void validate_return(const char *, const char *, int);
+static void validate_variable(int, returns_enum_t, const void *, int, int);
+static void validate_byte(returns_t *, returns_t *, int);
+static void write_cmd_pipe(char *);
+static void write_cmd_pipe_args(args_state_t, void *);
+static void read_cmd_pipe(returns_t *);
+static void write_func_and_args(void);
+static void compare_streams(char *, bool);
+static void do_function_call(size_t);
+static void save_slave_output(bool);
+static void validate_type(returns_enum_t, returns_t *, int);
+static void set_var(returns_enum_t, char *, void *);
+static void validate_reference(int, void *);
+static char *numeric_or(char *, char *);
+static char *get_numeric_var(const char *);
+static void perform_delay(struct timespec *);
+
+static const char *input_functions[] = {
+ "getch", "getnstr", "getstr", "mvgetnstr", "mvgetstr", "mvgetnstr",
+ "mvgetstr", "mvscanw", "mvwscanw", "scanw", "wgetch", "wgetnstr",
+ "wgetstr"
+};
+
+static const unsigned ninput_functions =
+ sizeof(input_functions) / sizeof(char *);
+
+saved_data_t saved_output;
+
+%}
+
+%union {
+ char *string;
+ returns_t *retval;
+}
+
+%token <string> PATH
+%token <string> STRING
+%token <retval> BYTE
+%token <string> VARNAME
+%token <string> FILENAME
+%token <string> VARIABLE
+%token <string> REFERENCE
+%token <string> NULL_RET
+%token <string> NON_NULL
+%token <string> ERR_RET
+%token <string> OK_RET
+%token <string> numeric
+%token <string> DELAY
+%token <string> INPUT
+%token <string> COMPARE
+%token <string> COMPAREND
+%token <string> ASSIGN
+%token EOL CALL CHECK NOINPUT OR LHB RHB
+%token CALL2 CALL3 CALL4 DRAIN
+
+%nonassoc OR
+
+%%
+
+statement : /* empty */
+ | assign statement
+ | call statement
+ | call2 statement
+ | call3 statement
+ | call4 statement
+ | check statement
+ | delay statement
+ | input statement
+ | noinput statement
+ | compare statement
+ | comparend statement
+ | eol statement
+ ;
+
+assign : ASSIGN VARNAME numeric {set_var(ret_number, $2, $3);} eol
+ | ASSIGN VARNAME LHB expr RHB {set_var(ret_number, $2, $<string>4);} eol
+ | ASSIGN VARNAME STRING {set_var(ret_string, $2, $3);} eol
+ | ASSIGN VARNAME BYTE {set_var(ret_byte, $2, $3);} eol
+ ;
+
+call : CALL result fn_name args eol {
+ do_function_call(1);
+}
+ ;
+
+call2 : CALL2 result result fn_name args eol {
+ do_function_call(2);
+}
+ ;
+
+call3 : CALL3 result result result fn_name args eol {
+ do_function_call(3);
+}
+ ;
+
+call4 : CALL4 result result result result fn_name args eol {
+ do_function_call(4);
+ }
+ ;
+
+check : CHECK var returns eol {
+ returns_t retvar;
+ var_t *vptr;
+ if (command.returns[0].return_index == -1)
+ err(1, "Undefined variable in check statement, line %zu"
+ " of file %s", line, cur_file);
+
+ if (verbose) {
+ fprintf(stderr, "Checking contents of variable %s for %s\n",
+ vars[command.returns[0].return_index].name,
+ returns_enum_names[command.returns[1].return_type]);
+ }
+
+ if (((command.returns[1].return_type == ret_byte) &&
+ (vars[command.returns[0].return_index].type != ret_byte)) ||
+ vars[command.returns[0].return_index].type != ret_string)
+ err(1, "Var type %s (%d) does not match return type %s (%d)",
+ returns_enum_names[
+ vars[command.returns[0].return_index].type],
+ vars[command.returns[0].return_index].type,
+ returns_enum_names[command.returns[1].return_type],
+ command.returns[1].return_type);
+
+ switch (command.returns[1].return_type) {
+ case ret_err:
+ validate_variable(0, ret_string, "ERR",
+ command.returns[0].return_index, 0);
+ break;
+
+ case ret_ok:
+ validate_variable(0, ret_string, "OK",
+ command.returns[0].return_index, 0);
+ break;
+
+ case ret_null:
+ validate_variable(0, ret_string, "NULL",
+ command.returns[0].return_index, 0);
+ break;
+
+ case ret_nonnull:
+ validate_variable(0, ret_string, "NULL",
+ command.returns[0].return_index, 1);
+ break;
+
+ case ret_string:
+ case ret_number:
+ if (verbose) {
+ fprintf(stderr, " %s == returned %s\n",
+ (const char *)command.returns[1].return_value,
+ (const char *)
+ vars[command.returns[0].return_index].value);
+ }
+ validate_variable(0, ret_string,
+ command.returns[1].return_value,
+ command.returns[0].return_index, 0);
+ break;
+
+ case ret_byte:
+ vptr = &vars[command.returns[0].return_index];
+ retvar.return_len = vptr->len;
+ retvar.return_type = vptr->type;
+ retvar.return_value = vptr->value;
+ validate_byte(&retvar, &command.returns[1], 0);
+ break;
+
+ default:
+ err(1, "Malformed check statement at line %zu "
+ "of file %s", line, cur_file);
+ break;
+ }
+
+ init_parse_variables(0);
+ }
+ ;
+
+delay : DELAY numeric eol {
+ /* set the inter-character delay */
+ if (sscanf($2, "%d", &input_delay) == 0)
+ err(1, "delay specification %s could not be converted to "
+ "numeric at line %zu of file %s", $2, line, cur_file);
+ if (verbose) {
+ fprintf(stderr, "Set input delay to %d ms\n", input_delay);
+ }
+
+ if (input_delay < DELAY_MIN)
+ input_delay = DELAY_MIN;
+ /*
+ * Fill in the timespec structure now ready for use later.
+ * The delay is specified in milliseconds so convert to timespec
+ * values
+ */
+ delay_spec.tv_sec = input_delay / 1000;
+ delay_spec.tv_nsec = (input_delay - 1000 * delay_spec.tv_sec) * 1000;
+ if (verbose) {
+ fprintf(stderr, "set delay to %jd.%jd\n",
+ (intmax_t)delay_spec.tv_sec,
+ (intmax_t)delay_spec.tv_nsec);
+ }
+
+ init_parse_variables(0);
+ }
+ ;
+
+input : INPUT STRING eol {
+ if (input_str != NULL) {
+ warnx("%s, %zu: Discarding unused input string",
+ cur_file, line);
+ free(input_str);
+ }
+
+ if ((input_str = malloc(strlen($2) + 1)) == NULL)
+ err(2, "Cannot allocate memory for input string");
+
+ strlcpy(input_str, $2, strlen($2) + 1);
+}
+ ;
+
+
+noinput : NOINPUT eol {
+ if (input_str != NULL) {
+ warnx("%s, %zu: Discarding unused input string",
+ cur_file, line);
+ free(input_str);
+ }
+
+ no_input = true;
+ }
+
+compare : COMPARE PATH eol
+ | COMPARE FILENAME eol
+{
+ compare_streams($2, true);
+}
+ ;
+
+
+comparend : COMPAREND PATH eol
+ | COMPAREND FILENAME eol
+{
+ compare_streams($2, false);
+}
+ ;
+
+
+result : returns
+ | var
+ | reference
+ ;
+
+returns : numeric { assign_rets(ret_number, $1); }
+ | LHB expr RHB { assign_rets(ret_number, $<string>2); }
+ | STRING { assign_rets(ret_string, $1); }
+ | BYTE { assign_rets(ret_byte, (void *) $1); }
+ | ERR_RET { assign_rets(ret_err, NULL); }
+ | OK_RET { assign_rets(ret_ok, NULL); }
+ | NULL_RET { assign_rets(ret_null, NULL); }
+ | NON_NULL { assign_rets(ret_nonnull, NULL); }
+ ;
+
+var : VARNAME {
+ assign_rets(ret_var, $1);
+ }
+ ;
+
+reference : VARIABLE {
+ assign_rets(ret_ref, $1);
+ }
+
+fn_name : VARNAME {
+ if (command.function != NULL)
+ free(command.function);
+
+ command.function = malloc(strlen($1) + 1);
+ if (command.function == NULL)
+ err(1, "Could not allocate memory for function name");
+ strcpy(command.function, $1);
+ }
+ ;
+
+expr : numeric
+ | VARIABLE
+ { $<string>$ = get_numeric_var($1); }
+ | expr OR expr
+ { $<string>$ = numeric_or($<string>1, $<string>3); }
+ ;
+
+args : /* empty */
+ | LHB expr RHB { assign_arg(arg_static, $<string>2); } args
+ | numeric { assign_arg(arg_static, $1); } args
+ | STRING { assign_arg(arg_static, $1); } args
+ | BYTE { assign_arg(arg_byte, $1); } args
+ | PATH { assign_arg(arg_static, $1); } args
+ | FILENAME { assign_arg(arg_static, $1); } args
+ | VARNAME { assign_arg(arg_static, $1); } args
+ | VARIABLE { assign_arg(arg_var, $1); } args
+ | NULL_RET { assign_arg(arg_null, $1); } args
+ ;
+
+eol : EOL
+ ;
+
+%%
+
+static void
+excess(const char *fname, size_t lineno, const char *func, const char *comment,
+ const void *data, size_t datalen)
+{
+ size_t dstlen = datalen * 4 + 1;
+ char *dst = malloc(dstlen);
+
+ if (dst == NULL)
+ err(1, "malloc");
+
+ if (strnvisx(dst, dstlen, data, datalen, VIS_WHITE | VIS_OCTAL) == -1)
+ err(1, "strnvisx");
+
+ warnx("%s, %zu: [%s] Excess %zu bytes%s [%s]",
+ fname, lineno, func, datalen, comment, dst);
+ free(dst);
+}
+
+/*
+ * Get the value of a variable, error if the variable has not been set or
+ * is not a numeric type.
+ */
+static char *
+get_numeric_var(const char *var)
+{
+ int i;
+
+ if ((i = find_var_index(var)) < 0)
+ err(1, "Variable %s is undefined", var);
+
+ if (vars[i].type != ret_number)
+ err(1, "Variable %s is not a numeric type", var);
+
+ return vars[i].value;
+}
+
+/*
+ * Perform a bitwise OR on two numbers and return the result.
+ */
+static char *
+numeric_or(char *n1, char *n2)
+{
+ unsigned long i1, i2, result;
+ char *ret;
+
+ i1 = strtoul(n1, NULL, 10);
+ i2 = strtoul(n2, NULL, 10);
+
+ result = i1 | i2;
+ asprintf(&ret, "%lu", result);
+
+ if (verbose) {
+ fprintf(stderr, "numeric or of 0x%lx (%s) and 0x%lx (%s)"
+ " results in 0x%lx (%s)\n",
+ i1, n1, i2, n2, result, ret);
+ }
+
+ return ret;
+}
+
+/*
+ * Sleep for the specified time, handle the sleep getting interrupted
+ * by a signal.
+ */
+static void
+perform_delay(struct timespec *ts)
+{
+ struct timespec delay_copy, delay_remainder;
+
+ delay_copy = *ts;
+ while (nanosleep(&delay_copy, &delay_remainder) < 0) {
+ if (errno != EINTR)
+ err(2, "nanosleep returned error");
+ delay_copy = delay_remainder;
+ }
+}
+
+/*
+ * Assign the value given to the named variable.
+ */
+static void
+set_var(returns_enum_t type, char *name, void *value)
+{
+ int i;
+ char *number;
+ returns_t *ret;
+
+ i = find_var_index(name);
+ if (i < 0)
+ i = assign_var(name);
+
+ vars[i].type = type;
+ if ((type == ret_number) || (type == ret_string)) {
+ number = value;
+ vars[i].len = strlen(number) + 1;
+ vars[i].value = malloc(vars[i].len + 1);
+ if (vars[i].value == NULL)
+ err(1, "Could not malloc memory for assign string");
+ strcpy(vars[i].value, number);
+ } else {
+ /* can only be a byte value */
+ ret = value;
+ vars[i].len = ret->return_len;
+ vars[i].value = malloc(vars[i].len);
+ if (vars[i].value == NULL)
+ err(1, "Could not malloc memory to assign byte string");
+ memcpy(vars[i].value, ret->return_value, vars[i].len);
+ }
+}
+
+/*
+ * Add a new variable to the vars array, the value will be assigned later,
+ * when a test function call returns.
+ */
+static int
+assign_var(char *varname)
+{
+ var_t *temp;
+ char *name;
+
+ if ((name = malloc(strlen(varname) + 1)) == NULL)
+ err(1, "Alloc of varname failed");
+
+ if ((temp = realloc(vars, sizeof(*temp) * (nvars + 1))) == NULL) {
+ free(name);
+ err(1, "Realloc of vars array failed");
+ }
+
+ strcpy(name, varname);
+ vars = temp;
+ vars[nvars].name = name;
+ vars[nvars].len = 0;
+ vars[nvars].value = NULL;
+ nvars++;
+
+ return (nvars - 1);
+}
+
+/*
+ * Allocate and assign a new argument of the given type.
+ */
+static void
+assign_arg(args_state_t arg_type, void *arg)
+{
+ args_t *temp, cur;
+ char *str = arg;
+ returns_t *ret;
+
+ if (verbose) {
+ fprintf(stderr, "function is >%s<, adding arg >%s< type %s\n",
+ command.function, str, args_enum_names[arg_type]);
+ }
+
+ cur.arg_type = arg_type;
+ switch (arg_type) {
+ case arg_var:
+ cur.var_index = find_var_index(arg);
+ if (cur.var_index < 0)
+ err(1, "Invalid variable %s at line %zu of file %s",
+ str, line, cur_file);
+ cur.arg_type = ret_string;
+ break;
+
+ case arg_byte:
+ ret = arg;
+ cur.arg_len = ret->return_len;
+ cur.arg_string = malloc(cur.arg_len);
+ if (cur.arg_string == NULL)
+ err(1, "Could not malloc memory for arg bytes");
+ memcpy(cur.arg_string, ret->return_value, cur.arg_len);
+ break;
+
+ case arg_null:
+ cur.arg_len = 0;
+ cur.arg_string = NULL;
+ break;
+
+ default:
+ cur.arg_len = strlen(str);
+ cur.arg_string = malloc(cur.arg_len + 1);
+ if (cur.arg_string == NULL)
+ err(1, "Could not malloc memory for arg string");
+ strcpy(cur.arg_string, arg);
+ }
+
+ temp = realloc(command.args, sizeof(*temp) * (command.nargs + 1));
+ if (temp == NULL)
+ err(1, "Failed to reallocate args");
+ command.args = temp;
+ memcpy(&command.args[command.nargs], &cur, sizeof(args_t));
+ command.nargs++;
+}
+
+/*
+ * Allocate and assign a new return.
+ */
+static void
+assign_rets(returns_enum_t ret_type, void *ret)
+{
+ returns_t *temp, cur;
+ char *ret_str;
+ returns_t *ret_ret;
+
+ cur.return_type = ret_type;
+ if (ret_type != ret_var) {
+ if ((ret_type == ret_number) || (ret_type == ret_string)) {
+ ret_str = ret;
+ cur.return_len = strlen(ret_str) + 1;
+ cur.return_value = malloc(cur.return_len + 1);
+ if (cur.return_value == NULL)
+ err(1,
+ "Could not malloc memory for arg string");
+ strcpy(cur.return_value, ret_str);
+ } else if (ret_type == ret_byte) {
+ ret_ret = ret;
+ cur.return_len = ret_ret->return_len;
+ cur.return_value = malloc(cur.return_len);
+ if (cur.return_value == NULL)
+ err(1,
+ "Could not malloc memory for byte string");
+ memcpy(cur.return_value, ret_ret->return_value,
+ cur.return_len);
+ } else if (ret_type == ret_ref) {
+ if ((cur.return_index = find_var_index(ret)) < 0)
+ err(1, "Undefined variable reference");
+ }
+ } else {
+ cur.return_index = find_var_index(ret);
+ if (cur.return_index < 0)
+ cur.return_index = assign_var(ret);
+ }
+
+ temp = realloc(command.returns, sizeof(*temp) * (command.nrets + 1));
+ if (temp == NULL)
+ err(1, "Failed to reallocate returns");
+ command.returns = temp;
+ memcpy(&command.returns[command.nrets], &cur, sizeof(returns_t));
+ command.nrets++;
+}
+
+/*
+ * Find the given variable name in the var array and return the i
+ * return -1 if var is not found.
+ */
+static int
+find_var_index(const char *var_name)
+{
+ int result;
+ size_t i;
+
+ result = -1;
+
+ for (i = 0; i < nvars; i++) {
+ if (strcmp(var_name, vars[i].name) == 0) {
+ result = i;
+ break;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Check the given function name in the given table of names, return 1 if
+ * there is a match.
+ */
+static int check_function_table(char *function, const char *table[],
+ int nfunctions)
+{
+ int i;
+
+ for (i = 0; i < nfunctions; i++) {
+ if ((strlen(function) == strlen(table[i])) &&
+ (strcmp(function, table[i]) == 0))
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Compare the output from the slave against the given file and report
+ * any differences.
+ */
+static void
+compare_streams(char *filename, bool discard)
+{
+ char check_file[PATH_MAX], drain[100], ref, data;
+ struct pollfd fds[2];
+ int nfd, check_fd;
+ ssize_t result;
+ size_t offs;
+
+ /*
+ * Don't prepend check path iff check file has an absolute
+ * path.
+ */
+ if (filename[0] != '/') {
+ if (strlcpy(check_file, check_path, sizeof(check_file))
+ >= sizeof(check_file))
+ err(2, "CHECK_PATH too long");
+
+ if (strlcat(check_file, "/", sizeof(check_file))
+ >= sizeof(check_file))
+ err(2, "Could not append / to check file path");
+ } else {
+ check_file[0] = '\0';
+ }
+
+ if (strlcat(check_file, filename, sizeof(check_file))
+ >= sizeof(check_file))
+ err(2, "Path to check file path overflowed");
+
+ if ((check_fd = open(check_file, O_RDONLY, 0)) < 0)
+ err(2, "failed to open file %s line %zu of file %s",
+ check_file, line, cur_file);
+
+ fds[0].fd = check_fd;
+ fds[0].events = POLLIN;
+ fds[1].fd = master;
+ fds[1].events = POLLIN;
+
+ nfd = 2;
+ /*
+ * if we have saved output then only check for data in the
+ * reference file since the slave data may already be drained.
+ */
+ if (saved_output.count > 0)
+ nfd = 1;
+
+ offs = 0;
+ while (poll(fds, nfd, 500) == nfd) {
+ if (fds[0].revents & POLLIN) {
+ if ((result = read(check_fd, &ref, 1)) < 1) {
+ if (result != 0) {
+ err(2,
+ "Bad read on file %s", check_file);
+ } else {
+ break;
+ }
+ }
+ }
+
+ if (saved_output.count > 0) {
+ data = saved_output.data[saved_output.readp];
+ saved_output.count--;
+ saved_output.readp++;
+ /* run out of saved data, switch to file */
+ if (saved_output.count == 0)
+ nfd = 2;
+ } else {
+ if (fds[0].revents & POLLIN) {
+ if (read(master, &data, 1) < 1)
+ err(2, "Bad read on slave pty");
+ } else
+ continue;
+ }
+
+ if (verbose) {
+ fprintf(stderr, "Comparing reference byte 0x%x (%c)"
+ " against slave byte 0x%x (%c)\n",
+ ref, (ref >= ' ') ? ref : '-',
+ data, (data >= ' ' )? data : '-');
+ }
+
+ if (ref != data) {
+ errx(2, "%s, %zu: refresh data from slave does "
+ "not match expected from file %s offs %zu "
+ "[reference 0x%x (%c) != slave 0x%x (%c)]",
+ cur_file, line, check_file, offs,
+ ref, (ref >= ' ') ? ref : '-',
+ data, (data >= ' ') ? data : '-');
+ }
+
+ offs++;
+ }
+
+
+ if (saved_output.count > 0)
+ excess(cur_file, line, __func__, " from slave",
+ &saved_output.data[saved_output.readp], saved_output.count);
+
+ /* discard any excess saved output if required */
+ if (discard) {
+ saved_output.count = 0;
+ saved_output.readp = 0;
+ }
+
+ if ((result = poll(&fds[0], 2, 0)) != 0) {
+ if (result == -1)
+ err(2, "poll of file descriptors failed");
+
+ if ((fds[1].revents & POLLIN) == POLLIN) {
+ save_slave_output(true);
+ } else if ((fds[0].revents & POLLIN) == POLLIN) {
+ /*
+ * handle excess in file if it exists. Poll
+ * says there is data until EOF is read.
+ * Check next read is EOF, if it is not then
+ * the file really has more data than the
+ * slave produced so flag this as a warning.
+ */
+ result = read(check_fd, drain, sizeof(drain));
+ if (result == -1)
+ err(1, "read of data file failed");
+
+ if (result > 0) {
+ excess(check_file, 0, __func__, "", drain,
+ result);
+ }
+ }
+ }
+
+ close(check_fd);
+}
+
+/*
+ * Pass a function call and arguments to the slave and wait for the
+ * results. The variable nresults determines how many returns we expect
+ * back from the slave. These results will be validated against the
+ * expected returns or assigned to variables.
+ */
+static void
+do_function_call(size_t nresults)
+{
+#define MAX_RESULTS 4
+ char *p;
+ int do_input;
+ size_t i;
+ struct pollfd fds[3];
+ returns_t response[MAX_RESULTS], returns_count;
+ assert(nresults <= MAX_RESULTS);
+
+ do_input = check_function_table(command.function, input_functions,
+ ninput_functions);
+
+ write_func_and_args();
+
+ /*
+ * We should get the number of returns back here, grab it before
+ * doing input otherwise it will confuse the input poll
+ */
+ read_cmd_pipe(&returns_count);
+ if (returns_count.return_type != ret_count)
+ err(2, "expected return type of ret_count but received %s",
+ returns_enum_names[returns_count.return_type]);
+
+ perform_delay(&delay_post_call); /* let slave catch up */
+
+ if (verbose) {
+ fprintf(stderr, "Expect %zu results from slave, slave "
+ "reported %zu\n", nresults, returns_count.return_len);
+ }
+
+ if ((no_input == false) && (do_input == 1)) {
+ if (verbose) {
+ fprintf(stderr, "doing input with inputstr >%s<\n",
+ input_str);
+ }
+
+ if (input_str == NULL)
+ errx(2, "%s, %zu: Call to input function "
+ "but no input defined", cur_file, line);
+
+ fds[0].fd = slvpipe[READ_PIPE];
+ fds[0].events = POLLIN;
+ fds[1].fd = master;
+ fds[1].events = POLLOUT;
+ p = input_str;
+ save_slave_output(false);
+ while(*p != '\0') {
+ perform_delay(&delay_spec);
+
+ if (poll(fds, 2, 0) < 0)
+ err(2, "poll failed");
+ if (fds[0].revents & POLLIN) {
+ warnx("%s, %zu: Slave function "
+ "returned before end of input string",
+ cur_file, line);
+ break;
+ }
+ if ((fds[1].revents & POLLOUT) == 0)
+ continue;
+ if (verbose) {
+ fprintf(stderr, "Writing char >%c< to slave\n",
+ *p);
+ }
+ if (write(master, p, 1) != 1) {
+ warn("%s, %zu: Slave function write error",
+ cur_file, line);
+ break;
+ }
+ p++;
+
+ }
+ save_slave_output(false);
+
+ if (verbose) {
+ fprintf(stderr, "Input done.\n");
+ }
+
+ /* done with the input string, free the resources */
+ free(input_str);
+ input_str = NULL;
+ }
+
+ if (verbose) {
+ fds[0].fd = slvpipe[READ_PIPE];
+ fds[0].events = POLLIN;
+
+ fds[1].fd = slvpipe[WRITE_PIPE];
+ fds[1].events = POLLOUT;
+
+ fds[2].fd = master;
+ fds[2].events = POLLIN | POLLOUT;
+
+ i = poll(&fds[0], 3, 1000);
+ fprintf(stderr, "Poll returned %zu\n", i);
+ for (i = 0; i < 3; i++) {
+ fprintf(stderr, "revents for fd[%zu] = 0x%x\n",
+ i, fds[i].revents);
+ }
+ }
+
+ /* drain any trailing output */
+ save_slave_output(false);
+
+ for (i = 0; i < returns_count.return_len; i++) {
+ read_cmd_pipe(&response[i]);
+ }
+
+ /*
+ * Check for a slave error in the first return slot, if the
+ * slave errored then we may not have the number of returns we
+ * expect but in this case we should report the slave error
+ * instead of a return count mismatch.
+ */
+ if ((returns_count.return_len > 0) &&
+ (response[0].return_type == ret_slave_error))
+ err(2, "Slave returned error: %s",
+ (const char *)response[0].return_value);
+
+ if (returns_count.return_len != nresults)
+ err(2, "Incorrect number of returns from slave, expected %zu "
+ "but received %zu", nresults, returns_count.return_len);
+
+ if (verbose) {
+ for (i = 0; i < nresults; i++) {
+ if ((response[i].return_type != ret_byte) &&
+ (response[i].return_type != ret_err) &&
+ (response[i].return_type != ret_ok))
+ fprintf(stderr,
+ "received response >%s< "
+ "expected",
+ (const char *)response[i].return_value);
+ else
+ fprintf(stderr, "received");
+
+ fprintf(stderr, " return_type %s\n",
+ returns_enum_names[command.returns[i].return_type]);
+ }
+ }
+
+ for (i = 0; i < nresults; i++) {
+ if (command.returns[i].return_type != ret_var) {
+ validate(i, &response[i]);
+ } else {
+ vars[command.returns[i].return_index].len =
+ response[i].return_len;
+ vars[command.returns[i].return_index].value =
+ response[i].return_value;
+ vars[command.returns[i].return_index].type =
+ response[i].return_type;
+ }
+ }
+
+ if (verbose && (saved_output.count > 0))
+ excess(cur_file, line, __func__, " from slave",
+ &saved_output.data[saved_output.readp], saved_output.count);
+
+ init_parse_variables(0);
+}
+
+/*
+ * Write the function and command arguments to the command pipe.
+ */
+static void
+write_func_and_args(void)
+{
+ int i;
+
+ if (verbose) {
+ fprintf(stderr, "calling function >%s<\n", command.function);
+ }
+
+ write_cmd_pipe(command.function);
+ for (i = 0; i < command.nargs; i++) {
+ if (command.args[i].arg_type == arg_var)
+ write_cmd_pipe_args(command.args[i].arg_type,
+ &vars[command.args[i].var_index]);
+ else
+ write_cmd_pipe_args(command.args[i].arg_type,
+ &command.args[i]);
+ }
+
+ write_cmd_pipe(NULL); /* signal end of arguments */
+}
+
+/*
+ * Initialise the command structure - if initial is non-zero then just set
+ * everything to sane values otherwise free any memory that was allocated
+ * when building the structure.
+ */
+void
+init_parse_variables(int initial)
+{
+ int i, result;
+ struct pollfd slave_pty;
+
+ if (initial == 0) {
+ free(command.function);
+ for (i = 0; i < command.nrets; i++) {
+ if (command.returns[i].return_type == ret_number)
+ free(command.returns[i].return_value);
+ }
+ free(command.returns);
+
+ for (i = 0; i < command.nargs; i++) {
+ if (command.args[i].arg_type != arg_var)
+ free(command.args[i].arg_string);
+ }
+ free(command.args);
+ } else {
+ line = 0;
+ input_delay = 0;
+ vars = NULL;
+ nvars = 0;
+ input_str = NULL;
+ saved_output.allocated = 0;
+ saved_output.count = 0;
+ saved_output.readp = 0;
+ saved_output.data = NULL;
+ }
+
+ no_input = false;
+ command.function = NULL;
+ command.nargs = 0;
+ command.args = NULL;
+ command.nrets = 0;
+ command.returns = NULL;
+
+ /*
+ * Check the slave pty for stray output from the slave, at this
+ * point we should not see any data as it should have been
+ * consumed by the test functions. If we see data then we have
+ * either a bug or are not handling an output generating function
+ * correctly.
+ */
+ slave_pty.fd = master;
+ slave_pty.events = POLLIN;
+ result = poll(&slave_pty, 1, 0);
+
+ if (result < 0)
+ err(2, "Poll of slave pty failed");
+ else if (result > 0)
+ warnx("%s, %zu: Unexpected data from slave", cur_file, line);
+}
+
+/*
+ * Validate the response against the expected return. The variable
+ * i is the i into the rets array in command.
+ */
+static void
+validate(int i, void *data)
+{
+ char *response;
+ returns_t *byte_response;
+
+ byte_response = data;
+ if ((command.returns[i].return_type != ret_byte) &&
+ (command.returns[i].return_type != ret_err) &&
+ (command.returns[i].return_type != ret_ok)) {
+ if ((byte_response->return_type == ret_byte) ||
+ (byte_response->return_type == ret_err) ||
+ (byte_response->return_type == ret_ok))
+ err(1, "%s: expecting type %s, received type %s"
+ " at line %zu of file %s", __func__,
+ returns_enum_names[command.returns[i].return_type],
+ returns_enum_names[byte_response->return_type],
+ line, cur_file);
+
+ response = byte_response->return_value;
+ }
+
+ switch (command.returns[i].return_type) {
+ case ret_err:
+ validate_type(ret_err, byte_response, 0);
+ break;
+
+ case ret_ok:
+ validate_type(ret_ok, byte_response, 0);
+ break;
+
+ case ret_null:
+ validate_return("NULL", response, 0);
+ break;
+
+ case ret_nonnull:
+ validate_return("NULL", response, 1);
+ break;
+
+ case ret_string:
+ case ret_number:
+ validate_return(command.returns[i].return_value,
+ response, 0);
+ break;
+
+ case ret_ref:
+ validate_reference(i, response);
+ break;
+
+ case ret_byte:
+ validate_byte(&command.returns[i], byte_response, 0);
+ break;
+
+ default:
+ err(1, "Malformed statement at line %zu of file %s",
+ line, cur_file);
+ break;
+ }
+}
+
+/*
+ * Validate the return against the contents of a variable.
+ */
+static void
+validate_reference(int i, void *data)
+{
+ char *response;
+ returns_t *byte_response;
+ var_t *varp;
+
+ varp = &vars[command.returns[i].return_index];
+
+ byte_response = data;
+ if (command.returns[i].return_type != ret_byte)
+ response = data;
+
+ if (verbose) {
+ fprintf(stderr,
+ "%s: return type of %s, value %s \n", __func__,
+ returns_enum_names[varp->type],
+ (const char *)varp->value);
+ }
+
+ switch (varp->type) {
+ case ret_string:
+ case ret_number:
+ validate_return(varp->value, response, 0);
+ break;
+
+ case ret_byte:
+ validate_byte(varp->value, byte_response, 0);
+ break;
+
+ default:
+ err(1,
+ "Invalid return type for reference at line %zu of file %s",
+ line, cur_file);
+ break;
+ }
+}
+
+/*
+ * Validate the return type against the expected type, throw an error
+ * if they don't match.
+ */
+static void
+validate_type(returns_enum_t expected, returns_t *value, int check)
+{
+ if (((check == 0) && (expected != value->return_type)) ||
+ ((check == 1) && (expected == value->return_type)))
+ err(1, "Validate expected type %s %s %s line %zu of file %s",
+ returns_enum_names[expected],
+ (check == 0)? "matching" : "not matching",
+ returns_enum_names[value->return_type], line, cur_file);
+
+ if (verbose) {
+ fprintf(stderr, "Validate expected type %s %s %s line %zu"
+ " of file %s\n",
+ returns_enum_names[expected],
+ (check == 0)? "matching" : "not matching",
+ returns_enum_names[value->return_type], line, cur_file);
+ }
+}
+
+/*
+ * Validate the return value against the expected value, throw an error
+ * if they don't match.
+ */
+static void
+validate_return(const char *expected, const char *value, int check)
+{
+ if (((check == 0) && strcmp(expected, value) != 0) ||
+ ((check == 1) && strcmp(expected, value) == 0))
+ errx(1, "Validate expected %s %s %s line %zu of file %s",
+ expected,
+ (check == 0)? "matching" : "not matching", value,
+ line, cur_file);
+ if (verbose) {
+ fprintf(stderr, "Validated expected value %s %s %s "
+ "at line %zu of file %s\n", expected,
+ (check == 0)? "matches" : "does not match",
+ value, line, cur_file);
+ }
+}
+
+/*
+ * Validate the return value against the expected value, throw an error
+ * if they don't match expectations.
+ */
+static void
+validate_byte(returns_t *expected, returns_t *value, int check)
+{
+ char *ch;
+ size_t i;
+
+ if (verbose) {
+ ch = value->return_value;
+ fprintf(stderr, "checking returned byte stream: ");
+ for (i = 0; i < value->return_len; i++)
+ fprintf(stderr, "%s0x%x", (i != 0)? ", " : "", ch[i]);
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, "%s byte stream: ",
+ (check == 0)? "matches" : "does not match");
+ ch = (char *) expected->return_value;
+ for (i = 0; i < expected->return_len; i++)
+ fprintf(stderr, "%s0x%x", (i != 0)? ", " : "", ch[i]);
+ fprintf(stderr, "\n");
+ }
+
+ /*
+ * No chance of a match if lengths differ...
+ */
+ if ((check == 0) && (expected->return_len != value->return_len))
+ errx(1, "Byte validation failed, length mismatch, expected %zu,"
+ "received %zu", expected->return_len, value->return_len);
+
+ /*
+ * If check is 0 then we want to throw an error IFF the byte streams
+ * do not match, if check is 1 then throw an error if the byte
+ * streams match.
+ */
+ if (((check == 0) && memcmp(expected->return_value, value->return_value,
+ value->return_len) != 0) ||
+ ((check == 1) && (expected->return_len == value->return_len) &&
+ memcmp(expected->return_value, value->return_value,
+ value->return_len) == 0))
+ errx(1, "Validate expected %s byte stream at line %zu"
+ "of file %s",
+ (check == 0)? "matching" : "not matching", line, cur_file);
+ if (verbose) {
+ fprintf(stderr, "Validated expected %s byte stream "
+ "at line %zu of file %s\n",
+ (check == 0)? "matching" : "not matching",
+ line, cur_file);
+ }
+}
+
+/*
+ * Validate the variable at i against the expected value, throw an
+ * error if they don't match, if check is non-zero then the match is
+ * negated.
+ */
+static void
+validate_variable(int ret, returns_enum_t type, const void *value, int i,
+ int check)
+{
+ returns_t *retval;
+ var_t *varptr;
+
+ retval = &command.returns[ret];
+ varptr = &vars[command.returns[ret].return_index];
+
+ if (varptr->value == NULL)
+ err(1, "Variable %s has no value assigned to it", varptr->name);
+
+
+ if (varptr->type != type)
+ err(1, "Variable %s is not the expected type", varptr->name);
+
+ if (type != ret_byte) {
+ if ((((check == 0) && strcmp(value, varptr->value) != 0))
+ || ((check == 1) && strcmp(value, varptr->value) == 0))
+ err(1, "Variable %s contains %s instead of %s"
+ " value %s at line %zu of file %s",
+ varptr->name, (const char *)varptr->value,
+ (check == 0)? "expected" : "not matching",
+ (const char *)value,
+ line, cur_file);
+ if (verbose) {
+ fprintf(stderr, "Variable %s contains %s value "
+ "%s at line %zu of file %s\n",
+ varptr->name,
+ (check == 0)? "expected" : "not matching",
+ (const char *)varptr->value, line, cur_file);
+ }
+ } else {
+ if ((check == 0) && (retval->return_len != varptr->len))
+ err(1, "Byte validation failed, length mismatch");
+
+ /*
+ * If check is 0 then we want to throw an error IFF
+ * the byte streams do not match, if check is 1 then
+ * throw an error if the byte streams match.
+ */
+ if (((check == 0) && memcmp(retval->return_value, varptr->value,
+ varptr->len) != 0) ||
+ ((check == 1) && (retval->return_len == varptr->len) &&
+ memcmp(retval->return_value, varptr->value,
+ varptr->len) == 0))
+ err(1, "Validate expected %s byte stream at line %zu"
+ " of file %s",
+ (check == 0)? "matching" : "not matching",
+ line, cur_file);
+ if (verbose) {
+ fprintf(stderr, "Validated expected %s byte stream "
+ "at line %zu of file %s\n",
+ (check == 0)? "matching" : "not matching",
+ line, cur_file);
+ }
+ }
+}
+
+/*
+ * Write a string to the command pipe - we feed the number of bytes coming
+ * down first to allow storage allocation and then follow up with the data.
+ * If cmd is NULL then feed a -1 down the pipe to say the end of the args.
+ */
+static void
+write_cmd_pipe(char *cmd)
+{
+ args_t arg;
+ size_t len;
+
+ if (cmd == NULL)
+ len = 0;
+ else
+ len = strlen(cmd);
+
+ arg.arg_type = arg_static;
+ arg.arg_len = len;
+ arg.arg_string = cmd;
+ write_cmd_pipe_args(arg.arg_type, &arg);
+
+}
+
+static void
+write_cmd_pipe_args(args_state_t type, void *data)
+{
+ var_t *var_data;
+ args_t *arg_data;
+ int len, send_type;
+ void *cmd;
+
+ arg_data = data;
+ switch (type) {
+ case arg_var:
+ var_data = data;
+ len = var_data->len;
+ cmd = var_data->value;
+ if (type == arg_byte)
+ send_type = ret_byte;
+ else
+ send_type = ret_string;
+ break;
+
+ case arg_null:
+ send_type = ret_null;
+ len = 0;
+ break;
+
+ default:
+ if ((arg_data->arg_len == 0) && (arg_data->arg_string == NULL))
+ len = -1;
+ else
+ len = arg_data->arg_len;
+ cmd = arg_data->arg_string;
+ if (type == arg_byte)
+ send_type = ret_byte;
+ else
+ send_type = ret_string;
+ }
+
+ if (verbose) {
+ fprintf(stderr, "Writing type %s to command pipe\n",
+ returns_enum_names[send_type]);
+ }
+
+ if (write(cmdpipe[WRITE_PIPE], &send_type, sizeof(int)) < 0)
+ err(1, "command pipe write for type failed");
+
+ if (verbose) {
+ fprintf(stderr, "Writing length %d to command pipe\n", len);
+ }
+
+ if (write(cmdpipe[WRITE_PIPE], &len, sizeof(int)) < 0)
+ err(1, "command pipe write for length failed");
+
+ if (len > 0) {
+ if (verbose) {
+ fprintf(stderr, "Writing data >%s< to command pipe\n",
+ (const char *)cmd);
+ }
+ if (write(cmdpipe[WRITE_PIPE], cmd, len) < 0)
+ err(1, "command pipe write of data failed");
+ }
+}
+
+/*
+ * Read a response from the command pipe, first we will receive the
+ * length of the response then the actual data.
+ */
+static void
+read_cmd_pipe(returns_t *response)
+{
+ int len, type;
+ struct pollfd rfd[2];
+ char *str;
+
+ /*
+ * Check if there is data to read - just in case slave has died, we
+ * don't want to block on the read and just hang. We also check
+ * output from the slave because the slave may be blocked waiting
+ * for a flush on its stdout.
+ */
+ rfd[0].fd = slvpipe[READ_PIPE];
+ rfd[0].events = POLLIN;
+ rfd[1].fd = master;
+ rfd[1].events = POLLIN;
+
+ do {
+ if (poll(rfd, 2, 4000) == 0)
+ errx(2, "%s, %zu: Command pipe read timeout",
+ cur_file, line);
+
+ if ((rfd[1].revents & POLLIN) == POLLIN) {
+ if (verbose) {
+ fprintf(stderr,
+ "draining output from slave\n");
+ }
+ save_slave_output(false);
+ }
+ }
+ while((rfd[1].revents & POLLIN) == POLLIN);
+
+ if (read(slvpipe[READ_PIPE], &type, sizeof(int)) < 0)
+ err(1, "command pipe read for type failed");
+ response->return_type = type;
+
+ if ((type != ret_ok) && (type != ret_err) && (type != ret_count)) {
+ if (read(slvpipe[READ_PIPE], &len, sizeof(int)) < 0)
+ err(1, "command pipe read for length failed");
+ response->return_len = len;
+
+ if (verbose) {
+ fprintf(stderr,
+ "Reading %d bytes from command pipe\n", len);
+ }
+
+ if ((response->return_value = malloc(len + 1)) == NULL)
+ err(1, "Failed to alloc memory for cmd pipe read");
+
+ if (read(slvpipe[READ_PIPE], response->return_value, len) < 0)
+ err(1, "command pipe read of data failed");
+
+ if (response->return_type != ret_byte) {
+ str = response->return_value;
+ str[len] = '\0';
+
+ if (verbose) {
+ fprintf(stderr, "Read data >%s< from pipe\n",
+ (const char *)response->return_value);
+ }
+ }
+ } else {
+ response->return_value = NULL;
+ if (type == ret_count) {
+ if (read(slvpipe[READ_PIPE], &len, sizeof(int)) < 0)
+ err(1, "command pipe read for number of "
+ "returns failed");
+ response->return_len = len;
+ }
+
+ if (verbose) {
+ fprintf(stderr, "Read type %s from pipe\n",
+ returns_enum_names[type]);
+ }
+ }
+}
+
+/*
+ * Check for writes from the slave on the pty, save the output into a
+ * buffer for later checking if discard is false.
+ */
+#define MAX_DRAIN 256
+
+static void
+save_slave_output(bool discard)
+{
+ char *new_data, drain[MAX_DRAIN];
+ size_t to_allocate;
+ ssize_t result;
+ size_t i;
+
+ result = 0;
+ for (;;) {
+ if (result == -1)
+ err(2, "poll of slave pty failed");
+ result = MAX_DRAIN;
+ if ((result = read(master, drain, result)) < 0) {
+ if (errno == EAGAIN)
+ break;
+ else
+ err(2, "draining slave pty failed");
+ }
+ if (result == 0)
+ abort();
+
+ if (!discard) {
+ if ((size_t)result >
+ (saved_output.allocated - saved_output.count)) {
+ to_allocate = 1024 * ((result / 1024) + 1);
+
+ if ((new_data = realloc(saved_output.data,
+ saved_output.allocated + to_allocate))
+ == NULL)
+ err(2, "Realloc of saved_output failed");
+ saved_output.data = new_data;
+ saved_output.allocated += to_allocate;
+ }
+
+ if (verbose) {
+ fprintf(stderr, "count = %zu, "
+ "allocated = %zu\n", saved_output.count,
+ saved_output.allocated);
+ for (i = 0; i < (size_t)result; i++) {
+ fprintf(stderr, "Saving slave output "
+ "at %zu: 0x%x (%c)\n",
+ saved_output.count + i, drain[i],
+ (drain[i] >= ' ')? drain[i] : '-');
+ }
+ }
+
+ memcpy(&saved_output.data[saved_output.count], drain,
+ result);
+ saved_output.count += result;
+
+ if (verbose) {
+ fprintf(stderr, "count = %zu, "
+ "allocated = %zu\n", saved_output.count,
+ saved_output.allocated);
+ }
+ } else {
+ if (verbose) {
+ for (i = 0; i < (size_t)result; i++) {
+ fprintf(stderr, "Discarding slave "
+ "output 0x%x (%c)\n",
+ drain[i],
+ (drain[i] >= ' ')? drain[i] : '-');
+ }
+ }
+ }
+ }
+}
+
+static void
+yyerror(const char *msg)
+{
+ warnx("%s in line %zu of file %s", msg, line, cur_file);
+}
diff --git a/contrib/netbsd-tests/lib/libcurses/slave/command_table.h b/contrib/netbsd-tests/lib/libcurses/slave/command_table.h
new file mode 100644
index 0000000..ef57a00
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/slave/command_table.h
@@ -0,0 +1,397 @@
+/* $NetBSD: command_table.h,v 1.3 2011/09/15 11:46:19 blymn Exp $ */
+
+/*-
+ * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
+ *
+ * All rights reserved.
+ *
+ * This code has been donated to The NetBSD Foundation by the Author.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ *
+ */
+
+#ifndef _COMMAND_TABLE_H_
+#define _COMMAND_TABLE_H_
+
+#include "curses_commands.h"
+
+/*
+ * Curses commands
+ */
+struct command_def commands[] = {
+ {"DRAIN", cmd_DRAIN},
+ {"addbytes", cmd_addbytes},
+ {"addch", cmd_addch},
+ {"addchnstr", cmd_addchnstr},
+ {"addchstr", cmd_addchstr},
+ {"addnstr", cmd_addnstr},
+ {"addstr", cmd_addstr},
+ {"attr_get", cmd_attr_get},
+ {"attr_off", cmd_attr_off},
+ {"attr_on", cmd_attr_on},
+ {"attr_set", cmd_attr_set},
+ {"attroff", cmd_attroff},
+ {"attron", cmd_attron},
+ {"attrset", cmd_attrset},
+ {"bkgd", cmd_bkgd},
+ {"bkgdset", cmd_bkgdset},
+ {"border", cmd_border},
+ {"clear", cmd_clear},
+ {"clrtobot", cmd_clrtobot},
+ {"clrtoeol", cmd_clrtoeol},
+ {"color_set", cmd_color_set},
+ {"delch", cmd_delch},
+ {"deleteln", cmd_deleteln},
+ {"echochar", cmd_echochar},
+ {"erase", cmd_erase},
+ {"getch", cmd_getch},
+ {"getnstr", cmd_getnstr},
+ {"getstr", cmd_getstr},
+ {"inch", cmd_inch},
+ {"inchnstr", cmd_inchnstr},
+ {"inchstr", cmd_inchstr},
+ {"innstr", cmd_innstr},
+ {"insch", cmd_insch},
+ {"insdelln", cmd_insdelln},
+ {"insertln", cmd_insertln},
+ {"instr", cmd_instr},
+ {"move", cmd_move},
+ {"refresh", cmd_refresh},
+ {"scrl", cmd_scrl},
+ {"setscrreg", cmd_setscrreg},
+ {"standend", cmd_standend},
+ {"standout", cmd_standout},
+ {"timeout", cmd_timeout},
+ {"underscore", cmd_underscore},
+ {"underend", cmd_underend},
+ {"waddbytes", cmd_waddbytes},
+ {"waddstr", cmd_waddstr},
+ {"mvaddbytes", cmd_mvaddbytes},
+ {"mvaddch", cmd_mvaddch},
+ {"mvaddchnstr", cmd_mvaddchnstr},
+ {"mvaddchstr", cmd_mvaddchstr},
+ {"mvaddnstr", cmd_mvaddnstr},
+ {"mvaddstr", cmd_mvaddstr},
+ {"mvdelch", cmd_mvdelch},
+ {"mvgetch", cmd_mvgetch},
+ {"mvgetnstr", cmd_mvgetnstr},
+ {"mvgetstr", cmd_mvgetstr},
+ {"mvinch", cmd_mvinch},
+ {"mvinchnstr", cmd_mvinchnstr},
+ {"mvinchstr", cmd_mvinchstr},
+ {"mvinnstr", cmd_mvinnstr},
+ {"mvinsch", cmd_mvinsch},
+ {"mvinstr", cmd_mvinstr},
+ {"mvwaddbytes", cmd_mvwaddbytes},
+ {"mvwaddch", cmd_mvwaddch},
+ {"mvwaddchnstr", cmd_mvwaddchnstr},
+ {"mvwaddchstr", cmd_mvwaddchstr},
+ {"mvwaddnstr", cmd_mvwaddnstr},
+ {"mvwaddstr", cmd_mvwaddstr},
+ {"mvwdelch", cmd_mvwdelch},
+ {"mvwgetch", cmd_mvwgetch},
+ {"mvwgetnstr", cmd_mvwgetnstr},
+ {"mvwgetstr", cmd_mvwgetstr},
+ {"mvwinch", cmd_mvwinch},
+ {"mvwinsch", cmd_mvwinsch},
+ {"assume_default_colors", cmd_assume_default_colors},
+ {"baudrate", cmd_baudrate},
+ {"beep", cmd_beep},
+ {"box", cmd_box},
+ {"can_change_color", cmd_can_change_color},
+ {"cbreak", cmd_cbreak},
+ {"clearok", cmd_clearok},
+ {"color_content", cmd_color_content},
+ {"copywin", cmd_copywin},
+ {"curs_set", cmd_curs_set},
+ {"def_prog_mode", cmd_def_prog_mode},
+ {"def_shell_mode", cmd_def_shell_mode},
+ {"define_key", cmd_define_key},
+ {"delay_output", cmd_delay_output},
+ {"delscreen", cmd_delscreen},
+ {"delwin", cmd_delwin},
+ {"derwin", cmd_derwin},
+ {"dupwin", cmd_dupwin},
+ {"doupdate", cmd_doupdate},
+ {"echo", cmd_echo},
+ {"endwin", cmd_endwin},
+ {"erasechar", cmd_erasechar},
+ {"flash", cmd_flash},
+ {"flushinp", cmd_flushinp},
+ {"flushok", cmd_flushok},
+ {"fullname", cmd_fullname},
+ {"getattrs", cmd_getattrs},
+ {"getbkgd", cmd_getbkgd},
+ {"getcury", cmd_getcury},
+ {"getcurx", cmd_getcurx},
+ {"getyx", cmd_getyx},
+ {"getbegy", cmd_getbegy},
+ {"getbegx", cmd_getbegx},
+ {"getmaxy", cmd_getmaxy},
+ {"getmaxx", cmd_getmaxx},
+ {"getpary", cmd_getpary},
+ {"getparx", cmd_getparx},
+ {"getparyx", cmd_getparyx},
+ {"gettmode", cmd_gettmode},
+ {"getwin", cmd_getwin},
+ {"halfdelay", cmd_halfdelay},
+ {"has_colors", cmd_has_colors},
+ {"has_ic", cmd_has_ic},
+ {"has_il", cmd_has_il},
+ {"hline", cmd_hline},
+ {"idcok", cmd_idcok},
+ {"idlok", cmd_idlok},
+ {"init_color", cmd_init_color},
+ {"init_pair", cmd_init_pair},
+ {"initscr", cmd_initscr},
+ {"intrflush", cmd_intrflush},
+ {"isendwin", cmd_isendwin},
+ {"is_linetouched", cmd_is_linetouched},
+ {"is_wintouched", cmd_is_wintouched},
+ {"keyok", cmd_keyok},
+ {"keypad", cmd_keypad},
+ {"keyname", cmd_keyname},
+ {"killchar", cmd_killchar},
+ {"leaveok", cmd_leaveok},
+ {"meta", cmd_meta},
+ {"mvcur", cmd_mvcur},
+ {"mvderwin", cmd_mvderwin},
+ {"mvhline", cmd_mvhline},
+ {"mvprintw", cmd_mvprintw},
+ {"mvscanw", cmd_mvscanw},
+ {"mvvline", cmd_mvvline},
+ {"mvwhline", cmd_mvwhline},
+ {"mvwvline", cmd_mvwvline},
+ {"mvwin", cmd_mvwin},
+ {"mvwinchnstr", cmd_mvwinchnstr},
+ {"mvwinchstr", cmd_mvwinchstr},
+ {"mvwinnstr", cmd_mvwinnstr},
+ {"mvwinstr", cmd_mvwinstr},
+ {"mvwprintw", cmd_mvwprintw},
+ {"mvwscanw", cmd_mvwscanw},
+ {"napms", cmd_napms},
+ {"newpad", cmd_newpad},
+ {"newterm", cmd_newterm},
+ {"newwin", cmd_newwin},
+ {"nl", cmd_nl},
+ {"no_color_attributes", cmd_no_color_attributes},
+ {"nocbreak", cmd_nocbreak},
+ {"nodelay", cmd_nodelay},
+ {"noecho", cmd_noecho},
+ {"nonl", cmd_nonl},
+ {"noqiflush", cmd_noqiflush},
+ {"noraw", cmd_noraw},
+ {"notimeout", cmd_notimeout},
+ {"overlay", cmd_overlay},
+ {"overwrite", cmd_overwrite},
+ {"pair_content", cmd_pair_content},
+ {"pechochar", cmd_pechochar},
+ {"pnoutrefresh", cmd_pnoutrefresh},
+ {"prefresh", cmd_prefresh},
+ {"printw", cmd_printw},
+ {"putwin", cmd_putwin},
+ {"qiflush", cmd_qiflush},
+ {"raw", cmd_raw},
+ {"redrawwin", cmd_redrawwin},
+ {"reset_prog_mode", cmd_reset_prog_mode},
+ {"reset_shell_mode", cmd_reset_shell_mode},
+ {"resetty", cmd_resetty},
+ {"resizeterm", cmd_resizeterm},
+ {"savetty", cmd_savetty},
+ {"scanw", cmd_scanw},
+ {"scroll", cmd_scroll},
+ {"scrollok", cmd_scrollok},
+ {"setterm", cmd_setterm},
+ {"set_term", cmd_set_term},
+ {"start_color", cmd_start_color},
+ {"subpad", cmd_subpad},
+ {"subwin", cmd_subwin},
+ {"termattrs", cmd_termattrs},
+ {"term_attrs", cmd_term_attrs},
+ {"touchline", cmd_touchline},
+ {"touchoverlap", cmd_touchoverlap},
+ {"touchwin", cmd_touchwin},
+ {"ungetch", cmd_ungetch},
+ {"untouchwin", cmd_untouchwin},
+ {"use_default_colors", cmd_use_default_colors},
+ {"vline", cmd_vline},
+ {"vw_printw", cmd_vw_printw},
+ {"vw_scanw", cmd_vw_scanw},
+ {"vwprintw", cmd_vwprintw},
+ {"vwscanw", cmd_vwscanw},
+ {"waddch", cmd_waddch},
+ {"waddchnstr", cmd_waddchnstr},
+ {"waddchstr", cmd_waddchstr},
+ {"waddnstr", cmd_waddnstr},
+ {"wattr_get", cmd_wattr_get},
+ {"wattr_off", cmd_wattr_off},
+ {"wattr_on", cmd_wattr_on},
+ {"wattr_set", cmd_wattr_set},
+ {"wattroff", cmd_wattroff},
+ {"wattron", cmd_wattron},
+ {"wattrset", cmd_wattrset},
+ {"wbkgd", cmd_wbkgd},
+ {"wbkgdset", cmd_wbkgdset},
+ {"wborder", cmd_wborder},
+ {"wclear", cmd_wclear},
+ {"wclrtobot", cmd_wclrtobot},
+ {"wclrtoeol", cmd_wclrtoeol},
+ {"wcolor_set", cmd_wcolor_set},
+ {"wdelch", cmd_wdelch},
+ {"wdeleteln", cmd_wdeleteln},
+ {"wechochar", cmd_wechochar},
+ {"werase", cmd_werase},
+ {"wgetch", cmd_wgetch},
+ {"wgetnstr", cmd_wgetnstr},
+ {"wgetstr", cmd_wgetstr},
+ {"whline", cmd_whline},
+ {"winch", cmd_winch},
+ {"winchnstr", cmd_winchnstr},
+ {"winchstr", cmd_winchstr},
+ {"winnstr", cmd_winnstr},
+ {"winsch", cmd_winsch},
+ {"winsdelln", cmd_winsdelln},
+ {"winsertln", cmd_winsertln},
+ {"winstr", cmd_winstr},
+ {"wmove", cmd_wmove},
+ {"wnoutrefresh", cmd_wnoutrefresh},
+ {"wprintw", cmd_wprintw},
+ {"wredrawln", cmd_wredrawln},
+ {"wrefresh", cmd_wrefresh},
+ {"wresize", cmd_wresize},
+ {"wscanw", cmd_wscanw},
+ {"wscrl", cmd_wscrl},
+ {"wsetscrreg", cmd_wsetscrreg},
+ {"wstandend", cmd_wstandend},
+ {"wstandout", cmd_wstandout},
+ {"wtimeout", cmd_wtimeout},
+ {"wtouchln", cmd_wtouchln},
+ {"wunderend", cmd_wunderend},
+ {"wunderscore", cmd_wunderscore},
+ {"wvline", cmd_wvline},
+ {"insnstr", cmd_insnstr},
+ {"insstr", cmd_insstr},
+ {"mvinsnstr", cmd_mvinsnstr},
+ {"mvinsstr", cmd_mvinsstr},
+ {"mvwinsnstr", cmd_mvwinsnstr},
+ {"mvwinsstr", cmd_mvwinsstr},
+ {"winsnstr", cmd_winsnstr},
+ {"winsstr", cmd_winsstr},
+ {"chgat", cmd_chgat},
+ {"wchgat", cmd_wchgat},
+ {"mvchgat", cmd_mvchgat},
+ {"mvwchgat", cmd_mvwchgat},
+ {"add_wch", cmd_add_wch},
+ {"wadd_wch", cmd_wadd_wch},
+ {"mvadd_wch", cmd_mvadd_wch},
+ {"mvwadd_wch", cmd_mvwadd_wch},
+ {"add_wchnstr", cmd_add_wchnstr},
+ {"add_wchstr", cmd_add_wchstr},
+ {"wadd_wchnstr", cmd_wadd_wchnstr},
+ {"wadd_wchstr", cmd_wadd_wchstr},
+ {"mvadd_wchnstr", cmd_mvadd_wchnstr},
+ {"mvadd_wchstr", cmd_mvadd_wchstr},
+ {"mvwadd_wchnstr", cmd_mvwadd_wchnstr},
+ {"mvwadd_wchstr", cmd_mvwadd_wchstr},
+ {"addnwstr", cmd_addnwstr},
+ {"addwstr", cmd_addwstr},
+ {"mvaddnwstr", cmd_mvaddnwstr},
+ {"mvaddwstr", cmd_mvaddwstr},
+ {"mvwaddnwstr", cmd_mvwaddnwstr},
+ {"mvwaddwstr", cmd_mvwaddwstr},
+ {"waddnwstr", cmd_waddnwstr},
+ {"waddwstr", cmd_waddwstr},
+ {"echo_wchar", cmd_echo_wchar},
+ {"wecho_wchar", cmd_wecho_wchar},
+ {"pecho_wchar", cmd_pecho_wchar},
+ {"ins_wch", cmd_ins_wch},
+ {"wins_wch", cmd_wins_wch},
+ {"mvins_wch", cmd_mvins_wch},
+ {"mvwins_wch", cmd_mvwins_wch},
+ {"ins_nwstr", cmd_ins_nwstr},
+ {"ins_wstr", cmd_ins_wstr},
+ {"mvins_nwstr", cmd_mvins_nwstr},
+ {"mvins_wstr", cmd_mvins_wstr},
+ {"mvwins_nwstr", cmd_mvwins_nwstr},
+ {"mvwins_wstr", cmd_mvwins_wstr},
+ {"wins_nwstr", cmd_wins_nwstr},
+ {"wins_wstr", cmd_wins_wstr},
+ {"get_wch", cmd_get_wch},
+ {"unget_wch", cmd_unget_wch},
+ {"mvget_wch", cmd_mvget_wch},
+ {"mvwget_wch", cmd_mvwget_wch},
+ {"wget_wch", cmd_wget_wch},
+ {"getn_wstr", cmd_getn_wstr},
+ {"get_wstr", cmd_get_wstr},
+ {"mvgetn_wstr", cmd_mvgetn_wstr},
+ {"mvget_wstr", cmd_mvget_wstr},
+ {"mvwgetn_wstr", cmd_mvwgetn_wstr},
+ {"mvwget_wstr", cmd_mvwget_wstr},
+ {"wgetn_wstr", cmd_wgetn_wstr},
+ {"wget_wstr", cmd_wget_wstr},
+ {"in_wch", cmd_in_wch},
+ {"mvin_wch", cmd_mvin_wch},
+ {"mvwin_wch", cmd_mvwin_wch},
+ {"win_wch", cmd_win_wch},
+ {"in_wchnstr", cmd_in_wchnstr},
+ {"in_wchstr", cmd_in_wchstr},
+ {"mvin_wchnstr", cmd_mvin_wchnstr},
+ {"mvin_wchstr", cmd_mvin_wchstr},
+ {"mvwin_wchnstr", cmd_mvwin_wchnstr},
+ {"mvwin_wchstr", cmd_mvwin_wchstr},
+ {"win_wchnstr", cmd_win_wchnstr},
+ {"win_wchstr", cmd_win_wchstr},
+ {"innwstr", cmd_innwstr},
+ {"inwstr", cmd_inwstr},
+ {"mvinnwstr", cmd_mvinnwstr},
+ {"mvinwstr", cmd_mvinwstr},
+ {"mvwinnwstr", cmd_mvwinnwstr},
+ {"mvwinwstr", cmd_mvwinwstr},
+ {"winnwstr", cmd_winnwstr},
+ {"winwstr", cmd_winwstr},
+ {"setcchar", cmd_setcchar},
+ {"getcchar", cmd_getcchar},
+ {"key_name", cmd_key_name},
+ {"border_set", cmd_border_set},
+ {"wborder_set", cmd_wborder_set},
+ {"box_set", cmd_box_set},
+ {"erasewchar", cmd_erasewchar},
+ {"killwchar", cmd_killwchar},
+ {"hline_set", cmd_hline_set},
+ {"mvhline_set", cmd_mvhline_set},
+ {"mvvline_set", cmd_mvvline_set},
+ {"mvwhline_set", cmd_mvwhline_set},
+ {"mvwvline_set", cmd_mvwvline_set},
+ {"vline_set", cmd_vline_set},
+ {"whline_set", cmd_whline_set},
+ {"wvline_set", cmd_wvline_set},
+ {"bkgrnd", cmd_bkgrnd},
+ {"bkgrndset", cmd_bkgrndset},
+ {"getbkgrnd", cmd_getbkgrnd},
+ {"wbkgrnd", cmd_wbkgrnd},
+ {"wbkgrndset", cmd_wbkgrndset},
+ {"wgetbkgrnd", cmd_wgetbkgrnd},
+};
+
+size_t ncmds = sizeof(commands) / sizeof(struct command_def);
+
+#endif /* _COMMAND_TABLE_H */
diff --git a/contrib/netbsd-tests/lib/libcurses/slave/commands.c b/contrib/netbsd-tests/lib/libcurses/slave/commands.c
new file mode 100644
index 0000000..2f26024
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/slave/commands.c
@@ -0,0 +1,243 @@
+/* $NetBSD: commands.c,v 1.4 2011/09/15 11:46:19 blymn Exp $ */
+
+/*-
+ * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
+ *
+ * All rights reserved.
+ *
+ * This code has been donated to The NetBSD Foundation by the Author.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <curses.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <err.h>
+#include <sys/types.h>
+#include "returns.h"
+#include "slave.h"
+#include "command_table.h"
+
+extern int cmdpipe[2];
+extern int slvpipe[2];
+
+static void report_type(returns_enum_t);
+static void report_message(int, const char *);
+
+/*
+ * Match the passed command string and execute the associated test
+ * function.
+ */
+void
+command_execute(char *func, int nargs, char **args)
+{
+ size_t i;
+
+ i = 0;
+ while (i < ncmds) {
+ if (strcasecmp(func, commands[i].name) == 0) {
+ /* matched function */
+ commands[i].func(nargs, args);
+ return;
+ }
+ i++;
+ }
+
+ report_status("UNKNOWN_FUNCTION");
+}
+
+/*
+ * Report an pointer value back to the director
+ */
+void
+report_ptr(void *ptr)
+{
+ char *string;
+
+ if (ptr == NULL)
+ asprintf(&string, "NULL");
+ else
+ asprintf(&string, "%p", ptr);
+ report_status(string);
+ free(string);
+}
+
+/*
+ * Report an integer value back to the director
+ */
+void
+report_int(int value)
+{
+ char *string;
+
+ asprintf(&string, "%d", value);
+ report_status(string);
+ free(string);
+}
+
+/*
+ * Report either an ERR or OK back to the director
+ */
+void
+report_return(int status)
+{
+ if (status == ERR)
+ report_type(ret_err);
+ else if (status == OK)
+ report_type(ret_ok);
+ else
+ report_status("INVALID_RETURN");
+}
+
+/*
+ * Report the type back to the director via the command pipe
+ */
+static void
+report_type(returns_enum_t return_type)
+{
+ int type;
+
+ type = return_type;
+ if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0)
+ err(1, "command pipe write for status type failed");
+
+}
+
+/*
+ * Report the number of returns back to the director via the command pipe
+ */
+void
+report_count(int count)
+{
+ int type;
+
+ type = ret_count;
+ if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0)
+ err(1, "command pipe write for count type failed");
+
+ if (write(slvpipe[WRITE_PIPE], &count, sizeof(int)) < 0)
+ err(1, "command pipe write for count");
+}
+
+/*
+ * Report the status back to the director via the command pipe
+ */
+void
+report_status(const char *status)
+{
+ report_message(ret_string, status);
+}
+
+/*
+ * Report an error message back to the director via the command pipe.
+ */
+void
+report_error(const char *status)
+{
+ report_message(ret_slave_error, status);
+}
+
+/*
+ * Report the message with the given type back to the director via the
+ * command pipe.
+ */
+static void
+report_message(int type, const char *status)
+{
+ int len;
+
+ len = strlen(status);
+
+ if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0)
+ err(1, "command pipe write for message type failed");
+
+ if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0)
+ err(1, "command pipe write for message length failed");
+
+ if (write(slvpipe[WRITE_PIPE], status, len) < 0)
+ err(1, "command pipe write of message data failed");
+}
+
+/*
+ * Report a string of chtype back to the director via the command pipe.
+ */
+void
+report_byte(chtype c)
+{
+ chtype string[2];
+
+ string[0] = c;
+ string[1] = A_NORMAL | '\0';
+ report_nstr(string);
+}
+
+/*
+ * Report a string of chtype back to the director via the command pipe.
+ */
+void
+report_nstr(chtype *string)
+{
+ int len, type;
+ chtype *p;
+
+ len = 0;
+ p = string;
+
+ while ((*p++ & __CHARTEXT) != 0) {
+ len++;
+ }
+
+ len++; /* add in the termination chtype */
+ len *= sizeof(chtype);
+
+ type = ret_byte;
+ if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0)
+ err(1, "%s: command pipe write for status type failed",
+ __func__);
+
+ if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0)
+ err(1, "%s: command pipe write for status length failed",
+ __func__);
+
+ if (write(slvpipe[WRITE_PIPE], string, len) < 0)
+ err(1, "%s: command pipe write of status data failed",
+ __func__);
+}
+
+/*
+ * Check the number of args we received are what we expect. Return an
+ * error if they do not match.
+ */
+int
+check_arg_count(int nargs, int expected)
+{
+ if (nargs != expected) {
+ report_count(1);
+ report_error("INCORRECT_ARGUMENT_NUMBER");
+ return(1);
+ }
+
+ return(0);
+}
diff --git a/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.c b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.c
new file mode 100644
index 0000000..9a6679a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.c
@@ -0,0 +1,7165 @@
+/* $NetBSD: curses_commands.c,v 1.7 2012/09/19 11:51:08 blymn Exp $ */
+
+/*-
+ * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
+ *
+ * All rights reserved.
+ *
+ * This code has been donated to The NetBSD Foundation by the Author.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <curses.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <stdarg.h>
+
+#include "slave.h"
+#include "curses_commands.h"
+
+void
+cmd_DRAIN(int nargs, char **args)
+{
+ while (getch() != ERR);
+ report_count(1);
+ report_return(OK);
+}
+
+void
+cmd_addbytes(int nargs, char **args)
+{
+ int count;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[1], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(addbytes(args[0], count));
+}
+
+
+void
+cmd_addch(int nargs, char **args)
+{
+ chtype *ch;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ ch = (chtype *) args[0];
+ report_count(1);
+ report_return(addch(ch[0]));
+}
+
+
+void
+cmd_addchnstr(int nargs, char **args)
+{
+ int count;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[1], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(addchnstr((chtype *) args[0], count));
+}
+
+
+void
+cmd_addchstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_return(addchstr((chtype *) args[0]));
+}
+
+
+void
+cmd_addnstr(int nargs, char **args)
+{
+ int count;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[1], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(addnstr(args[0], count));
+}
+
+
+void
+cmd_addstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_return(addstr(args[0]));
+}
+
+
+void
+cmd_attr_get(int nargs, char **args)
+{
+ attr_t attrs;
+ short colours;
+ int retval;
+
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ retval = attr_get(&attrs, &colours, NULL);
+
+ /* XXXX - call3 */
+ report_count(3);
+ report_return(retval);
+ report_int(attrs);
+ report_int(colours);
+}
+
+
+void
+cmd_attr_off(int nargs, char **args)
+{
+ int attrib;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &attrib) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(attr_off(attrib, NULL));
+}
+
+
+void
+cmd_attr_on(int nargs, char **args)
+{
+ int attrib;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &attrib) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(attr_on(attrib, NULL));
+}
+
+
+void
+cmd_attr_set(int nargs, char **args)
+{
+ int attrib;
+ short pair;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &attrib) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%hd", &pair) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(attr_set(attrib, pair, NULL));
+}
+
+
+void
+cmd_attroff(int nargs, char **args)
+{
+ int attrib;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &attrib) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(attroff(attrib));
+}
+
+
+void
+cmd_attron(int nargs, char **args)
+{
+ int attrib;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &attrib) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(attron(attrib));
+}
+
+
+void
+cmd_attrset(int nargs, char **args)
+{
+ int attrib;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &attrib) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(attrset(attrib));
+}
+
+
+void
+cmd_bkgd(int nargs, char **args)
+{
+ chtype *ch;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ ch = (chtype *) args[0];
+ report_count(1);
+ report_return(bkgd(ch[0]));
+}
+
+
+void
+cmd_bkgdset(int nargs, char **args)
+{
+ chtype *ch;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ ch = (chtype *) args[0];
+ bkgdset(ch[0]); /* returns void */
+ report_count(1);
+ report_return(OK);
+}
+
+
+void
+cmd_border(int nargs, char **args)
+{
+ int ls, rs, ts, bs, tl, tr, bl, br;
+
+ if (check_arg_count(nargs, 8) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &ls) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+ if (sscanf(args[1], "%d", &rs) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+ if (sscanf(args[2], "%d", &ts) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+ if (sscanf(args[3], "%d", &bs) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+ if (sscanf(args[4], "%d", &tl) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+ if (sscanf(args[5], "%d", &tr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+ if (sscanf(args[6], "%d", &bl) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+ if (sscanf(args[7], "%d", &br) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(border(ls, rs, ts, bs, tl, tr, bl, br));
+}
+
+
+void
+cmd_clear(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(clear());
+}
+
+
+void
+cmd_clrtobot(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(clrtobot());
+}
+
+
+void
+cmd_clrtoeol(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(clrtoeol());
+}
+
+
+void
+cmd_color_set(int nargs, char **args)
+{
+ short colour_pair;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%hd", &colour_pair) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(color_set(colour_pair, NULL));
+}
+
+
+void
+cmd_delch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(delch());
+}
+
+
+void
+cmd_deleteln(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(deleteln());
+}
+
+
+void
+cmd_echochar(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ /* XXX causes refresh */
+ report_count(1);
+ report_return(echochar(args[0][0]));
+}
+
+
+void
+cmd_erase(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(erase());
+}
+
+
+void
+cmd_getch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ /* XXX causes refresh */
+ report_count(1);
+ report_int(getch());
+}
+
+
+void
+cmd_getnstr(int nargs, char **args)
+{
+ int limit;
+ char *string;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &limit) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if ((string = malloc(limit + 1)) == NULL) {
+ report_count(1);
+ report_error("MALLOC_FAILED");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(getnstr(string, limit));
+ report_status(string);
+ free(string);
+}
+
+
+void
+cmd_getstr(int nargs, char **args)
+{
+ char string[256];
+
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(getstr(string));
+ report_status(string);
+}
+
+
+void
+cmd_inch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+
+ report_count(1);
+ report_byte(inch());
+}
+
+
+void
+cmd_inchnstr(int nargs, char **args)
+{
+ int limit;
+ chtype *string;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &limit) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if ((string = malloc((limit + 1) * sizeof(chtype))) == NULL) {
+ report_count(1);
+ report_error("MALLOC_FAILED");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(inchnstr(string, limit));
+ report_nstr(string);
+ free(string);
+}
+
+
+void
+cmd_inchstr(int nargs, char **args)
+{
+ chtype string[256];
+
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(inchstr(string));
+ report_nstr(string);
+}
+
+
+void
+cmd_innstr(int nargs, char **args)
+{
+ int limit;
+ char *string;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &limit) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if ((string = malloc(limit + 1)) == NULL) {
+ report_count(1);
+ report_error("MALLOC_FAILED");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_int(innstr(string, limit));
+ report_status(string);
+ free(string);
+}
+
+
+void
+cmd_insch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_return(insch(args[0][0]));
+}
+
+
+void
+cmd_insdelln(int nargs, char **args)
+{
+ int nlines;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &nlines) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(insdelln(nlines));
+}
+
+
+void
+cmd_insertln(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(insertln());
+}
+
+
+void
+cmd_instr(int nargs, char **args)
+{
+ char string[256];
+
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(instr(string));
+ report_status(string);
+}
+
+
+void
+cmd_move(int nargs, char **args)
+{
+ int y, x;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(move(y, x));
+}
+
+
+void
+cmd_refresh(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(refresh());
+}
+
+
+void
+cmd_scrl(int nargs, char **args)
+{
+ int nlines;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &nlines) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(scrl(nlines));
+}
+
+
+void
+cmd_setscrreg(int nargs, char **args)
+{
+ int top, bottom;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &top) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &bottom) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(setscrreg(top, bottom));
+}
+
+
+void
+cmd_standend(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(standend());
+}
+
+
+void
+cmd_standout(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(standout());
+}
+
+
+void
+cmd_timeout(int nargs, char **args)
+{
+ int tval;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &tval) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ timeout(tval); /* void return */
+ report_count(1);
+ report_return(OK);
+}
+
+
+void
+cmd_underscore(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(underscore());
+}
+
+
+void
+cmd_underend(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(underend());
+}
+
+
+void
+cmd_waddbytes(int nargs, char **args)
+{
+ WINDOW *win;
+ int count;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(waddbytes(win, args[1], count));
+}
+
+
+void
+cmd_waddstr(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(waddstr(win, args[1]));
+}
+
+
+void
+cmd_mvaddbytes(int nargs, char **args)
+{
+ int y, x, count;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvaddbytes(y, x, args[2], count));
+}
+
+
+void
+cmd_mvaddch(int nargs, char **args)
+{
+ int y, x;
+ chtype *ch;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ ch = (chtype *) args[2];
+ report_count(1);
+ report_return(mvaddch(y, x, ch[0]));
+}
+
+
+void
+cmd_mvaddchnstr(int nargs, char **args)
+{
+ int y, x, count;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvaddchnstr(y, x, (chtype *) args[2], count));
+}
+
+
+void
+cmd_mvaddchstr(int nargs, char **args)
+{
+ int y, x;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvaddchstr(y, x, (chtype *) args[2]));
+}
+
+
+void
+cmd_mvaddnstr(int nargs, char **args)
+{
+ int y, x, count;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvaddnstr(y, x, args[2], count));
+}
+
+
+void
+cmd_mvaddstr(int nargs, char **args)
+{
+ int y, x;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvaddstr(y, x, args[2]));
+}
+
+
+void
+cmd_mvdelch(int nargs, char **args)
+{
+ int y, x;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvdelch(y, x));
+}
+
+
+void
+cmd_mvgetch(int nargs, char **args)
+{
+ int y, x;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(mvgetch(y, x));
+}
+
+
+void
+cmd_mvgetnstr(int nargs, char **args)
+{
+ int y, x, count;
+ char *string;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if ((string = malloc(count + 1)) == NULL) {
+ report_count(1);
+ report_error("MALLOC_FAILED");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(mvgetnstr(y, x, string, count));
+ report_status(string);
+ free(string);
+}
+
+
+void
+cmd_mvgetstr(int nargs, char **args)
+{
+ int y, x;
+ char string[256];
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(mvgetstr(y, x, string));
+ report_status(string);
+}
+
+
+void
+cmd_mvinch(int nargs, char **args)
+{
+ int y, x;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(mvinch(y, x));
+}
+
+
+void
+cmd_mvinchnstr(int nargs, char **args)
+{
+ int y, x, count;
+ chtype *string;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if ((string = malloc((count + 1) * sizeof(chtype))) == NULL) {
+ report_count(1);
+ report_error("MALLOC_FAILED");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(mvinchnstr(y, x, string, count));
+ report_nstr(string);
+ free(string);
+}
+
+
+void
+cmd_mvinchstr(int nargs, char **args)
+{
+ int y, x;
+ chtype string[256];
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(mvinchstr(y, x, string));
+ report_nstr(string);
+}
+
+
+void
+cmd_mvinnstr(int nargs, char **args)
+{
+ int y, x, count;
+ char *string;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if ((string = malloc(count + 1)) == NULL) {
+ report_count(1);
+ report_error("MALLOC_FAILED");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(mvinnstr(y, x, string, count));
+ report_status(string);
+ free(string);
+}
+
+
+void
+cmd_mvinsch(int nargs, char **args)
+{
+ int y, x, ch;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &ch) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvinsch(y, x, ch));
+}
+
+
+void
+cmd_mvinstr(int nargs, char **args)
+{
+ int y, x;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvinstr(y, x, args[2]));
+}
+
+
+
+void
+cmd_mvwaddbytes(int nargs, char **args)
+{
+ int y, x, count;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 5) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwaddbytes(win, y, x, args[3], count));
+}
+
+
+void
+cmd_mvwaddch(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwaddch(win, y, x, args[3][0]));
+}
+
+
+void
+cmd_mvwaddchnstr(int nargs, char **args)
+{
+ int y, x, count;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 5) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwaddchnstr(win, y, x, (chtype *) args[3], count));
+}
+
+
+void
+cmd_mvwaddchstr(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwaddchstr(win, y, x, (chtype *) args[3]));
+}
+
+
+void
+cmd_mvwaddnstr(int nargs, char **args)
+{
+ int y, x, count;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 5) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwaddnstr(win, y, x, args[3], count));
+}
+
+
+void
+cmd_mvwaddstr(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwaddstr(win, y, x, args[3]));
+}
+
+
+void
+cmd_mvwdelch(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwdelch(win, y, x));
+}
+
+
+void
+cmd_mvwgetch(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - implicit refresh */
+ report_count(1);
+ report_int(mvwgetch(win, y, x));
+}
+
+
+void
+cmd_mvwgetnstr(int nargs, char **args)
+{
+ int y, x, count;
+ char *string;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if ((string = malloc(count + 1)) == NULL) {
+ report_count(1);
+ report_error("MALLOC_FAILED");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(mvwgetnstr(win, y, x, string, count));
+ report_status(string);
+ free(string);
+}
+
+
+void
+cmd_mvwgetstr(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+ char string[256];
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call2 */
+ report_count(2);
+ report_return(mvwgetstr(win, y, x, string));
+ report_status(string);
+}
+
+
+void
+cmd_mvwinch(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(mvwinch(win, y, x));
+}
+
+
+void
+cmd_mvwinsch(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(mvwinsch(win, y, x, args[3][0]));
+}
+
+
+void
+cmd_assume_default_colors(int nargs, char **args)
+{
+ short fore, back;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%hd", &fore) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%hd", &back) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(assume_default_colors(fore, back));
+}
+
+
+void
+cmd_baudrate(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_int(baudrate());
+}
+
+
+void
+cmd_beep(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(beep());
+}
+
+
+void
+cmd_box(int nargs, char **args)
+{
+ WINDOW *win;
+ chtype *vertical, *horizontal;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ vertical = (chtype *) args[1];
+ horizontal = (chtype *) args[2];
+ report_count(1);
+ report_return(box(win, vertical[0], horizontal[0]));
+}
+
+
+void
+cmd_can_change_color(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_int(can_change_color());
+}
+
+
+void
+cmd_cbreak(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(cbreak());
+}
+
+
+void
+cmd_clearok(int nargs, char **args)
+{
+ WINDOW *win;
+ int flag;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(clearok(win, flag));
+}
+
+
+void
+cmd_color_content(int nargs, char **args)
+{
+ short colour, red, green, blue;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%hd", &colour) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call4 */
+ report_count(4);
+ report_return(color_content(colour, &red, &green, &blue));
+ report_int(red);
+ report_int(green);
+ report_int(blue);
+}
+
+
+void
+cmd_copywin(int nargs, char **args)
+{
+ int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol, ovlay;
+ WINDOW *source, *destination;
+
+ if (check_arg_count(nargs, 9) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &source) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%p", &destination) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &sminrow) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &smincol) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &dminrow) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[5], "%d", &dmincol) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[6], "%d", &dmaxrow) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[7], "%d", &dmaxcol) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[8], "%d", &ovlay) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(copywin(source, destination, sminrow, smincol, dminrow,
+ dmincol, dmaxrow, dmaxcol, ovlay));
+}
+
+
+void
+cmd_curs_set(int nargs, char **args)
+{
+ int vis;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &vis) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(curs_set(vis));
+}
+
+
+void
+cmd_def_prog_mode(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(def_prog_mode());
+}
+
+
+void
+cmd_def_shell_mode(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(def_shell_mode());
+}
+
+
+void
+cmd_define_key(int nargs, char **args)
+{
+ int symbol;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[1], "%d", &symbol) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(define_key(args[0], symbol));
+}
+
+
+void
+cmd_delay_output(int nargs, char **args)
+{
+ int dtime;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &dtime) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(delay_output(dtime));
+}
+
+
+void
+cmd_delscreen(int nargs, char **args)
+{
+ SCREEN *scrn;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &scrn) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ delscreen(scrn); /* void return */
+ report_count(1);
+ report_return(OK);
+}
+
+
+void
+cmd_delwin(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(delwin(win));
+}
+
+
+void
+cmd_derwin(int nargs, char **args)
+{
+ int lines, cols, y, x;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 5) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &lines) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &cols) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_ptr(derwin(win, lines, cols, y, x));
+}
+
+
+void
+cmd_dupwin(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_ptr(dupwin(win));
+}
+
+
+void
+cmd_doupdate(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ /* XXX - implicit refresh */
+ report_count(1);
+ report_return(doupdate());
+}
+
+
+void
+cmd_echo(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(echo());
+}
+
+
+void
+cmd_endwin(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(endwin());
+}
+
+
+void
+cmd_erasechar(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_int(erasechar());
+}
+
+
+void
+cmd_flash(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(flash());
+}
+
+
+void
+cmd_flushinp(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(flushinp());
+}
+
+
+void
+cmd_flushok(int nargs, char **args)
+{
+ int flag;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(flushok(win, flag));
+}
+
+
+void
+cmd_fullname(int nargs, char **args)
+{
+ char string[256];
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ /* XXX - call2 */
+ report_count(2);
+ report_status(fullname(args[0], string));
+ report_status(string);
+}
+
+
+void
+cmd_getattrs(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(getattrs(win));
+}
+
+
+void
+cmd_getbkgd(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_byte(getbkgd(win));
+}
+
+
+void
+cmd_getcury(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(getcury(win));
+}
+
+
+void
+cmd_getcurx(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(getcurx(win));
+}
+
+
+void
+cmd_getyx(int nargs, char **args)
+{
+ WINDOW *win;
+ int y, x;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ getyx(win, y, x);
+ report_count(2);
+ report_int(y);
+ report_int(x);
+}
+
+
+void
+cmd_getbegy(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(getbegy(win));
+}
+
+
+void
+cmd_getbegx(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(getbegx(win));
+}
+
+
+void
+cmd_getmaxy(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(getmaxy(win));
+}
+
+
+void
+cmd_getmaxx(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(getmaxx(win));
+}
+
+
+void
+cmd_getpary(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(getpary(win));
+}
+
+
+void
+cmd_getparx(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(getparx(win));
+}
+
+
+void
+cmd_getparyx(int nargs, char **args)
+{
+ WINDOW *win;
+ int y, x;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(2);
+ getparyx(win, y, x);
+ report_int(y);
+ report_int(x);
+}
+
+
+void
+cmd_gettmode(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(gettmode());
+}
+
+
+void
+cmd_getwin(int nargs, char **args)
+{
+ FILE *fp;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if ((fp = fopen(args[0], "r")) == NULL) {
+ report_count(1);
+ report_error("BAD FILE_ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_ptr(getwin(fp));
+ fclose(fp);
+}
+
+
+void
+cmd_halfdelay(int nargs, char **args)
+{
+ int ms;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &ms) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(halfdelay(ms));
+}
+
+
+void
+cmd_has_colors(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_int(has_colors());
+}
+
+
+void
+cmd_has_ic(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_int(has_ic());
+}
+
+
+void
+cmd_has_il(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_int(has_il());
+}
+
+
+void
+cmd_hline(int nargs, char **args)
+{
+ int count;
+ chtype *ch;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ ch = (chtype *) args[0];
+
+ if (sscanf(args[1], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(hline(ch[0], count));
+}
+
+
+void
+cmd_idcok(int nargs, char **args)
+{
+ int flag;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(idcok(win, flag));
+}
+
+
+void
+cmd_idlok(int nargs, char **args)
+{
+ int flag;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(idlok(win, flag));
+}
+
+
+void
+cmd_init_color(int nargs, char **args)
+{
+ short colour, red, green, blue;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%hd", &colour) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%hd", &red) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%hd", &green) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%hd", &blue) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(init_color(colour, red, green, blue));
+}
+
+
+void
+cmd_init_pair(int nargs, char **args)
+{
+ short pair, fore, back;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%hd", &pair) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%hd", &fore) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%hd", &back) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(init_pair(pair, fore, back));
+}
+
+
+void
+cmd_initscr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_ptr(initscr());
+}
+
+
+void
+cmd_intrflush(int nargs, char **args)
+{
+ int flag;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(intrflush(win, flag));
+}
+
+
+void
+cmd_isendwin(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_int(isendwin());
+}
+
+
+void
+cmd_is_linetouched(int nargs, char **args)
+{
+ int line;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &line) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(is_linetouched(win, line));
+}
+
+
+void
+cmd_is_wintouched(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(is_wintouched(win));
+}
+
+
+void
+cmd_keyok(int nargs, char **args)
+{
+ int keysym, flag;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &keysym) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(keyok(keysym, flag));
+}
+
+
+void
+cmd_keypad(int nargs, char **args)
+{
+ int flag;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(keypad(win, flag));
+}
+
+
+void
+cmd_keyname(int nargs, char **args)
+{
+ unsigned int key;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &key) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_status(keyname(key));
+}
+
+
+void
+cmd_killchar(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_int(killchar());
+}
+
+
+void
+cmd_leaveok(int nargs, char **args)
+{
+ int flag;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(leaveok(win, flag));
+}
+
+
+void
+cmd_meta(int nargs, char **args)
+{
+ int flag;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(meta(win, flag));
+}
+
+
+void
+cmd_mvcur(int nargs, char **args)
+{
+ int oldy, oldx, y, x;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &oldy) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &oldx) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvcur(oldy, oldx, y, x));
+}
+
+
+void
+cmd_mvderwin(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvderwin(win, y, x));
+}
+
+
+void
+cmd_mvhline(int nargs, char **args)
+{
+ int y, x, n;
+ chtype *ch;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ ch = (chtype *) args[2];
+
+ if (sscanf(args[3], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvhline(y, x, ch[0], n));
+}
+
+
+void
+cmd_mvprintw(int nargs, char **args)
+{
+ int y, x;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvprintw(y, x, args[2], args[3]));
+}
+
+
+void
+cmd_mvscanw(int nargs, char **args)
+{
+ int y, x;
+ char string[256];
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call2 */
+ report_count(2);
+ report_return(mvscanw(y, x, args[2], &string));
+ report_status(string);
+}
+
+
+void
+cmd_mvvline(int nargs, char **args)
+{
+ int y, x, n;
+ chtype *ch;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ ch = (chtype *) args[2];
+
+ if (sscanf(args[3], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvvline(y, x, ch[0], n));
+}
+
+
+void
+cmd_mvwhline(int nargs, char **args)
+{
+ int y, x, ch, n;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 5) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &ch) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwhline(win, y, x, ch, n));
+}
+
+
+void
+cmd_mvwvline(int nargs, char **args)
+{
+ int y, x, n;
+ WINDOW *win;
+ chtype *ch;
+
+ if (check_arg_count(nargs, 5) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ ch = (chtype *) args[3];
+
+ if (sscanf(args[4], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwvline(win, y, x, ch[0], n));
+}
+
+
+void
+cmd_mvwin(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwin(win, y, x));
+}
+
+
+void
+cmd_mvwinchnstr(int nargs, char **args)
+{
+ int y, x, count;
+ chtype *string;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if ((string = malloc((count + 1) * sizeof(chtype))) == NULL) {
+ report_count(1);
+ report_error("MALLOC_FAILED");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(mvwinchnstr(win, y, x, string, count));
+ report_nstr(string);
+ free(string);
+}
+
+
+void
+cmd_mvwinchstr(int nargs, char **args)
+{
+ int y, x;
+ chtype string[256];
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(mvwinchstr(win, y, x, string));
+ report_nstr(string);
+}
+
+
+void
+cmd_mvwinnstr(int nargs, char **args)
+{
+ int y, x, count;
+ char *string;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if ((string = malloc(count + 1)) == NULL) {
+ report_count(1);
+ report_error("MALLOC_FAILED");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(mvwinnstr(win, y, x, string, count));
+ report_status(string);
+ free(string);
+}
+
+
+void
+cmd_mvwinstr(int nargs, char **args)
+{
+ int y, x;
+ char string[256];
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(mvwinstr(win, y, x, string));
+ report_status(string);
+}
+
+
+void
+cmd_mvwprintw(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 5) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwprintw(win, y, x, args[3], args[4]));
+}
+
+
+void
+cmd_mvwscanw(int nargs, char **args)
+{
+ int y, x;
+ WINDOW *win;
+ char string[256];
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call2 */
+ report_count(2);
+ report_int(mvwscanw(win, y, x, args[3], &string));
+ report_status(string);
+}
+
+
+void
+cmd_napms(int nargs, char **args)
+{
+ int naptime;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &naptime) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(napms(naptime));
+}
+
+
+void
+cmd_newpad(int nargs, char **args)
+{
+ int y, x;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_ptr(newpad(y, x));
+}
+
+
+void
+cmd_newterm(int nargs, char **args)
+{
+ FILE *in, *out;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if ((in = fopen(args[1], "rw")) == NULL) {
+ report_count(1);
+ report_error("BAD FILE_ARGUMENT");
+ return;
+ }
+
+
+ if ((out = fopen(args[2], "rw")) == NULL) {
+ report_count(1);
+ report_error("BAD FILE_ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_ptr(newterm(args[0], out, in));
+}
+
+
+void
+cmd_newwin(int nargs, char **args)
+{
+ int lines, cols, begin_y, begin_x;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &lines) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &cols) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &begin_y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &begin_x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_ptr(newwin(lines, cols, begin_y, begin_x));
+}
+
+
+void
+cmd_nl(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(nl());
+}
+
+
+void
+cmd_no_color_attributes(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_int(no_color_attributes());
+}
+
+
+void
+cmd_nocbreak(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(nocbreak());
+}
+
+
+void
+cmd_nodelay(int nargs, char **args)
+{
+ int flag;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(nodelay(win, flag));
+}
+
+
+void
+cmd_noecho(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(noecho());
+}
+
+
+void
+cmd_nonl(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(nonl());
+}
+
+
+void
+cmd_noqiflush(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ noqiflush();
+ report_count(1);
+ report_return(OK); /* fake a return, the call returns void */
+}
+
+
+void
+cmd_noraw(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(noraw());
+}
+
+
+void
+cmd_notimeout(int nargs, char **args)
+{
+ int flag;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(notimeout(win, flag));
+}
+
+
+void
+cmd_overlay(int nargs, char **args)
+{
+ WINDOW *source, *dest;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &source) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%p", &dest) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(overlay(source, dest));
+}
+
+
+void
+cmd_overwrite(int nargs, char **args)
+{
+ WINDOW *source, *dest;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &source) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%p", &dest) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(overwrite(source, dest));
+}
+
+
+void
+cmd_pair_content(int nargs, char **args)
+{
+ short pair, fore, back;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%hd", &pair) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call3 */
+ report_count(3);
+ report_return(pair_content(pair, &fore, &back));
+ report_int(fore);
+ report_int(back);
+}
+
+
+void
+cmd_pechochar(int nargs, char **args)
+{
+ int ch;
+ WINDOW *pad;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &pad) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &ch) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(pechochar(pad, ch));
+}
+
+
+void
+cmd_pnoutrefresh(int nargs, char **args)
+{
+ int pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y, smax_x;
+ WINDOW *pad;
+
+ if (check_arg_count(nargs, 7) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &pad) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &pbeg_y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &pbeg_x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &sbeg_y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &sbeg_x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[5], "%d", &smax_y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[6], "%d", &smax_x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(pnoutrefresh(pad, pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y,
+ smax_x));
+}
+
+
+void
+cmd_prefresh(int nargs, char **args)
+{
+ int pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y, smax_x;
+ WINDOW *pad;
+
+ if (check_arg_count(nargs, 7) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &pad) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &pbeg_y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &pbeg_x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &sbeg_y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &sbeg_x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[5], "%d", &smax_y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[6], "%d", &smax_x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX causes refresh */
+ report_count(1);
+ report_return(prefresh(pad, pbeg_y, pbeg_x, sbeg_y, sbeg_x, smax_y,
+ smax_x));
+
+}
+
+
+void
+cmd_printw(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+
+ report_count(1);
+ report_return(printw(args[0], args[1]));
+}
+
+
+void
+cmd_putwin(int nargs, char **args)
+{
+ FILE *fp;
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if ((fp = fopen(args[1], "rw")) == NULL) {
+ report_count(1);
+ report_error("BAD FILE_ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(putwin(win, fp));
+}
+
+
+void
+cmd_qiflush(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ qiflush();
+ report_count(1);
+ report_return(OK); /* fake a return because call returns void */
+}
+
+
+void
+cmd_raw(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(raw());
+}
+
+
+void
+cmd_redrawwin(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(redrawwin(win));
+}
+
+
+void
+cmd_reset_prog_mode(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(reset_prog_mode());
+}
+
+
+void
+cmd_reset_shell_mode(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(reset_shell_mode());
+}
+
+
+void
+cmd_resetty(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(resetty());
+}
+
+
+void
+cmd_resizeterm(int nargs, char **args)
+{
+ int rows, cols;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &rows) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &cols) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(resizeterm(rows, cols));
+}
+
+
+void
+cmd_savetty(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(savetty());
+}
+
+
+void
+cmd_scanw(int nargs, char **args)
+{
+ char string[256];
+
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ /* XXX call2 */
+ report_count(2);
+ report_return(scanw("%s", string));
+ report_status(string);
+}
+
+
+void
+cmd_scroll(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(scroll(win));
+}
+
+
+void
+cmd_scrollok(int nargs, char **args)
+{
+ WINDOW *win;
+ int flag;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &flag) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(scrollok(win, flag));
+}
+
+
+void
+cmd_setterm(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_return(setterm(args[0]));
+}
+
+
+void
+cmd_set_term(int nargs, char **args)
+{
+ SCREEN *scrn;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &scrn) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_ptr(set_term(scrn));
+}
+
+
+void
+cmd_start_color(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(start_color());
+}
+
+
+void
+cmd_subpad(int nargs, char **args)
+{
+ WINDOW *pad;
+ int lines, cols, begin_y, begin_x;
+
+ if (check_arg_count(nargs, 5) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &pad) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &lines) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &cols) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &begin_y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &begin_x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_ptr(subpad(pad, lines, cols, begin_y, begin_x));
+}
+
+
+void
+cmd_subwin(int nargs, char **args)
+{
+ WINDOW *win;
+ int lines, cols, begin_y, begin_x;
+
+ if (check_arg_count(nargs, 5) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &lines) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &cols) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &begin_y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &begin_x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_ptr(subwin(win, lines, cols, begin_y, begin_x));
+}
+
+
+void
+cmd_termattrs(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_int(termattrs());
+}
+
+
+void
+cmd_term_attrs(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_int(term_attrs());
+}
+
+
+void
+cmd_touchline(int nargs, char **args)
+{
+ WINDOW *win;
+ int start, count;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &start) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(touchline(win, start, count));
+}
+
+
+void
+cmd_touchoverlap(int nargs, char **args)
+{
+ WINDOW *win1, *win2;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win1) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%p", &win2) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(touchoverlap(win1, win2));
+}
+
+
+void
+cmd_touchwin(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(touchwin(win));
+}
+
+
+void
+cmd_ungetch(int nargs, char **args)
+{
+ int ch;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &ch) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(ungetch(ch));
+}
+
+
+void
+cmd_untouchwin(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(untouchwin(win));
+}
+
+
+void
+cmd_use_default_colors(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ report_count(1);
+ report_return(use_default_colors());
+}
+
+
+void
+cmd_vline(int nargs, char **args)
+{
+ int count;
+ chtype *ch;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ ch = (chtype *) args[0];
+
+ if (sscanf(args[1], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(vline(ch[0], count));
+}
+
+
+static int
+internal_vw_printw(WINDOW *win, char *arg1, ...)
+{
+ va_list va;
+ int rv;
+
+ va_start(va, arg1);
+ rv = vw_printw(win, arg1, va);
+ va_end(va);
+
+ return rv;
+}
+
+void
+cmd_vw_printw(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(internal_vw_printw(win, args[1], args[2]));
+}
+
+
+static int
+internal_vw_scanw(WINDOW *win, char *arg1, ...)
+{
+ va_list va;
+ int rv;
+
+ va_start(va, arg1);
+ rv = vw_scanw(win, arg1, va);
+ va_end(va);
+
+ return rv;
+}
+
+void
+cmd_vw_scanw(int nargs, char **args)
+{
+ WINDOW *win;
+ char string[256];
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call2 */
+ report_count(2);
+ report_int(internal_vw_scanw(win, args[1], string));
+ report_status(string);
+}
+
+
+void
+cmd_vwprintw(int nargs, char **args)
+{
+ cmd_vw_printw(nargs, args);
+}
+
+
+void
+cmd_vwscanw(int nargs, char **args)
+{
+ cmd_vw_scanw(nargs, args);
+}
+
+
+void
+cmd_waddch(int nargs, char **args)
+{
+ WINDOW *win;
+ chtype *ch;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ ch = (chtype *) args[1];
+
+ report_count(1);
+ report_return(waddch(win, ch[0]));
+}
+
+
+void
+cmd_waddchnstr(int nargs, char **args)
+{
+ WINDOW *win;
+ int count;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(waddchnstr(win, (chtype *) args[1], count));
+}
+
+
+void
+cmd_waddchstr(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(waddchstr(win, (chtype *) args[1]));
+}
+
+
+void
+cmd_waddnstr(int nargs, char **args)
+{
+ WINDOW *win;
+ int count;
+
+ if (check_arg_count(nargs, 1) == 3)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(waddnstr(win, args[1], count));
+
+}
+
+
+void
+cmd_wattr_get(int nargs, char **args)
+{
+ WINDOW *win;
+ int attr;
+ short pair;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call3 */
+ report_count(3);
+ report_return(wattr_get(win, &attr, &pair, NULL));
+ report_int(attr);
+ report_int(pair);
+}
+
+
+void
+cmd_wattr_off(int nargs, char **args)
+{
+ WINDOW *win;
+ int attr;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &attr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wattr_off(win, attr, NULL));
+}
+
+
+void
+cmd_wattr_on(int nargs, char **args)
+{
+ WINDOW *win;
+ int attr;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &attr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wattr_on(win, attr, NULL));
+}
+
+
+void
+cmd_wattr_set(int nargs, char **args)
+{
+ WINDOW *win;
+ int attr;
+ short pair;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &attr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%hd", &pair) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wattr_set(win, attr, pair, NULL));
+}
+
+
+void
+cmd_wattroff(int nargs, char **args)
+{
+ WINDOW *win;
+ int attr;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &attr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wattroff(win, attr));
+}
+
+
+void
+cmd_wattron(int nargs, char **args)
+{
+ WINDOW *win;
+ int attr;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &attr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wattron(win, attr));
+}
+
+
+void
+cmd_wattrset(int nargs, char **args)
+{
+ WINDOW *win;
+ int attr;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &attr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wattrset(win, attr));
+}
+
+
+void
+cmd_wbkgd(int nargs, char **args)
+{
+ WINDOW *win;
+ chtype *ch;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ ch = (chtype *) args[1];
+ report_count(1);
+ report_return(wbkgd(win, ch[0]));
+}
+
+
+void
+cmd_wbkgdset(int nargs, char **args)
+{
+ WINDOW *win;
+ int ch;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &ch) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ wbkgdset(win, ch); /* void return */
+ report_count(1);
+ report_return(OK);
+}
+
+
+void
+cmd_wborder(int nargs, char **args)
+{
+ WINDOW *win;
+ int ls, rs, ts, bs, tl, tr, bl, br;
+
+ if (check_arg_count(nargs, 9) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &ls) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &rs) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &ts) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &bs) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[5], "%d", &tl) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[6], "%d", &tr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[7], "%d", &bl) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[8], "%d", &br) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wborder(win, ls, rs, ts, bs, tl, tr, bl, br));
+}
+
+
+void
+cmd_wclear(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wclear(win));
+}
+
+
+void
+cmd_wclrtobot(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wclrtobot(win));
+}
+
+
+void
+cmd_wclrtoeol(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wclrtoeol(win));
+
+}
+
+
+void
+cmd_wcolor_set(int nargs, char **args)
+{
+ WINDOW *win;
+ short pair;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%hd", &pair) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wcolor_set(win, pair, NULL));
+}
+
+
+void
+cmd_wdelch(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wdelch(win));
+}
+
+
+void
+cmd_wdeleteln(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wdeleteln(win));
+
+}
+
+
+void
+cmd_wechochar(int nargs, char **args)
+{
+ WINDOW *win;
+ int ch;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &ch) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wechochar(win, ch));
+}
+
+
+void
+cmd_werase(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(werase(win));
+}
+
+
+void
+cmd_wgetch(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(wgetch(win));
+}
+
+
+void
+cmd_wgetnstr(int nargs, char **args)
+{
+ WINDOW *win;
+ int count;
+ char string[256];
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call2 */
+ report_count(2);
+ report_return(wgetnstr(win, string, count));
+ report_status(string);
+}
+
+
+void
+cmd_wgetstr(int nargs, char **args)
+{
+ WINDOW *win;
+ char string[256];
+
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ string[0] = '\0';
+
+ report_count(2);
+ report_return(wgetstr(win, string));
+ report_status(string);
+}
+
+
+void
+cmd_whline(int nargs, char **args)
+{
+ WINDOW *win;
+ int ch, count;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &ch) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(whline(win, ch, count));
+}
+
+
+void
+cmd_winch(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_int(winch(win));
+}
+
+
+void
+cmd_winchnstr(int nargs, char **args)
+{
+ WINDOW *win;
+ chtype string[256];
+ int count;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call2 */
+ report_count(2);
+ report_return(winchnstr(win, string, count));
+ report_nstr(string);
+}
+
+
+void
+cmd_winchstr(int nargs, char **args)
+{
+ WINDOW *win;
+ chtype string[256];
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call2 */
+ report_count(2);
+ report_return(winchstr(win, string));
+ report_nstr(string);
+}
+
+
+void
+cmd_winnstr(int nargs, char **args)
+{
+ WINDOW *win;
+ char string[256];
+ int count;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call2 */
+ report_count(2);
+ report_return(winnstr(win, string, count));
+ report_status(string);
+}
+
+
+void
+cmd_winsch(int nargs, char **args)
+{
+ WINDOW *win;
+ int ch;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &ch) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(winsch(win, ch));
+}
+
+
+void
+cmd_winsdelln(int nargs, char **args)
+{
+ WINDOW *win;
+ int count;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &count) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(winsdelln(win, count));
+}
+
+
+void
+cmd_winsertln(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(winsertln(win));
+}
+
+
+void
+cmd_winstr(int nargs, char **args)
+{
+ WINDOW *win;
+ char string[256];
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - call2 */
+ report_count(2);
+ report_return(winstr(win, string));
+ report_status(string);
+}
+
+
+void
+cmd_wmove(int nargs, char **args)
+{
+ WINDOW *win;
+ int y, x;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wmove(win, y, x));
+}
+
+
+void
+cmd_wnoutrefresh(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wnoutrefresh(win));
+}
+
+
+void
+cmd_wprintw(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wprintw(win, args[1], args[2]));
+}
+
+
+void
+cmd_wredrawln(int nargs, char **args)
+{
+ WINDOW *win;
+ int beg_line, num_lines;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &beg_line) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &num_lines) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wredrawln(win, beg_line, num_lines));
+}
+
+
+void
+cmd_wrefresh(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* XXX - generates output */
+ report_count(1);
+ report_return(wrefresh(win));
+}
+
+
+void
+cmd_wresize(int nargs, char **args)
+{
+ WINDOW *win;
+ int lines, cols;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &lines) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &cols) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wresize(win, lines, cols));
+}
+
+
+void
+cmd_wscanw(int nargs, char **args)
+{
+ WINDOW *win;
+ char string[256];
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wscanw(win, args[1], &string));
+}
+
+
+void
+cmd_wscrl(int nargs, char **args)
+{
+ WINDOW *win;
+ int n;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wscrl(win, n));
+}
+
+
+void
+cmd_wsetscrreg(int nargs, char **args)
+{
+ WINDOW *win;
+ int top, bottom;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &top) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &bottom) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wsetscrreg(win, top, bottom));
+}
+
+
+void
+cmd_wstandend(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wstandend(win));
+}
+
+
+void
+cmd_wstandout(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wstandout(win));
+}
+
+
+void
+cmd_wtimeout(int nargs, char **args)
+{
+ WINDOW *win;
+ int tval;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &tval) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ wtimeout(win, tval); /* void return */
+ report_count(1);
+ report_return(OK);
+}
+
+
+void
+cmd_wtouchln(int nargs, char **args)
+{
+ WINDOW *win;
+ int line, n, changed;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &line) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &changed) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wtouchln(win, line, n, changed));
+}
+
+
+void
+cmd_wunderend(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wunderend(win));
+}
+
+
+void
+cmd_wunderscore(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wunderscore(win));
+}
+
+
+void
+cmd_wvline(int nargs, char **args)
+{
+ WINDOW *win;
+ int n;
+ chtype *ch;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ ch = (chtype *) args[1];
+
+ if (sscanf(args[2], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wvline(win, ch[0], n));
+}
+
+
+void
+cmd_insnstr(int nargs, char **args)
+{
+ int n;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[1], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(insnstr(args[0], n));
+}
+
+
+void
+cmd_insstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_return(insstr(args[0]));
+}
+
+
+void
+cmd_mvinsnstr(int nargs, char **args)
+{
+ int y, x, n;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvinsnstr(y, x, args[2], n));
+}
+
+
+void
+cmd_mvinsstr(int nargs, char **args)
+{
+ int y, x;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvinsstr(y, x, args[2]));
+}
+
+
+void
+cmd_mvwinsnstr(int nargs, char **args)
+{
+ WINDOW *win;
+ int y, x, n;
+
+ if (check_arg_count(nargs, 5) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwinsnstr(win, y, x, args[3], n));
+
+}
+
+
+void
+cmd_mvwinsstr(int nargs, char **args)
+{
+ WINDOW *win;
+ int y, x;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwinsstr(win, y, x, args[3]));
+}
+
+
+void
+cmd_winsnstr(int nargs, char **args)
+{
+ WINDOW *win;
+ int n;
+
+ if (check_arg_count(nargs, 3) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(winsnstr(win, args[1], n));
+}
+
+
+void
+cmd_winsstr(int nargs, char **args)
+{
+ WINDOW *win;
+
+ if (check_arg_count(nargs, 2) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(winsstr(win, args[1]));
+}
+
+
+
+void
+cmd_chgat(int nargs, char **args)
+{
+ int n, attr, colour;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &attr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &colour) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ /* Note: 4th argument unused in current curses implementation */
+ report_count(1);
+ report_return(chgat(n, attr, colour, NULL));
+}
+
+
+void
+cmd_wchgat(int nargs, char **args)
+{
+ WINDOW *win;
+ int n, attr;
+ short colour;
+
+ if (check_arg_count(nargs, 4) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &attr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%hd", &colour) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(wchgat(win, n, attr, colour, NULL));
+}
+
+
+void
+cmd_mvchgat(int nargs, char **args)
+{
+ int y, x, n, attr;
+ short colour;
+
+ if (check_arg_count(nargs, 6) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &attr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%hd", &colour) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvchgat(y, x, n, attr, colour, NULL));
+}
+
+
+void
+cmd_mvwchgat(int nargs, char **args)
+{
+ WINDOW *win;
+ int y, x, n, attr, colour;
+
+ if (check_arg_count(nargs, 6) == 1)
+ return;
+
+ if (sscanf(args[0], "%p", &win) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[1], "%d", &y) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[2], "%d", &x) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[3], "%d", &n) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[4], "%d", &attr) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ if (sscanf(args[5], "%d", &colour) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_return(mvwchgat(win, y, x, n, attr, colour, NULL));
+}
+
+
+void
+cmd_add_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wadd_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvadd_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwadd_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+void
+cmd_add_wchnstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_add_wchstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wadd_wchnstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wadd_wchstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvadd_wchnstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvadd_wchstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwadd_wchnstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwadd_wchstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+void
+cmd_addnwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_addwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvaddnwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvaddwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwaddnwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwaddwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_waddnwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_waddwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+void
+cmd_echo_wchar(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wecho_wchar(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_pecho_wchar(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+/* insert */
+void
+cmd_ins_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wins_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvins_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwins_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+void
+cmd_ins_nwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_ins_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvins_nwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvins_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwins_nwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwins_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wins_nwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wins_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+/* input */
+void
+cmd_get_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_unget_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvget_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwget_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wget_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+void
+cmd_getn_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_get_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvgetn_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvget_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwgetn_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwget_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wgetn_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wget_wstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+void
+cmd_in_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvin_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwin_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_win_wch(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+void
+cmd_in_wchnstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_in_wchstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvin_wchnstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvin_wchstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwin_wchnstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwin_wchstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_win_wchnstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_win_wchstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+void
+cmd_innwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_inwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvinnwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvinwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwinnwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwinwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_winnwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_winwstr(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+/* cchar handlgin */
+void
+cmd_setcchar(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_getcchar(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+
+/* misc */
+void
+cmd_key_name(int nargs, char **args)
+{
+ int w;
+
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ if (sscanf(args[0], "%d", &w) == 0) {
+ report_count(1);
+ report_error("BAD ARGUMENT");
+ return;
+ }
+
+ report_count(1);
+ report_status(key_name(w));
+}
+
+
+void
+cmd_border_set(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wborder_set(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_box_set(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_erasewchar(int nargs, char **args)
+{
+ wchar_t ch;
+
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ /* XXX - call2 */
+ report_count(2);
+ report_return(erasewchar(&ch));
+ report_int(ch);
+}
+
+
+void
+cmd_killwchar(int nargs, char **args)
+{
+ wchar_t ch;
+
+ if (check_arg_count(nargs, 0) == 1)
+ return;
+
+ /* XXX - call2 */
+ report_count(2);
+ report_return(erasewchar(&ch));
+ report_int(ch);
+}
+
+
+void
+cmd_hline_set(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvhline_set(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvvline_set(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwhline_set(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_mvwvline_set(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_vline_set(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_whline_set(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wvline_set(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_bkgrnd(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_bkgrndset(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_getbkgrnd(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wbkgrnd(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wbkgrndset(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
+
+
+void
+cmd_wgetbkgrnd(int nargs, char **args)
+{
+ if (check_arg_count(nargs, 1) == 1)
+ return;
+
+ report_count(1);
+ report_error("UNSUPPORTED");
+}
diff --git a/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.h b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.h
new file mode 100644
index 0000000..d7f2ad7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/slave/curses_commands.h
@@ -0,0 +1,422 @@
+/* $NetBSD: curses_commands.h,v 1.3 2011/09/15 11:46:19 blymn Exp $ */
+
+/*-
+ * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
+ *
+ * All rights reserved.
+ *
+ * This code has been donated to The NetBSD Foundation by the Author.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ *
+ */
+
+#ifndef _CURSES_COMMANDS_H_
+#define _CURSES_COMMANDS_H_
+
+struct command_def {
+ const char *name;
+ void (*func)(int, char **);
+};
+
+/*
+ * prototypes for test commands
+ */
+void cmd_DRAIN(int, char **); /* not a curses function */
+
+void cmd_addbytes(int, char **);
+void cmd_addch(int, char **);
+void cmd_addchnstr(int, char **);
+void cmd_addchstr(int, char **);
+void cmd_addnstr(int, char **);
+void cmd_addstr(int, char **);
+void cmd_attr_get(int, char **);
+void cmd_attr_off(int, char **);
+void cmd_attr_on(int, char **);
+void cmd_attr_set(int, char **);
+void cmd_attroff(int, char **);
+void cmd_attron(int, char **);
+void cmd_attrset(int, char **);
+void cmd_bkgd(int, char **);
+void cmd_bkgdset(int, char **);
+void cmd_border(int, char **);
+void cmd_clear(int, char **);
+void cmd_clrtobot(int, char **);
+void cmd_clrtoeol(int, char **);
+void cmd_color_set(int, char **);
+void cmd_delch(int, char **);
+void cmd_deleteln(int, char **);
+void cmd_echochar(int, char **);
+void cmd_erase(int, char **);
+void cmd_getch(int, char **);
+void cmd_getnstr(int, char **);
+void cmd_getstr(int, char **);
+void cmd_inch(int, char **);
+void cmd_inchnstr(int, char **);
+void cmd_inchstr(int, char **);
+void cmd_innstr(int, char **);
+void cmd_insch(int, char **);
+void cmd_insdelln(int, char **);
+void cmd_insertln(int, char **);
+void cmd_instr(int, char **);
+void cmd_move(int, char **);
+void cmd_refresh(int, char **);
+void cmd_scrl(int, char **);
+void cmd_setscrreg(int, char **);
+void cmd_standend(int, char **);
+void cmd_standout(int, char **);
+void cmd_timeout(int, char **);
+void cmd_underscore(int, char **);
+void cmd_underend(int, char **);
+void cmd_waddbytes(int, char **);
+void cmd_waddstr(int, char **);
+void cmd_mvaddbytes(int, char **);
+void cmd_mvaddch(int, char **);
+void cmd_mvaddchnstr(int, char **);
+void cmd_mvaddchstr(int, char **);
+void cmd_mvaddnstr(int, char **);
+void cmd_mvaddstr(int, char **);
+void cmd_mvdelch(int, char **);
+void cmd_mvgetch(int, char **);
+void cmd_mvgetnstr(int, char **);
+void cmd_mvgetstr(int, char **);
+void cmd_mvinch(int, char **);
+void cmd_mvinchnstr(int, char **);
+void cmd_mvinchstr(int, char **);
+void cmd_mvinnstr(int, char **);
+void cmd_mvinsch(int, char **);
+void cmd_mvinstr(int, char **);
+
+void cmd_mvwaddbytes(int, char **);
+void cmd_mvwaddch(int, char **);
+void cmd_mvwaddchnstr(int, char **);
+void cmd_mvwaddchstr(int, char **);
+void cmd_mvwaddnstr(int, char **);
+void cmd_mvwaddstr(int, char **);
+void cmd_mvwdelch(int, char **);
+void cmd_mvwgetch(int, char **);
+void cmd_mvwgetnstr(int, char **);
+void cmd_mvwgetstr(int, char **);
+void cmd_mvwinch(int, char **);
+void cmd_mvwinsch(int, char **);
+void cmd_assume_default_colors(int, char **);
+void cmd_baudrate(int, char **);
+void cmd_beep(int, char **);
+void cmd_box(int, char **);
+void cmd_can_change_color(int, char **);
+void cmd_cbreak(int, char **);
+void cmd_chgat(int, char **);
+void cmd_clearok(int, char **);
+void cmd_color_content(int, char **);
+void cmd_copywin(int, char **);
+void cmd_curs_set(int, char **);
+void cmd_def_prog_mode(int, char **);
+void cmd_def_shell_mode(int, char **);
+void cmd_define_key(int, char **);
+void cmd_delay_output(int, char **);
+void cmd_delscreen(int, char **);
+void cmd_delwin(int, char **);
+void cmd_derwin(int, char **);
+void cmd_dupwin(int, char **);
+void cmd_doupdate(int, char **);
+void cmd_echo(int, char **);
+void cmd_endwin(int, char **);
+void cmd_erasechar(int, char **);
+void cmd_flash(int, char **);
+void cmd_flushinp(int, char **);
+void cmd_flushok(int, char **);
+void cmd_fullname(int, char **);
+void cmd_getattrs(int, char **);
+void cmd_getbkgd(int, char **);
+void cmd_getcury(int, char **);
+void cmd_getcurx(int, char **);
+void cmd_getyx(int, char **);
+void cmd_getbegy(int, char **);
+void cmd_getbegx(int, char **);
+void cmd_getmaxy(int, char **);
+void cmd_getmaxx(int, char **);
+void cmd_getpary(int, char **);
+void cmd_getparx(int, char **);
+void cmd_getparyx(int, char **);
+void cmd_gettmode(int, char **);
+void cmd_getwin(int, char **);
+void cmd_halfdelay(int, char **);
+void cmd_has_colors(int, char **);
+void cmd_has_ic(int, char **);
+void cmd_has_il(int, char **);
+void cmd_hline(int, char **);
+void cmd_idcok(int, char **);
+void cmd_idlok(int, char **);
+void cmd_init_color(int, char **);
+void cmd_init_pair(int, char **);
+void cmd_initscr(int, char **);
+void cmd_intrflush(int, char **);
+void cmd_isendwin(int, char **);
+void cmd_is_linetouched(int, char **);
+void cmd_is_wintouched(int, char **);
+void cmd_keyok(int, char **);
+void cmd_keypad(int, char **);
+void cmd_keyname(int, char **);
+void cmd_killchar(int, char **);
+void cmd_leaveok(int, char **);
+void cmd_meta(int, char **);
+void cmd_mvchgat(int, char **);
+void cmd_mvcur(int, char **);
+void cmd_mvderwin(int, char **);
+void cmd_mvhline(int, char **);
+void cmd_mvprintw(int, char **);
+void cmd_mvscanw(int, char **);
+void cmd_mvvline(int, char **);
+void cmd_mvwchgat(int, char **);
+void cmd_mvwhline(int, char **);
+void cmd_mvwvline(int, char **);
+void cmd_mvwin(int, char **);
+void cmd_mvwinchnstr(int, char **);
+void cmd_mvwinchstr(int, char **);
+void cmd_mvwinnstr(int, char **);
+void cmd_mvwinstr(int, char **);
+void cmd_mvwprintw(int, char **);
+void cmd_mvwscanw(int, char **);
+void cmd_napms(int, char **);
+void cmd_newpad(int, char **);
+void cmd_newterm(int, char **);
+void cmd_newwin(int, char **);
+void cmd_nl(int, char **);
+void cmd_no_color_attributes(int, char **);
+void cmd_nocbreak(int, char **);
+void cmd_nodelay(int, char **);
+void cmd_noecho(int, char **);
+void cmd_nonl(int, char **);
+void cmd_noqiflush(int, char **);
+void cmd_noraw(int, char **);
+void cmd_notimeout(int, char **);
+void cmd_overlay(int, char **);
+void cmd_overwrite(int, char **);
+void cmd_pair_content(int, char **);
+void cmd_pechochar(int, char **);
+void cmd_pnoutrefresh(int, char **);
+void cmd_prefresh(int, char **);
+void cmd_printw(int, char **);
+void cmd_putwin(int, char **);
+void cmd_qiflush(int, char **);
+void cmd_raw(int, char **);
+void cmd_redrawwin(int, char **);
+void cmd_reset_prog_mode(int, char **);
+void cmd_reset_shell_mode(int, char **);
+void cmd_resetty(int, char **);
+void cmd_resizeterm(int, char **);
+void cmd_savetty(int, char **);
+void cmd_scanw(int, char **);
+void cmd_scroll(int, char **);
+void cmd_scrollok(int, char **);
+void cmd_setterm(int, char **);
+void cmd_set_term(int, char **);
+void cmd_start_color(int, char **);
+void cmd_subpad(int, char **);
+void cmd_subwin(int, char **);
+void cmd_termattrs(int, char **);
+void cmd_term_attrs(int, char **);
+void cmd_touchline(int, char **);
+void cmd_touchoverlap(int, char **);
+void cmd_touchwin(int, char **);
+void cmd_ungetch(int, char **);
+void cmd_untouchwin(int, char **);
+void cmd_use_default_colors(int, char **);
+void cmd_vline(int, char **);
+void cmd_vw_printw(int, char **);
+void cmd_vw_scanw(int, char **);
+void cmd_vwprintw(int, char **);
+void cmd_vwscanw(int, char **);
+void cmd_waddch(int, char **);
+void cmd_waddchnstr(int, char **);
+void cmd_waddchstr(int, char **);
+void cmd_waddnstr(int, char **);
+void cmd_wattr_get(int, char **);
+void cmd_wattr_off(int, char **);
+void cmd_wattr_on(int, char **);
+void cmd_wattr_set(int, char **);
+void cmd_wattroff(int, char **);
+void cmd_wattron(int, char **);
+void cmd_wattrset(int, char **);
+void cmd_wbkgd(int, char **);
+void cmd_wbkgdset(int, char **);
+void cmd_wborder(int, char **);
+void cmd_wchgat(int, char **);
+void cmd_wclear(int, char **);
+void cmd_wclrtobot(int, char **);
+void cmd_wclrtoeol(int, char **);
+void cmd_wcolor_set(int, char **);
+void cmd_wdelch(int, char **);
+void cmd_wdeleteln(int, char **);
+void cmd_wechochar(int, char **);
+void cmd_werase(int, char **);
+void cmd_wgetch(int, char **);
+void cmd_wgetnstr(int, char **);
+void cmd_wgetstr(int, char **);
+void cmd_whline(int, char **);
+void cmd_winch(int, char **);
+void cmd_winchnstr(int, char **);
+void cmd_winchstr(int, char **);
+void cmd_winnstr(int, char **);
+void cmd_winsch(int, char **);
+void cmd_winsdelln(int, char **);
+void cmd_winsertln(int, char **);
+void cmd_winstr(int, char **);
+void cmd_wmove(int, char **);
+void cmd_wnoutrefresh(int, char **);
+void cmd_wprintw(int, char **);
+void cmd_wredrawln(int, char **);
+void cmd_wrefresh(int, char **);
+void cmd_wresize(int, char **);
+void cmd_wscanw(int, char **);
+void cmd_wscrl(int, char **);
+void cmd_wsetscrreg(int, char **);
+void cmd_wstandend(int, char **);
+void cmd_wstandout(int, char **);
+void cmd_wtimeout(int, char **);
+void cmd_wtouchln(int, char **);
+void cmd_wunderend(int, char **);
+void cmd_wunderscore(int, char **);
+void cmd_wvline(int, char **);
+void cmd_insnstr(int, char **);
+void cmd_insstr(int, char **);
+void cmd_mvinsnstr(int, char **);
+void cmd_mvinsstr(int, char **);
+void cmd_mvwinsnstr(int, char **);
+void cmd_mvwinsstr(int, char **);
+void cmd_winsnstr(int, char **);
+void cmd_winsstr(int, char **);
+
+void cmd_chgat(int, char **);
+void cmd_wchgat(int, char **);
+void cmd_mvchgat(int, char **);
+void cmd_mvwchgat(int, char **);
+void cmd_add_wch(int, char **);
+void cmd_wadd_wch(int, char **);
+void cmd_mvadd_wch(int, char **);
+void cmd_mvwadd_wch(int, char **);
+
+void cmd_add_wchnstr(int, char **);
+void cmd_add_wchstr(int, char **);
+void cmd_wadd_wchnstr(int, char **);
+void cmd_wadd_wchstr(int, char **);
+void cmd_mvadd_wchnstr(int, char **);
+void cmd_mvadd_wchstr(int, char **);
+void cmd_mvwadd_wchnstr(int, char **);
+void cmd_mvwadd_wchstr(int, char **);
+
+void cmd_addnwstr(int, char **);
+void cmd_addwstr(int, char **);
+void cmd_mvaddnwstr(int, char **);
+void cmd_mvaddwstr(int, char **);
+void cmd_mvwaddnwstr(int, char **);
+void cmd_mvwaddwstr(int, char **);
+void cmd_waddnwstr(int, char **);
+void cmd_waddwstr(int, char **);
+
+void cmd_echo_wchar(int, char **);
+void cmd_wecho_wchar(int, char **);
+void cmd_pecho_wchar(int, char **);
+
+/* insert */
+void cmd_ins_wch(int, char **);
+void cmd_wins_wch(int, char **);
+void cmd_mvins_wch(int, char **);
+void cmd_mvwins_wch(int, char **);
+
+void cmd_ins_nwstr(int, char **);
+void cmd_ins_wstr(int, char **);
+void cmd_mvins_nwstr(int, char **);
+void cmd_mvins_wstr(int, char **);
+void cmd_mvwins_nwstr(int, char **);
+void cmd_mvwins_wstr(int, char **);
+void cmd_wins_nwstr(int, char **);
+void cmd_wins_wstr(int, char **);
+
+/* input */
+void cmd_get_wch(int, char **);
+void cmd_unget_wch(int, char **);
+void cmd_mvget_wch(int, char **);
+void cmd_mvwget_wch(int, char **);
+void cmd_wget_wch(int, char **);
+
+void cmd_getn_wstr(int, char **);
+void cmd_get_wstr(int, char **);
+void cmd_mvgetn_wstr(int, char **);
+void cmd_mvget_wstr(int, char **);
+void cmd_mvwgetn_wstr(int, char **);
+void cmd_mvwget_wstr(int, char **);
+void cmd_wgetn_wstr(int, char **);
+void cmd_wget_wstr(int, char **);
+
+void cmd_in_wch(int, char **);
+void cmd_mvin_wch(int, char **);
+void cmd_mvwin_wch(int, char **);
+void cmd_win_wch(int, char **);
+
+void cmd_in_wchnstr(int, char **);
+void cmd_in_wchstr(int, char **);
+void cmd_mvin_wchnstr(int, char **);
+void cmd_mvin_wchstr(int, char **);
+void cmd_mvwin_wchnstr(int, char **);
+void cmd_mvwin_wchstr(int, char **);
+void cmd_win_wchnstr(int, char **);
+void cmd_win_wchstr(int, char **);
+
+void cmd_innwstr(int, char **);
+void cmd_inwstr(int, char **);
+void cmd_mvinnwstr(int, char **);
+void cmd_mvinwstr(int, char **);
+void cmd_mvwinnwstr(int, char **);
+void cmd_mvwinwstr(int, char **);
+void cmd_winnwstr(int, char **);
+void cmd_winwstr(int, char **);
+
+/* cchar handlgin */
+void cmd_setcchar(int, char **);
+void cmd_getcchar(int, char **);
+
+/* misc */
+void cmd_key_name(int, char **);
+void cmd_border_set(int, char **);
+void cmd_wborder_set(int, char **);
+void cmd_box_set(int, char **);
+void cmd_erasewchar(int, char **);
+void cmd_killwchar(int, char **);
+void cmd_hline_set(int, char **);
+void cmd_mvhline_set(int, char **);
+void cmd_mvvline_set(int, char **);
+void cmd_mvwhline_set(int, char **);
+void cmd_mvwvline_set(int, char **);
+void cmd_vline_set(int, char **);
+void cmd_whline_set(int, char **);
+void cmd_wvline_set(int, char **);
+void cmd_bkgrnd(int, char **);
+void cmd_bkgrndset(int, char **);
+void cmd_getbkgrnd(int, char **);
+void cmd_wbkgrnd(int, char **);
+void cmd_wbkgrndset(int, char **);
+void cmd_wgetbkgrnd(int, char **);
+
+
+
+
+#endif /* !_CURSES_COMMAND_H_ */
diff --git a/contrib/netbsd-tests/lib/libcurses/slave/slave.c b/contrib/netbsd-tests/lib/libcurses/slave/slave.c
new file mode 100644
index 0000000..b05a1da
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/slave/slave.c
@@ -0,0 +1,177 @@
+/* $NetBSD: slave.c,v 1.6 2011/09/15 11:46:19 blymn Exp $ */
+
+/*-
+ * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
+ *
+ * All rights reserved.
+ *
+ * This code has been donated to The NetBSD Foundation by the Author.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <curses.h>
+#include "returns.h"
+#include "slave.h"
+
+int cmdpipe[2];
+int slvpipe[2];
+
+#if 0
+static const char *returns_enum_names[] = {
+ "unused", "numeric", "string", "byte", "ERR", "OK", "NULL", "not NULL",
+ "variable"
+};
+#endif
+
+/*
+ * Read the command pipe for the function to execute, gather the args
+ * and then process the command.
+ */
+static void
+process_commands(WINDOW *mainscr)
+{
+ int len, maxlen, argslen, i, ret, type;
+ char *cmdbuf, *tmpbuf, **args, **tmpargs;
+
+ len = maxlen = 30;
+ if ((cmdbuf = malloc(maxlen)) == NULL)
+ err(1, "slave cmdbuf malloc failed");
+
+ while(1) {
+ if (read(cmdpipe[READ_PIPE], &type, sizeof(int)) < 0)
+ err(1, "slave command type read failed");
+
+ if (type != ret_string)
+ errx(1, "Unexpected type for command, got %d", type);
+
+ if (read(cmdpipe[READ_PIPE], &len, sizeof(int)) < 0)
+ err(1, "slave command len read failed");
+
+ if ((len + 1) > maxlen) {
+ maxlen = len + 1;
+ if ((tmpbuf = realloc(cmdbuf, maxlen)) == NULL)
+ err(1, "slave cmdbuf realloc to %d "
+ "bytes failed", maxlen);
+ cmdbuf = tmpbuf;
+ }
+
+ if (read(cmdpipe[READ_PIPE], cmdbuf, len) < 0)
+ err(1, "slave command read failed");
+ cmdbuf[len] = '\0';
+ argslen = 0;
+ args = NULL;
+
+ do {
+ if (read(cmdpipe[READ_PIPE], &type, sizeof(int)) < 0)
+ err(1, "slave arg type read failed");
+
+ if (read(cmdpipe[READ_PIPE], &len, sizeof(int)) < 0)
+ err(1, "slave arg len read failed");
+
+ if (len >= 0) {
+ tmpargs = realloc(args,
+ (argslen + 1) * sizeof(char *));
+ if (tmpargs == NULL)
+ err(1, "slave realloc of args array "
+ "failed");
+
+ args = tmpargs;
+ if (type != ret_null) {
+ args[argslen] = malloc(len + 1);
+
+ if (args[argslen] == NULL)
+ err(1, "slave alloc of %d bytes"
+ " for args failed", len);
+ }
+
+ if (len == 0) {
+ if (type == ret_null)
+ args[argslen] = NULL;
+ else
+ args[argslen][0] = '\0';
+ } else {
+ read(cmdpipe[READ_PIPE], args[argslen],
+ len);
+ if (type != ret_byte)
+ args[argslen][len] = '\0';
+
+ if (len == 6) {
+ if (strcmp(args[argslen],
+ "STDSCR") == 0) {
+ ret = asprintf(&tmpbuf,
+ "%p",
+ stdscr);
+ if (ret < 0)
+ err(2,
+ "asprintf of stdscr failed");
+ free(args[argslen]);
+ args[argslen] = tmpbuf;
+ }
+ }
+ }
+
+ argslen++;
+ }
+ }
+ while(len >= 0);
+
+ command_execute(cmdbuf, argslen, args);
+
+ if (args != NULL) {
+ for (i = 0; i < argslen; i++)
+ free(args[i]);
+
+ free(args);
+ }
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ WINDOW *mainscr;
+
+ if (argc != 5) {
+ fprintf(stderr, "Usage: %s <cmdin> <cmdout> <slvin> slvout>\n",
+ getprogname());
+ return 0;
+ }
+ sscanf(argv[1], "%d", &cmdpipe[0]);
+ sscanf(argv[2], "%d", &cmdpipe[1]);
+ sscanf(argv[3], "%d", &slvpipe[0]);
+ sscanf(argv[4], "%d", &slvpipe[1]);
+
+ mainscr = initscr();
+ if (mainscr == NULL)
+ err(1, "initscr failed");
+
+ process_commands(mainscr);
+
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libcurses/slave/slave.h b/contrib/netbsd-tests/lib/libcurses/slave/slave.h
new file mode 100644
index 0000000..98e9971
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/slave/slave.h
@@ -0,0 +1,50 @@
+/* $NetBSD: slave.h,v 1.3 2011/09/15 11:46:19 blymn Exp $ */
+
+/*-
+ * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
+ *
+ * All rights reserved.
+ *
+ * This code has been donated to The NetBSD Foundation by the Author.
+ *
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ *
+ */
+#ifndef CURTEST_SLAVE_H
+#define CURTEST_SLAVE_H
+
+#include <curses.h>
+
+#define READ_PIPE 0
+#define WRITE_PIPE 1
+
+void command_execute(char *, int, char **);
+void report_count(int);
+void report_error(const char *);
+void report_int(int);
+void report_byte(chtype);
+void report_return(int);
+void report_nstr(chtype *);
+void report_status(const char *);
+void report_ptr(void *);
+int check_arg_count(int, int);
+
+#endif
diff --git a/contrib/netbsd-tests/lib/libcurses/t_curses.sh b/contrib/netbsd-tests/lib/libcurses/t_curses.sh
new file mode 100755
index 0000000..5ff9474
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/t_curses.sh
@@ -0,0 +1,294 @@
+
+h_run()
+{
+ file="$(atf_get_srcdir)/tests/${1}"
+
+ export COLUMNS=80
+ export LINES=24
+ $(atf_get_srcdir)/director \
+ -T $(atf_get_srcdir) \
+ -t atf \
+ -I $(atf_get_srcdir)/tests \
+ -C $(atf_get_srcdir)/check_files \
+ -s $(atf_get_srcdir)/slave $file || atf_fail "test ${file} failed"
+}
+
+atf_test_case startup
+startup_head()
+{
+ atf_set "descr" "Checks curses initialisation sequence"
+}
+startup_body()
+{
+ h_run start
+}
+
+atf_test_case addch
+addch_head()
+{
+ atf_set "descr" "Tests adding a chtype to stdscr"
+}
+addch_body()
+{
+ h_run addch
+}
+
+atf_test_case addchstr
+addchstr_head()
+{
+ atf_set "descr" "Tests adding a chtype string to stdscr"
+}
+addchstr_body()
+{
+ h_run addchstr
+}
+
+atf_test_case addchnstr
+addchnstr_head()
+{
+ atf_set "descr" "Tests adding bytes from a chtype string to stdscr"
+}
+addchnstr_body()
+{
+ h_run addchnstr
+}
+
+atf_test_case addstr
+addstr_head()
+{
+ atf_set "descr" "Tests adding bytes from a string to stdscr"
+}
+addstr_body()
+{
+ h_run addstr
+}
+
+atf_test_case addnstr
+addnstr_head()
+{
+ atf_set "descr" "Tests adding bytes from a string to stdscr"
+}
+addnstr_body()
+{
+ h_run addnstr
+}
+
+atf_test_case getch
+getch_head()
+{
+ atf_set "descr" "Checks reading a character input"
+}
+getch_body()
+{
+ h_run getch
+}
+
+atf_test_case timeout
+timeout_head()
+{
+ atf_set "descr" "Checks timeout when reading a character"
+}
+timeout_body()
+{
+ h_run timeout
+}
+
+atf_test_case window
+window_head()
+{
+ atf_set "descr" "Checks window creation"
+}
+window_body()
+{
+ h_run window
+}
+
+atf_test_case wborder
+wborder_head()
+{
+ atf_set "descr" "Checks drawing a border around a window"
+}
+wborder_body()
+{
+ h_run wborder
+}
+
+atf_test_case box
+box_head()
+{
+ atf_set "descr" "Checks drawing a box around a window"
+}
+box_body()
+{
+ h_run box
+}
+
+atf_test_case wprintw
+wprintw_head()
+{
+ atf_set "descr" "Checks printing to a window"
+}
+wprintw_body()
+{
+ h_run wprintw
+}
+
+atf_test_case wscrl
+wscrl_head()
+{
+ atf_set "descr" "Check window scrolling"
+}
+wscrl_body()
+{
+ h_run wscrl
+}
+
+atf_test_case mvwin
+mvwin_head()
+{
+ atf_set "descr" "Check moving a window"
+}
+mvwin_body()
+{
+ h_run mvwin
+}
+
+atf_test_case getstr
+getstr_head()
+{
+ atf_set "descr" "Check getting a string from input"
+}
+getstr_body()
+{
+ h_run getstr
+}
+
+atf_test_case termattrs
+termattrs_head()
+{
+ atf_set "descr" "Check the terminal attributes"
+}
+termattrs_body()
+{
+ h_run termattrs
+}
+
+atf_test_case assume_default_colors
+assume_default_colors_head()
+{
+ atf_set "descr" "Check setting the default color pair"
+}
+assume_default_colors_body()
+{
+ h_run assume_default_colors
+}
+
+atf_test_case attributes
+attributes_head()
+{
+ atf_set "descr" "Check setting, clearing and getting of attributes"
+}
+attributes_body()
+{
+ h_run attributes
+}
+
+atf_test_case beep
+beep_head()
+{
+ atf_set "descr" "Check sending a beep"
+}
+beep_body()
+{
+ h_run beep
+}
+
+atf_test_case background
+background_head()
+{
+ atf_set "descr" "Check setting background character and attributes for both stdscr and a window."
+}
+background_body()
+{
+ h_run background
+}
+
+atf_test_case can_change_color
+can_change_color_head()
+{
+ atf_set "descr" "Check if the terminal can change colours"
+}
+can_change_color_body()
+{
+ h_run can_change_color
+}
+
+atf_test_case cbreak
+cbreak_head()
+{
+ atf_set "descr" "Check cbreak mode works"
+}
+cbreak_body()
+{
+ h_run cbreak
+}
+
+atf_test_case clear
+clear_head()
+{
+ atf_set "descr" "Check clear and erase work"
+}
+clear_body()
+{
+ h_run clear
+}
+
+atf_test_case copywin
+copywin_head()
+{
+ atf_set "descr" "Check all the modes of copying a window work"
+}
+copywin_body()
+{
+ h_run copywin
+}
+
+atf_test_case curs_set
+curs_set_head()
+{
+ atf_set "descr" "Check setting the cursor visibility works"
+}
+curs_set_body()
+{
+ h_run curs_set
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case startup
+ atf_add_test_case addch
+ atf_add_test_case addchstr
+ atf_add_test_case addchnstr
+ atf_add_test_case addstr
+ atf_add_test_case addnstr
+ atf_add_test_case getch
+ atf_add_test_case timeout
+ atf_add_test_case window
+ atf_add_test_case wborder
+ atf_add_test_case box
+ atf_add_test_case wprintw
+ atf_add_test_case wscrl
+ atf_add_test_case mvwin
+ atf_add_test_case getstr
+ atf_add_test_case termattrs
+ atf_add_test_case can_change_color
+ atf_add_test_case assume_default_colors
+ atf_add_test_case attributes
+# atf_add_test_case beep # comment out for now - return is wrong
+ atf_add_test_case background
+ atf_add_test_case cbreak
+ atf_add_test_case clear
+ atf_add_test_case copywin
+ atf_add_test_case curs_set
+}
+
diff --git a/contrib/netbsd-tests/lib/libcurses/testframe.txt b/contrib/netbsd-tests/lib/libcurses/testframe.txt
new file mode 100644
index 0000000..19884d7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/testframe.txt
@@ -0,0 +1,241 @@
+
+CURSES TESTFRAME
+----------------
+
+1. Introduction
+
+The curses library is a complex piece of software and, often, changes
+made to the library may introduce subtle bugs that are hidden by other
+actions so a visual check of the curses output may look correct in
+some circumstances and the bug only show itself after a certain
+sequence of actions. To assist with validating that changes made to
+the curses library have no undesired effects an automated test is
+needed to detect and highlight any changes in the curses application
+output stream. The programmer can then analyse the output changes and
+either correct a bug or update the automated test to accept the new
+output as valid.
+
+2. Architecture
+
+The curses testframe consists of two separate programs connected by a
+number of pipes and a pseudo-tty (pty). The programs are called the
+director and the slave. The director reads a configuration file of
+tests to perform, passes these commands to the slave over a pipe and
+reads the pty for any output from the slave. Data from the slave is
+compared against expected output held in a file and any differences
+are highlighted to the tester. The slave is a curses application that
+is forked by the director on start up. It reads commands from the
+director over a pipe, these commands are calls to curses routines
+along with the parameters required for the call. The slave takes the
+parameters and uses them as arguments for the requested curses routine
+call. The return value from the curses routine is passed back to the
+director over another pipe, if the curses routine updates any passed
+by reference arguments then these are also passed back to the director
+for analysis.
+
+3. Director
+
+The director has the following optional command line options:
+
+ -v enables verbose output to assist debugging
+ -s slave_path the director will execute slave_path as the slave
+ process. The default is ./slave
+ -t term Sets the TERM environment variable to term when
+ executing the slave. The default is atf
+
+There is one mandatory command line parameter, that is a file name
+that contains the test command file. The test command file holds the
+calls required to exercise a particular curses routine and validate
+both the return codes from the routines and the output from the
+slave. The test language has a small number of commands, they are:
+
+assign:
+ Assign a value to a variable. The syntax is:
+
+ assign var_name value
+
+ Where var_name is the name of the variable. Variable names are
+ an arbitrary sequence of alphanumeric characters, the variable
+ name must start with an alphabetic character. Value is the value
+ to be assigned. The value can either be a numeric or a string
+ type. Variables are created on first use and will be
+ overwritten on each subsequent use.
+
+call, call2, call3, call4:
+ All these are used to call curses routines, the only difference
+ between then is the number of expected return values. Call
+ expects one return value, call2 expects 2, call3 expects 3 and
+ call4 expects four. Any parameters that are passed by reference
+ and updated by the call are treated like returns. So, for
+ example, calling the function getyx() which has three
+ parameters, the window, a pointer to storage for y and a pointer
+ to storage for x would be called like this:
+
+ call3 OK 4 5 getyx $win1
+
+ Which calls getyx, the first (and possibly only) return is the
+ return status of the function call, in this case we expect "OK"
+ indicating that the call succeeded. The next two returns are
+ the values of y and x respectively, the parameter $win1 is a
+ variable that was assigned by a previous call. Any return can
+ be assigned to a variable by including the variable name in a
+ call return list. Variables are referenced in a call parameter
+ list by prefixing the name with a $ character. All returns are
+ validated against the expected values and an error raised if
+ there is a mismatch. The only exception to this is when the
+ return is assigned to a variable. Valid values for the returns
+ list are:
+
+ variable - assign the return to the given variable
+ name.
+ numeric - the value of the return must match the
+ number given.
+ string - an arbitrary sequence of characters
+ enclosed in double quotes.
+ ERR - expect an ERR return
+ OK - expect an OK return
+ NULL - expect a NULL pointer return
+ NON_NULL - expect a pointer that is not NULL valued
+
+ There is one special parameter that can be passed to a call,
+ that is the label STDSCR. This parameter will be substituted by
+ the value of stdscr when the function call is made.
+
+check:
+ Validate the value of a variable. This allows a variable to be
+ checked for an expected return after it has been assigned in a
+ previous call. The syntax is:
+
+ check var_name expected_result
+
+ Where var_name is a variable previously assigned and
+ expected_result is one of the valid return values listed in the
+ above call section.
+
+compare:
+ Compares the output stream from the slave against the contents
+ of a file that contains the expected
+ output. The syntax is:
+
+ compare filename
+
+ Where filename is the name of the file containing the expected
+ output. The file can either be an absolute path or relative
+ path. In the latter case the value of the environment variable
+ CHECK_PATH will be prepended to the argument to provide the path
+ to the file. The contents of this file will be compared byte by
+ byte against the output from the slave, any differences in the
+ output will be flagged. If the director is not in verbose mode
+ then the first mismatch in the byte stream will cause the
+ director to exit.
+
+comparend:
+ Performs the same function as the above compare except that
+ excess output from the slave is not discarded if there is more
+ data from the slave than there is in the check file. This
+ allows chaining of multiple check files.
+
+delay:
+ Defines an inter-character delay to be inserted between
+ characters being fed into the input of the slave. The syntax
+ is:
+
+ delay time
+
+ Where time is the amount of time to delay in milliseconds.
+
+include:
+ Include the contents of another test file, the parser will
+ suspend reading the current file and read commands from the
+ include file until the end of file of the include file is
+ reached at which point it will continue reading the original
+ file. Include files may be nested. The syntax is:
+
+ include filename
+
+ Where filename is the name of the file to include. If the
+ filename is not an absolute path then the contents of the
+ environment variable INCLUDE_PATH are prepended to the file
+ name.
+
+input:
+ Defines a string of characters that will be fed to the slave
+ when a call requires input. Any unused input will be discarded
+ after the call that required the input is called. The syntax
+ is:
+
+ input "string to pass"
+
+noinput:
+ Normally the director will error if an input function is called
+ without input being previously defined, this is to prevent input
+ functions causing the test to hang waiting for input that never
+ comes. If it is known that there is pending input for the slave
+ then the noinput keyword can be used to flag that the input
+ function has data available for it to read. The noinput command
+ only applies to the next function call then behaviour reverts to
+ the default.
+
+The testframe can define different types of strings, the type of string
+depends on the type of enclosing quotes. A null terminated string is
+indicated by enclosing double (") quotes. A byte string, one that is
+not null terminated and may contain the nul character within it is
+indicated by enclosing single (') quotes. A string of chtype
+character which are a combined attribute and character value is
+indicated by enclosing backticks (`), for this type of string pairs of
+bytes between the backticks are converted to an array of chtype, the
+first byte is the attribute and the second is the character.
+
+All strings defined will have a simple set of character substitutions
+performed on them when they are parsed. This allows the tester to
+embed some control characters into the string. Valid substitutions
+are:
+
+ \e escape
+ \n new line
+ \r carriage return
+ \t tab
+ \\ \ character
+ \nnn Where nnn is three octal digits, the character
+ represented by the octal number will be inserted into
+ the string.
+
+Any other invalid conversions will have the \ stripped and the
+subsequent characters inserted into the string.
+
+Integers may be specified by either a plain numeric (e.g. 12345) or by
+hexadecimal notation by prefixing the number with 0x (e.g. 0x3039).
+Internally, no distinction is made between the two formats and they
+can be freely intermixed.
+
+Integers and variables containing integers can have operations
+performed on them. Currently only bitwise ORing numbers together is
+supported. This can be done by separating a list of integers and
+variables with the pipe (|) symbol and enclosing the entire list in
+round brackets "()" like this:
+
+ ( $var1 | 0x0100 | $var2 | 512 )
+
+Variables and integer constants may be freely intermixed. The result
+of the operation can either be used as an argument for a call or can
+be used as an expected result for a call.
+
+In addition to all the curses calls being supported by the slave,
+there is one more special call called "drain". This call repeatedly
+called getch() until there are no more characters in stdin. The call
+assumes that the curses input is either in no delay or timed input
+mode otherwise the test will time out and fail. This call can be used
+to clear any pending input when testing testing a timed read to
+prevent the input being used in a later test.
+
+4. Slave
+
+The user has no direct interaction with the slave process. The slave
+is forked off by the director communicates to the director over a set
+of pipes and a pseudo-tty connected to its standard i/o file
+descriptors. The slave executes the passed curses calls and passes
+back return values to the director. The slave automatically calls
+initscr() on start up.
+
+
+
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addch b/contrib/netbsd-tests/lib/libcurses/tests/addch
new file mode 100644
index 0000000..a67e385
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/addch
@@ -0,0 +1,4 @@
+include start
+call OK addch `\001t`
+call OK refresh
+compare addch.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addchnstr b/contrib/netbsd-tests/lib/libcurses/tests/addchnstr
new file mode 100644
index 0000000..661bf74
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/addchnstr
@@ -0,0 +1,5 @@
+include start
+# note that there are more characters in the array, check we only get 5 out
+call OK addchnstr `\004a\004b\004c\004d\004e\004f\004g` 5
+call OK refresh
+compare addchstr.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addchstr b/contrib/netbsd-tests/lib/libcurses/tests/addchstr
new file mode 100644
index 0000000..4ccf7b8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/addchstr
@@ -0,0 +1,4 @@
+include start
+call OK addchstr `\004a\004b\004c\004d\004e`
+call OK refresh
+compare addchstr.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addnstr b/contrib/netbsd-tests/lib/libcurses/tests/addnstr
new file mode 100644
index 0000000..9c40801
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/addnstr
@@ -0,0 +1,5 @@
+include start
+call OK addnstr "abcdefg" 5
+call OK refresh
+# should be the same as addstr
+compare addstr.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/addstr b/contrib/netbsd-tests/lib/libcurses/tests/addstr
new file mode 100644
index 0000000..8c1d24f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/addstr
@@ -0,0 +1,4 @@
+include start
+call OK addstr "abcde"
+call OK refresh
+compare addstr.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/assume_default_colors b/contrib/netbsd-tests/lib/libcurses/tests/assume_default_colors
new file mode 100644
index 0000000..b6ccb09
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/assume_default_colors
@@ -0,0 +1,19 @@
+include start
+call OK start_color
+call OK assume_default_colors -1 -1
+call OK refresh
+compare color_start.chk
+# This should be the same as the default
+compare color_default.chk
+# default foreground, blue background
+call OK assume_default_colors -1 $COLOR_BLUE
+call OK refresh
+compare color_blue_back.chk
+# red foreground, default background
+call OK assume_default_colors $COLOR_RED -1
+call OK refresh
+compare color_red_fore.chk
+# back to default
+call OK assume_default_colors -1 -1
+call OK refresh
+compare color_default.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/attributes b/contrib/netbsd-tests/lib/libcurses/tests/attributes
new file mode 100644
index 0000000..b75d7d1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/attributes
@@ -0,0 +1,23 @@
+include start
+# no attributes, no color
+call3 OK 0 0 attr_get
+# set reverse and bold
+call OK attr_set ($BOLD | $REVERSE) 2
+# returned attributes includes color information
+call3 OK ($ACS_IS_WACS | $BOLD | $REVERSE) 2 attr_get
+# turn off reverse
+call OK attr_off $REVERSE
+call3 OK ($ACS_IS_WACS | $BOLD) 2 attr_get
+# turn on standout
+call OK attr_on $STANDOUT
+call3 OK ($ACS_IS_WACS | $BOLD | $STANDOUT) 2 attr_get
+# turn on blink
+call OK attron $BLINK
+call3 OK ($ACS_IS_WACS | $BOLD | $STANDOUT | $BLINK) 2 attr_get
+# turn off bold
+call OK attroff $BOLD
+call3 OK ($ACS_IS_WACS | $STANDOUT | $BLINK) 2 attr_get
+# print out something to check our attributes are there, standout and blink
+call OK printw "%s" "hello"
+call OK refresh
+compare attributes.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/background b/contrib/netbsd-tests/lib/libcurses/tests/background
new file mode 100644
index 0000000..2c4a575
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/background
@@ -0,0 +1,23 @@
+include start
+call OK bkgd `\002A`
+call OK refresh
+# looks like a bug - bottom right char not filled
+compare background1.chk
+call OK printw "%s" "a test string"
+call OK refresh
+compare background2.chk
+call win1 newwin 6 6 2 5
+check win1 NON_NULL
+call OK wprintw $win1 "%s" "window 1"
+# call OK refresh
+call OK wrefresh $win1
+compare background3.chk
+call OK wbkgd $win1 `\004B`
+call OK refresh
+call OK wrefresh $win1
+compare background4.chk
+call OK wprintw $win1 "%s" "hello world"
+call OK refresh
+call OK wrefresh $win1
+compare background5.chk
+
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/beep b/contrib/netbsd-tests/lib/libcurses/tests/beep
new file mode 100644
index 0000000..832e87f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/beep
@@ -0,0 +1,5 @@
+include start
+# SUSv2 says this should return OK but we return 1
+call 1 beep
+call OK refresh
+compare bell.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/box b/contrib/netbsd-tests/lib/libcurses/tests/box
new file mode 100644
index 0000000..bfd2e12
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/box
@@ -0,0 +1,8 @@
+include window
+call OK box $win1 `\000` `\000`
+call OK wrefresh $win1
+# default settings of box will output same as wborder
+compare wborder.chk
+call OK box $win1 `\001\000` `\004\000`
+call OK wrefresh $win1
+compare box_standout.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/can_change_color b/contrib/netbsd-tests/lib/libcurses/tests/can_change_color
new file mode 100644
index 0000000..aed622a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/can_change_color
@@ -0,0 +1,3 @@
+include start
+# our test terminal can change colors so expect true.
+call 1 can_change_color
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/cbreak b/contrib/netbsd-tests/lib/libcurses/tests/cbreak
new file mode 100644
index 0000000..b8bf60e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/cbreak
@@ -0,0 +1,18 @@
+include start
+# setting noecho stops getch setting cbreak itself so we should need
+# a newline before getch returns, check this works first.
+call OK noecho
+input "abcd\n"
+call 0x61 getch
+noinput
+call 0x62 getch
+noinput
+call 0x63 getch
+noinput
+call 0x64 getch
+noinput
+call 0x0a getch
+# set cbreak, getch should return without needing a newline
+input "ef"
+call OK cbreak
+call 0x65 getch
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/chgat b/contrib/netbsd-tests/lib/libcurses/tests/chgat
new file mode 100644
index 0000000..863ab11
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/chgat
@@ -0,0 +1,15 @@
+include start_color
+call OK init_pair 3 $COLOR_YELLOW $COLOR_CYAN
+call OK addch `\000d`
+call OK chgat 5 $REVERSE 3 0
+call OK refresh
+compare chgat1.chk
+call OK addch `\000e`
+call OK refresh
+compare chgat2.chk
+call OK move 0 0
+# The following should apply the attribute and colour to the whole line
+call OK chgat -1 $UNDERSCORE 3 0
+call OK refresh
+compare chgat3.chk
+
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/clear b/contrib/netbsd-tests/lib/libcurses/tests/clear
new file mode 100644
index 0000000..5aad934
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/clear
@@ -0,0 +1,57 @@
+include addstr
+call OK clear
+call OK refresh
+compare clear1.chk
+call OK move 5 5
+call OK addstr "abcde"
+call OK move 20 5
+call OK addstr "fghij"
+call OK move 10 5
+call OK refresh
+compare clear2.chk
+call OK clrtobot
+call OK refresh
+compare clear3.chk
+call OK erase
+call OK refresh
+compare clear4.chk
+include fill_screen
+compare fill.chk
+call OK erase
+call OK refresh
+compare clear5.chk
+# create a window to play with, defines win1 var
+include window_create
+call OK waddstr $win1 "abc"
+call OK mvwaddstr $win1 4 1 "efg"
+call OK wmove $win1 1 0
+call OK wrefresh $win1
+compare clear6.chk
+call OK wclrtobot $win1
+call OK wrefresh $win1
+compare clear7.chk
+include fill_screen
+comparend home.chk
+compare fill.chk
+call OK wrefresh $win1
+call OK wclear $win1
+call OK wrefresh $win1
+compare clear8.chk
+call OK clear
+call OK refresh
+compare clear1.chk
+include fill_screen
+compare fill.chk
+call OK werase $win1
+call OK wrefresh $win1
+compare clear9.chk
+call OK waddstr $win1 "abc"
+call OK mvwaddstr $win1 4 1 "efg"
+call OK wmove $win1 1 0
+call OK wrefresh $win1
+compare clear6.chk
+call OK wmove $win1 4 0
+call OK wclrtoeol $win1
+call OK wrefresh $win1
+compare clear10.chk
+
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/color_content b/contrib/netbsd-tests/lib/libcurses/tests/color_content
new file mode 100644
index 0000000..0db66e5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/color_content
@@ -0,0 +1,12 @@
+include start
+call OK start_color
+call4 OK 0 0 0 color_content $COLOR_BLACK
+call4 OK 1000 0 0 color_content $COLOR_RED
+call4 OK 0 1000 0 color_content $COLOR_GREEN
+call4 OK 1000 1000 0 color_content $COLOR_YELLOW
+call4 OK 0 0 1000 color_content $COLOR_BLUE
+call4 OK 1000 0 1000 color_content $COLOR_MAGENTA
+call4 OK 0 1000 1000 color_content $COLOR_CYAN
+call4 OK 1000 1000 1000 color_content $COLOR_WHITE
+
+
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/color_set b/contrib/netbsd-tests/lib/libcurses/tests/color_set
new file mode 100644
index 0000000..07cd1c5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/color_set
@@ -0,0 +1,11 @@
+include start
+call OK start_color
+call OK refresh
+comparend color_start.chk
+compare color_blank_draw.chk
+call OK init_pair 4 $COLOR_RED $COLOR_GREEN
+call OK color_set 4 0
+call OK printw "%s" "testing"
+call OK refresh
+compare color_set.chk
+
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/copywin b/contrib/netbsd-tests/lib/libcurses/tests/copywin
new file mode 100644
index 0000000..2dbec40
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/copywin
@@ -0,0 +1,81 @@
+include start
+include window_create
+call win2 newwin 7 9 10 14
+check win2 NON_NULL
+call OK wrefresh $win2
+compare copywin1.chk
+call OK mvwprintw $win1 0 0 "%s" "testin"
+call OK mvwprintw $win1 1 0 "%s" "gtesti"
+call OK mvwprintw $win1 2 0 "%s" "ngtest"
+call OK mvwprintw $win1 3 0 "%s" "ingtes"
+call OK mvwprintw $win1 4 0 "%s" "tingte"
+call OK mvwprintw $win1 5 0 "%s" "stingt"
+call OK wrefresh $win1
+compare copywin2.chk
+call OK copywin $win1 $win2 0 0 1 1 7 7 0
+call OK wrefresh $win2
+compare copywin3.chk
+call OK wclear $win1
+call OK wclear $win2
+call OK wrefresh $win1
+call OK wrefresh $win2
+compare copywin4.chk
+call OK mvwprintw $win2 0 0 "%s" "testingte"
+call OK mvwprintw $win2 1 0 "%s" "stingtest"
+call OK mvwprintw $win2 2 0 "%s" "ingtestin"
+call OK mvwprintw $win2 3 0 "%s" "gtestingt"
+call OK mvwprintw $win2 4 0 "%s" "estingtes"
+call OK mvwprintw $win2 5 0 "%s" "tingtesti"
+call OK wrefresh $win2
+compare copywin5.chk
+call OK copywin $win2 $win1 0 0 0 0 7 9 0
+call OK wrefresh $win1
+compare copywin6.chk
+call OK wclear $win1
+call OK wclear $win2
+call OK wrefresh $win1
+call OK wrefresh $win2
+compare copywin7.chk
+call OK mvwprintw $win1 0 0 "%s" "t s i "
+call OK mvwprintw $win1 1 0 "%s" "g e t "
+call OK mvwprintw $win1 2 0 "%s" "n t s "
+call OK mvwprintw $win1 3 0 "%s" " n t s"
+call OK mvwprintw $win1 4 0 "%s" "t n t "
+call OK mvwprintw $win1 5 0 "%s" " t n t"
+call OK wrefresh $win1
+compare copywin8.chk
+call OK mvwprintw $win2 0 0 "%s" " e t n"
+call OK mvwprintw $win2 1 0 "%s" " t s i"
+call OK mvwprintw $win2 2 0 "%s" " g e t"
+call OK mvwprintw $win2 3 0 "%s" "i g e "
+call OK mvwprintw $win2 4 0 "%s" " i g e"
+call OK mvwprintw $win2 5 0 "%s" "s i g "
+call OK wrefresh $win2
+compare copywin9.chk
+call OK copywin $win1 $win2 0 0 0 0 6 6 0
+call OK wrefresh $win2
+compare copywin10.chk
+call OK wclear $win1
+call OK wclear $win2
+call OK wrefresh $win1
+call OK wrefresh $win2
+compare copywin11.chk
+call OK mvwprintw $win1 0 0 "%s" "t s i "
+call OK mvwprintw $win1 1 0 "%s" "g e t "
+call OK mvwprintw $win1 2 0 "%s" "n t s "
+call OK mvwprintw $win1 3 0 "%s" " n t s"
+call OK mvwprintw $win1 4 0 "%s" "t n t "
+call OK mvwprintw $win1 5 0 "%s" " t n t"
+call OK wrefresh $win1
+compare copywin12.chk
+call OK mvwprintw $win2 0 0 "%s" " e t n"
+call OK mvwprintw $win2 1 0 "%s" " t s i"
+call OK mvwprintw $win2 2 0 "%s" " g e t"
+call OK mvwprintw $win2 3 0 "%s" "i g e "
+call OK mvwprintw $win2 4 0 "%s" " i g e"
+call OK mvwprintw $win2 5 0 "%s" "s i g "
+call OK wrefresh $win2
+compare copywin13.chk
+call OK copywin $win1 $win2 0 0 0 0 6 6 1
+call OK wrefresh $win2
+compare copywin14.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/curs_set b/contrib/netbsd-tests/lib/libcurses/tests/curs_set
new file mode 100644
index 0000000..5d7cb54
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/curs_set
@@ -0,0 +1,7 @@
+include start
+call 2 curs_set 0
+compare curs_set1.chk
+call 0 curs_set 1
+compare curs_set2.chk
+call 1 curs_set 2
+compare curs_set3.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/fill_screen b/contrib/netbsd-tests/lib/libcurses/tests/fill_screen
new file mode 100644
index 0000000..b9e2942
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/fill_screen
@@ -0,0 +1,29 @@
+#
+# Fill the screen with characters. We don't do a compare in here because
+# this is meant to be included from other tests which could result in random
+# cursor motions before the fill is done.
+#
+call OK mvaddstr 0 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 1 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 2 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 3 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 4 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 5 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 6 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 7 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 8 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 9 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 10 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 11 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 12 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 13 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 14 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 15 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 16 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 17 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 18 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 19 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 20 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 21 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK mvaddstr 22 0 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
+call OK refresh
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/getch b/contrib/netbsd-tests/lib/libcurses/tests/getch
new file mode 100644
index 0000000..9f437f5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/getch
@@ -0,0 +1,3 @@
+include start
+input "i"
+call 105 getch
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/getstr b/contrib/netbsd-tests/lib/libcurses/tests/getstr
new file mode 100644
index 0000000..320325f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/getstr
@@ -0,0 +1,6 @@
+include window
+input "input\n"
+call2 OK "input" wgetstr $win1
+compare wgetstr.chk
+call OK wrefresh $win1
+compare wgetstr_refresh.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/mvwin b/contrib/netbsd-tests/lib/libcurses/tests/mvwin
new file mode 100644
index 0000000..86d9bd6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/mvwin
@@ -0,0 +1,12 @@
+include window
+call OK wmove $win1 1 1
+call OK wprintw $win1 "%s" "xxxx"
+call OK wrefresh $win1
+compare /dev/zero
+call OK refresh
+compare /dev/zero
+call OK mvwin $win1 4 7
+call OK wrefresh $win1
+compare /dev/zero
+call OK refresh
+compare /dev/zero
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/start b/contrib/netbsd-tests/lib/libcurses/tests/start
new file mode 100644
index 0000000..963f2f4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/start
@@ -0,0 +1,3 @@
+include std_defines
+call OK refresh
+compare curses_start.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/start_color b/contrib/netbsd-tests/lib/libcurses/tests/start_color
new file mode 100644
index 0000000..6d3f133
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/start_color
@@ -0,0 +1,5 @@
+include start
+call OK start_color
+call OK refresh
+comparend color_start.chk
+compare color_blank_draw.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/std_defines b/contrib/netbsd-tests/lib/libcurses/tests/std_defines
new file mode 100644
index 0000000..9c986df
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/std_defines
@@ -0,0 +1,138 @@
+#
+# Define some standard symbols for curses so tests can reference things
+# symbolically instead of using magic numbers.
+#
+#
+# boolean
+#
+assign TRUE 0x01
+assign FALSE 0x00
+#
+# colours
+#
+assign COLOR_BLACK 0x00
+assign COLOR_RED 0x01
+assign COLOR_GREEN 0x02
+assign COLOR_YELLOW 0x03
+assign COLOR_BLUE 0x04
+assign COLOR_MAGENTA 0x05
+assign COLOR_CYAN 0x06
+assign COLOR_WHITE 0x07
+#
+# Attributes
+#
+assign NORMAL 0x00000000
+assign STANDOUT 0x00000100
+assign UNDERSCORE 0x00000200
+assign REVERSE 0x00000400
+assign BLINK 0x00000800
+assign DIM 0x00001000
+assign BOLD 0x00002000
+assign BLANK 0x00004000
+assign PROTECT 0x00008000
+assign ALTCHARSET 0x00010000
+assign ACS_IS_WACS 0x00040000
+#
+# Keys
+#
+assign KEY_BREAK 0x101
+assign KEY_DOWN 0x102
+assign KEY_UP 0x103
+assign KEY_LEFT 0x104
+assign KEY_RIGHT 0x105
+assign KEY_HOME 0x106
+assign KEY_BACKSPACE 0x107
+assign KEY_F0 0x108
+assign KEY_F1 0x109
+assign KEY_F2 0x10a
+assign KEY_F3 0x10b
+assign KEY_F4 0x10c
+assign KEY_F5 0x10d
+assign KEY_F6 0x10e
+assign KEY_F7 0x10f
+assign KEY_F8 0x110
+assign KEY_F9 0x111
+assign KEY_DL 0x148
+assign KEY_IL 0x149
+assign KEY_DC 0x14A
+assign KEY_IC 0x14B
+assign KEY_EIC 0x14C
+assign KEY_CLEAR 0x14D
+assign KEY_EOS 0x14E
+assign KEY_EOL 0x14F
+assign KEY_SF 0x150
+assign KEY_SR 0x151
+assign KEY_NPAGE 0x152
+assign KEY_PPAGE 0x153
+assign KEY_STAB 0x154
+assign KEY_CTAB 0x155
+assign KEY_CATAB 0x156
+assign KEY_ENTER 0x157
+assign KEY_SRESET 0x158
+assign KEY_RESET 0x159
+assign KEY_PRINT 0x15A
+assign KEY_LL 0x15B
+assign KEY_A1 0x15C
+assign KEY_A3 0x15D
+assign KEY_B2 0x15E
+assign KEY_C1 0x15F
+assign KEY_C3 0x160
+assign KEY_BTAB 0x161
+assign KEY_BEG 0x162
+assign KEY_CANCEL 0x163
+assign KEY_CLOSE 0x164
+assign KEY_COMMAND 0x165
+assign KEY_COPY 0x166
+assign KEY_CREATE 0x167
+assign KEY_END 0x168
+assign KEY_EXIT 0x169
+assign KEY_FIND 0x16A
+assign KEY_HELP 0x16B
+assign KEY_MARK 0x16C
+assign KEY_MESSAGE 0x16D
+assign KEY_MOVE 0x16E
+assign KEY_NEXT 0x16F
+assign KEY_OPEN 0x170
+assign KEY_OPTIONS 0x171
+assign KEY_PREVIOUS 0x172
+assign KEY_REDO 0x173
+assign KEY_REFERENCE 0x174
+assign KEY_REFRESH 0x175
+assign KEY_REPLACE 0x176
+assign KEY_RESTART 0x177
+assign KEY_RESUME 0x178
+assign KEY_SAVE 0x179
+assign KEY_SBEG 0x17A
+assign KEY_SCANCEL 0x17B
+assign KEY_SCOMMAND 0x17C
+assign KEY_SCOPY 0x17D
+assign KEY_SCREATE 0x17E
+assign KEY_SDC 0x17F
+assign KEY_SDL 0x180
+assign KEY_SELECT 0x181
+assign KEY_SEND 0x182
+assign KEY_SEOL 0x183
+assign KEY_SEXIT 0x184
+assign KEY_SFIND 0x185
+assign KEY_SHELP 0x186
+assign KEY_SHOME 0x187
+assign KEY_SIC 0x188
+assign KEY_SLEFT 0x189
+assign KEY_SMESSAGE 0x18A
+assign KEY_SMOVE 0x18B
+assign KEY_SNEXT 0x18C
+assign KEY_SOPTIONS 0x18D
+assign KEY_SPREVIOUS 0x18E
+assign KEY_SPRINT 0x18F
+assign KEY_SREDO 0x190
+assign KEY_SREPLACE 0x191
+assign KEY_SRIGHT 0x192
+assign KEY_SRSUME 0x193
+assign KEY_SSAVE 0x194
+assign KEY_SSUSPEND 0x195
+assign KEY_SUNDO 0x196
+assign KEY_SUSPEND 0x197
+assign KEY_UNDO 0x198
+assign KEY_MOUSE 0x199
+assign KEY_RESIZE 0x200
+
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/termattrs b/contrib/netbsd-tests/lib/libcurses/tests/termattrs
new file mode 100644
index 0000000..1025301
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/termattrs
@@ -0,0 +1,3 @@
+include start
+# the atf terminal can do all attributes except PROTECT
+call 0x17f00 termattrs
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/timeout b/contrib/netbsd-tests/lib/libcurses/tests/timeout
new file mode 100644
index 0000000..1adf057
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/timeout
@@ -0,0 +1,21 @@
+#
+# Validate the timeout works.
+#
+include start
+delay 2000
+input "a"
+call 97 getch
+call OK timeout 100
+input "b"
+# since delay is in effect and we set timeout the following getch should
+# return ERR not the character b.
+call -1 getch
+# drain input....
+call OK drain
+call OK timeout -1
+call OK keypad STDSCR 1
+delay 0
+input "\eOA"
+call $KEY_UP getch
+call OK refresh
+compare timeout.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/wborder b/contrib/netbsd-tests/lib/libcurses/tests/wborder
new file mode 100644
index 0000000..7a8e78f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/wborder
@@ -0,0 +1,6 @@
+include window
+call OK wborder $win1 0 0 0 0 0 0 0 0
+call OK wrefresh $win1
+compare wborder.chk
+call OK refresh
+compare wborder_refresh.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/window b/contrib/netbsd-tests/lib/libcurses/tests/window
new file mode 100644
index 0000000..52b2d0a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/window
@@ -0,0 +1,2 @@
+include start
+include window_create
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/window_create b/contrib/netbsd-tests/lib/libcurses/tests/window_create
new file mode 100644
index 0000000..8c96134
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/window_create
@@ -0,0 +1,4 @@
+call win1 newwin 6 6 2 5
+check win1 NON_NULL
+call OK wrefresh $win1
+compare window.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/wprintw b/contrib/netbsd-tests/lib/libcurses/tests/wprintw
new file mode 100644
index 0000000..a30fcc0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/wprintw
@@ -0,0 +1,6 @@
+include start
+call win1 newwin 2 5 2 5
+check win1 NON_NULL
+call OK wprintw $win1 "%s" "hello"
+call OK wrefresh $win1
+compare wprintw_refresh.chk
diff --git a/contrib/netbsd-tests/lib/libcurses/tests/wscrl b/contrib/netbsd-tests/lib/libcurses/tests/wscrl
new file mode 100644
index 0000000..51be531
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libcurses/tests/wscrl
@@ -0,0 +1,11 @@
+include window
+call OK wmove $win1 1 1
+call OK wprintw $win1 "%s" "xxxx"
+call OK wrefresh $win1
+call OK refresh
+compare wscrl1.chk
+call OK scrollok $win1 1
+call OK wscrl $win1 -2
+call OK wrefresh $win1
+call OK refresh
+compare wscrl2.chk
diff --git a/contrib/netbsd-tests/lib/libdes/t_des.c b/contrib/netbsd-tests/lib/libdes/t_des.c
new file mode 100644
index 0000000..abf2e54
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libdes/t_des.c
@@ -0,0 +1,989 @@
+/* $NetBSD: t_des.c,v 1.1 2010/08/25 16:46:36 jmmv Exp $ */
+
+/*
+ * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) All rights
+ * reserved.
+ *
+ * This package is an SSL implementation written by Eric Young
+ * (eay@cryptsoft.com). The implementation was written so as to conform with
+ * Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as the
+ * following conditions are aheared to. The following conditions apply to
+ * all code found in this distribution, be it the RC4, RSA, lhash, DES, etc.,
+ * code; not just the SSL code. The SSL documentation included with this
+ * distribution is covered by the same copyright terms except that the holder
+ * is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in the code
+ * are not to be removed. If this package is used in a product, Eric Young
+ * should be given attribution as the author of the parts of the library
+ * used. This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * 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 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. 3. All advertising materials
+ * mentioning features or use of this software must display the following
+ * acknowledgement: "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)" The word 'cryptographic' can be left out
+ * if the rouines from the library being used are not cryptographic related
+ * :-). 4. If you include any Windows specific code (or a derivative thereof)
+ * from the apps directory (application code) you must include an
+ * acknowledgement: "This product includes software written by Tim Hudson
+ * (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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 licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply
+ * be copied and put under another distribution licence [including the GNU
+ * Public Licence.]
+ */
+
+#include <atf-c.h>
+#include <des.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define crypt(c,s) (des_crypt((c),(s)))
+
+/* tisk tisk - the test keys don't all have odd parity :-( */
+/* test data */
+#define NUM_TESTS 34
+static unsigned char key_data[NUM_TESTS][8] = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
+ {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
+ {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
+ {0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57},
+ {0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E},
+ {0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86},
+ {0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E},
+ {0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6},
+ {0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE},
+ {0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6},
+ {0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE},
+ {0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16},
+ {0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F},
+ {0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46},
+ {0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E},
+ {0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76},
+ {0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07},
+ {0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F},
+ {0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7},
+ {0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF},
+ {0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6},
+ {0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF},
+ {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+ {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E},
+ {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
+ {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}
+};
+
+static unsigned char plain_data[NUM_TESTS][8] = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ {0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+ {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
+ {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
+ {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
+ {0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42},
+ {0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA},
+ {0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72},
+ {0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A},
+ {0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2},
+ {0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A},
+ {0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2},
+ {0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A},
+ {0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02},
+ {0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A},
+ {0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32},
+ {0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA},
+ {0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62},
+ {0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2},
+ {0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA},
+ {0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92},
+ {0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A},
+ {0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2},
+ {0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A},
+ {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
+ {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
+ {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
+};
+
+static unsigned char cipher_data[NUM_TESTS][8] = {
+ {0x8C, 0xA6, 0x4D, 0xE9, 0xC1, 0xB1, 0x23, 0xA7},
+ {0x73, 0x59, 0xB2, 0x16, 0x3E, 0x4E, 0xDC, 0x58},
+ {0x95, 0x8E, 0x6E, 0x62, 0x7A, 0x05, 0x55, 0x7B},
+ {0xF4, 0x03, 0x79, 0xAB, 0x9E, 0x0E, 0xC5, 0x33},
+ {0x17, 0x66, 0x8D, 0xFC, 0x72, 0x92, 0x53, 0x2D},
+ {0x8A, 0x5A, 0xE1, 0xF8, 0x1A, 0xB8, 0xF2, 0xDD},
+ {0x8C, 0xA6, 0x4D, 0xE9, 0xC1, 0xB1, 0x23, 0xA7},
+ {0xED, 0x39, 0xD9, 0x50, 0xFA, 0x74, 0xBC, 0xC4},
+ {0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B},
+ {0x7A, 0x38, 0x9D, 0x10, 0x35, 0x4B, 0xD2, 0x71},
+ {0x86, 0x8E, 0xBB, 0x51, 0xCA, 0xB4, 0x59, 0x9A},
+ {0x71, 0x78, 0x87, 0x6E, 0x01, 0xF1, 0x9B, 0x2A},
+ {0xAF, 0x37, 0xFB, 0x42, 0x1F, 0x8C, 0x40, 0x95},
+ {0x86, 0xA5, 0x60, 0xF1, 0x0E, 0xC6, 0xD8, 0x5B},
+ {0x0C, 0xD3, 0xDA, 0x02, 0x00, 0x21, 0xDC, 0x09},
+ {0xEA, 0x67, 0x6B, 0x2C, 0xB7, 0xDB, 0x2B, 0x7A},
+ {0xDF, 0xD6, 0x4A, 0x81, 0x5C, 0xAF, 0x1A, 0x0F},
+ {0x5C, 0x51, 0x3C, 0x9C, 0x48, 0x86, 0xC0, 0x88},
+ {0x0A, 0x2A, 0xEE, 0xAE, 0x3F, 0xF4, 0xAB, 0x77},
+ {0xEF, 0x1B, 0xF0, 0x3E, 0x5D, 0xFA, 0x57, 0x5A},
+ {0x88, 0xBF, 0x0D, 0xB6, 0xD7, 0x0D, 0xEE, 0x56},
+ {0xA1, 0xF9, 0x91, 0x55, 0x41, 0x02, 0x0B, 0x56},
+ {0x6F, 0xBF, 0x1C, 0xAF, 0xCF, 0xFD, 0x05, 0x56},
+ {0x2F, 0x22, 0xE4, 0x9B, 0xAB, 0x7C, 0xA1, 0xAC},
+ {0x5A, 0x6B, 0x61, 0x2C, 0xC2, 0x6C, 0xCE, 0x4A},
+ {0x5F, 0x4C, 0x03, 0x8E, 0xD1, 0x2B, 0x2E, 0x41},
+ {0x63, 0xFA, 0xC0, 0xD0, 0x34, 0xD9, 0xF7, 0x93},
+ {0x61, 0x7B, 0x3A, 0x0C, 0xE8, 0xF0, 0x71, 0x00},
+ {0xDB, 0x95, 0x86, 0x05, 0xF8, 0xC8, 0xC6, 0x06},
+ {0xED, 0xBF, 0xD1, 0xC6, 0x6C, 0x29, 0xCC, 0xC7},
+ {0x35, 0x55, 0x50, 0xB2, 0x15, 0x0E, 0x24, 0x51},
+ {0xCA, 0xAA, 0xAF, 0x4D, 0xEA, 0xF1, 0xDB, 0xAE},
+ {0xD5, 0xD4, 0x4F, 0xF7, 0x20, 0x68, 0x3D, 0x0D},
+ {0x2A, 0x2B, 0xB0, 0x08, 0xDF, 0x97, 0xC2, 0xF2}
+};
+
+static unsigned char cipher_ecb2[NUM_TESTS - 1][8] = {
+ {0x92, 0x95, 0xB5, 0x9B, 0xB3, 0x84, 0x73, 0x6E},
+ {0x19, 0x9E, 0x9D, 0x6D, 0xF3, 0x9A, 0xA8, 0x16},
+ {0x2A, 0x4B, 0x4D, 0x24, 0x52, 0x43, 0x84, 0x27},
+ {0x35, 0x84, 0x3C, 0x01, 0x9D, 0x18, 0xC5, 0xB6},
+ {0x4A, 0x5B, 0x2F, 0x42, 0xAA, 0x77, 0x19, 0x25},
+ {0xA0, 0x6B, 0xA9, 0xB8, 0xCA, 0x5B, 0x17, 0x8A},
+ {0xAB, 0x9D, 0xB7, 0xFB, 0xED, 0x95, 0xF2, 0x74},
+ {0x3D, 0x25, 0x6C, 0x23, 0xA7, 0x25, 0x2F, 0xD6},
+ {0xB7, 0x6F, 0xAB, 0x4F, 0xBD, 0xBD, 0xB7, 0x67},
+ {0x8F, 0x68, 0x27, 0xD6, 0x9C, 0xF4, 0x1A, 0x10},
+ {0x82, 0x57, 0xA1, 0xD6, 0x50, 0x5E, 0x81, 0x85},
+ {0xA2, 0x0F, 0x0A, 0xCD, 0x80, 0x89, 0x7D, 0xFA},
+ {0xCD, 0x2A, 0x53, 0x3A, 0xDB, 0x0D, 0x7E, 0xF3},
+ {0xD2, 0xC2, 0xBE, 0x27, 0xE8, 0x1B, 0x68, 0xE3},
+ {0xE9, 0x24, 0xCF, 0x4F, 0x89, 0x3C, 0x5B, 0x0A},
+ {0xA7, 0x18, 0xC3, 0x9F, 0xFA, 0x9F, 0xD7, 0x69},
+ {0x77, 0x2C, 0x79, 0xB1, 0xD2, 0x31, 0x7E, 0xB1},
+ {0x49, 0xAB, 0x92, 0x7F, 0xD0, 0x22, 0x00, 0xB7},
+ {0xCE, 0x1C, 0x6C, 0x7D, 0x85, 0xE3, 0x4A, 0x6F},
+ {0xBE, 0x91, 0xD6, 0xE1, 0x27, 0xB2, 0xE9, 0x87},
+ {0x70, 0x28, 0xAE, 0x8F, 0xD1, 0xF5, 0x74, 0x1A},
+ {0xAA, 0x37, 0x80, 0xBB, 0xF3, 0x22, 0x1D, 0xDE},
+ {0xA6, 0xC4, 0xD2, 0x5E, 0x28, 0x93, 0xAC, 0xB3},
+ {0x22, 0x07, 0x81, 0x5A, 0xE4, 0xB7, 0x1A, 0xAD},
+ {0xDC, 0xCE, 0x05, 0xE7, 0x07, 0xBD, 0xF5, 0x84},
+ {0x26, 0x1D, 0x39, 0x2C, 0xB3, 0xBA, 0xA5, 0x85},
+ {0xB4, 0xF7, 0x0F, 0x72, 0xFB, 0x04, 0xF0, 0xDC},
+ {0x95, 0xBA, 0xA9, 0x4E, 0x87, 0x36, 0xF2, 0x89},
+ {0xD4, 0x07, 0x3A, 0xF1, 0x5A, 0x17, 0x82, 0x0E},
+ {0xEF, 0x6F, 0xAF, 0xA7, 0x66, 0x1A, 0x7E, 0x89},
+ {0xC1, 0x97, 0xF5, 0x58, 0x74, 0x8A, 0x20, 0xE7},
+ {0x43, 0x34, 0xCF, 0xDA, 0x22, 0xC4, 0x86, 0xC8},
+ {0x08, 0xD7, 0xB4, 0xFB, 0x62, 0x9D, 0x08, 0x85}
+};
+
+static unsigned char cbc_key[8] = {
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+};
+static unsigned char cbc2_key[8] = {
+ 0xf1, 0xe0, 0xd3, 0xc2, 0xb5, 0xa4, 0x97, 0x86,
+};
+static unsigned char cbc3_key[8] = {
+ 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
+};
+static unsigned char cbc_iv[8] = {
+ 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
+};
+/*
+ * Changed the following text constant to binary so it will work on ebcdic
+ * machines :-)
+ */
+/* static char cbc_data[40]="7654321 Now is the time for \0001"; */
+static unsigned char cbc_data[40] = {
+ 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
+ 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
+ 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20,
+ 0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static unsigned char cbc_ok[32] = {
+ 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4,
+ 0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb,
+ 0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68,
+ 0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4,
+};
+
+#ifdef SCREW_THE_PARITY
+#error "SCREW_THE_PARITY is not ment to be defined."
+#error "Original vectors are preserved for reference only."
+static unsigned char cbc2_key[8] = {
+ 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87,
+};
+static unsigned char xcbc_ok[32] = {
+ 0x86, 0x74, 0x81, 0x0D, 0x61, 0xA4, 0xA5, 0x48,
+ 0xB9, 0x93, 0x03, 0xE1, 0xB8, 0xBB, 0xBD, 0xBD,
+ 0x64, 0x30, 0x0B, 0xB9, 0x06, 0x65, 0x81, 0x76,
+ 0x04, 0x1D, 0x77, 0x62, 0x17, 0xCA, 0x2B, 0xD2,
+};
+#else
+static unsigned char xcbc_ok[32] = {
+ 0x84, 0x6B, 0x29, 0x14, 0x85, 0x1E, 0x9A, 0x29,
+ 0x54, 0x73, 0x2F, 0x8A, 0xA0, 0xA6, 0x11, 0xC1,
+ 0x15, 0xCD, 0xC2, 0xD7, 0x95, 0x1B, 0x10, 0x53,
+ 0xA6, 0x3C, 0x5E, 0x03, 0xB2, 0x1A, 0xA3, 0xC4,
+};
+#endif
+
+static unsigned char cbc3_ok[32] = {
+ 0x3F, 0xE3, 0x01, 0xC9, 0x62, 0xAC, 0x01, 0xD0,
+ 0x22, 0x13, 0x76, 0x3C, 0x1C, 0xBD, 0x4C, 0xDC,
+ 0x79, 0x96, 0x57, 0xC0, 0x64, 0xEC, 0xF5, 0xD4,
+ 0x1C, 0x67, 0x38, 0x12, 0xCF, 0xDE, 0x96, 0x75
+};
+
+static unsigned char pcbc_ok[32] = {
+ 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4,
+ 0x6d, 0xec, 0xb4, 0x70, 0xa0, 0xe5, 0x6b, 0x15,
+ 0xae, 0xa6, 0xbf, 0x61, 0xed, 0x7d, 0x9c, 0x9f,
+ 0xf7, 0x17, 0x46, 0x3b, 0x8a, 0xb3, 0xcc, 0x88
+};
+
+static unsigned char cfb_key[8] = {
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+};
+static unsigned char cfb_iv[8] = {
+ 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef,
+};
+static unsigned char cfb_buf1[40], cfb_buf2[40], cfb_tmp[8];
+static unsigned char plain[24] =
+{
+ 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73,
+ 0x20, 0x74, 0x68, 0x65, 0x20, 0x74,
+ 0x69, 0x6d, 0x65, 0x20, 0x66, 0x6f,
+ 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20,
+};
+static unsigned char cfb_cipher8[24] = {
+ 0xf3, 0x1f, 0xda, 0x07, 0x01, 0x14,
+ 0x62, 0xee, 0x18, 0x7f, 0x43, 0xd8,
+ 0x0a, 0x7c, 0xd9, 0xb5, 0xb0, 0xd2,
+ 0x90, 0xda, 0x6e, 0x5b, 0x9a, 0x87,
+};
+static unsigned char cfb_cipher16[24] = {
+ 0xF3, 0x09, 0x87, 0x87, 0x7F, 0x57,
+ 0xF7, 0x3C, 0x36, 0xB6, 0xDB, 0x70,
+ 0xD8, 0xD5, 0x34, 0x19, 0xD3, 0x86,
+ 0xB2, 0x23, 0xB7, 0xB2, 0xAD, 0x1B,
+};
+static unsigned char cfb_cipher32[24] = {
+ 0xF3, 0x09, 0x62, 0x49, 0xA4, 0xDF,
+ 0xA4, 0x9F, 0x33, 0xDC, 0x7B, 0xAD,
+ 0x4C, 0xC8, 0x9F, 0x64, 0xE4, 0x53,
+ 0xE5, 0xEC, 0x67, 0x20, 0xDA, 0xB6,
+};
+static unsigned char cfb_cipher48[24] = {
+ 0xF3, 0x09, 0x62, 0x49, 0xC7, 0xF4,
+ 0x30, 0xB5, 0x15, 0xEC, 0xBB, 0x85,
+ 0x97, 0x5A, 0x13, 0x8C, 0x68, 0x60,
+ 0xE2, 0x38, 0x34, 0x3C, 0xDC, 0x1F,
+};
+static unsigned char cfb_cipher64[24] = {
+ 0xF3, 0x09, 0x62, 0x49, 0xC7, 0xF4,
+ 0x6E, 0x51, 0xA6, 0x9E, 0x83, 0x9B,
+ 0x1A, 0x92, 0xF7, 0x84, 0x03, 0x46,
+ 0x71, 0x33, 0x89, 0x8E, 0xA6, 0x22,
+};
+
+static unsigned char ofb_key[8] = {
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
+};
+static unsigned char ofb_iv[8] = {
+ 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef,
+};
+static unsigned char ofb_buf1[24], ofb_buf2[24], ofb_tmp[8];
+static unsigned char ofb_cipher[24] =
+{
+ 0xf3, 0x09, 0x62, 0x49, 0xc7, 0xf4, 0x6e, 0x51,
+ 0x35, 0xf2, 0x4a, 0x24, 0x2e, 0xeb, 0x3d, 0x3f,
+ 0x3d, 0x6d, 0x5b, 0xe3, 0x25, 0x5a, 0xf8, 0xc3
+};
+
+static DES_LONG cbc_cksum_ret = 0xB462FEF7L;
+static unsigned char cbc_cksum_data[8] = {
+ 0x1D, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4,
+};
+
+static char *
+pt(unsigned char *p)
+{
+ static char bufs[10][20];
+ static int bnum = 0;
+ char *ret;
+ int i;
+ static const char *f = "0123456789ABCDEF";
+
+ ret = &(bufs[bnum++][0]);
+ bnum %= 10;
+ for (i = 0; i < 8; i++) {
+ ret[i * 2] = f[(p[i] >> 4) & 0xf];
+ ret[i * 2 + 1] = f[p[i] & 0xf];
+ }
+ ret[16] = '\0';
+ return (ret);
+}
+
+static void
+fail_cfb_buf(const char *msg, unsigned char *ptr)
+{
+ char buf[1024];
+ int i;
+
+ *buf = '\0';
+ for (i = 0; i < 24; i += 8) {
+ char buf2[128];
+ snprintf(buf2, sizeof(buf2), "%s /", pt(&(cfb_buf1[i])));
+ strlcat(buf, buf2, sizeof(buf));
+ }
+
+ atf_tc_fail_nonfatal("%s: %s", msg, buf);
+}
+
+#if !defined(LIBDES_LIT)
+static void
+cfb_test(int bits, unsigned char *cfb_cipher)
+{
+ des_key_schedule ks;
+
+ des_set_key_checked(&cfb_key, ks);
+ memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv));
+ des_cfb_encrypt(plain, cfb_buf1, bits, sizeof(plain), ks, &cfb_tmp,
+ DES_ENCRYPT);
+ if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0)
+ fail_cfb_buf("cfb_encrypt encrypt error", cfb_buf1);
+ memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv));
+ des_cfb_encrypt(cfb_buf1, cfb_buf2, bits, sizeof(plain), ks, &cfb_tmp,
+ DES_DECRYPT);
+ if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0)
+ fail_cfb_buf("cfb_encrypt decrypt error", cfb_buf2);
+}
+#endif /* !defined(LIBDES_LIT) */
+
+#if !defined(LIBDES_LIT)
+static void
+cfb64_test(unsigned char *cfb_cipher)
+{
+ int n;
+ des_key_schedule ks;
+
+ des_set_key_checked(&cfb_key, ks);
+ memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv));
+ n = 0;
+ des_cfb64_encrypt(plain, cfb_buf1, 12, ks, &cfb_tmp, &n, DES_ENCRYPT);
+ des_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]), sizeof(plain) - 12, ks,
+ &cfb_tmp, &n, DES_ENCRYPT);
+ if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0)
+ fail_cfb_buf("cfb_encrypt encrypt error", cfb_buf1);
+ memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv));
+ n = 0;
+ des_cfb64_encrypt(cfb_buf1, cfb_buf2, 17, ks, &cfb_tmp, &n, DES_DECRYPT);
+ des_cfb64_encrypt(&(cfb_buf1[17]), &(cfb_buf2[17]),
+ sizeof(plain) - 17, ks, &cfb_tmp, &n, DES_DECRYPT);
+ if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0)
+ fail_cfb_buf("cfb_encrypt decrypt error", cfb_buf2);
+}
+#endif /* !defined(LIBDES_LIT) */
+
+#if !defined(LIBDES_LIT)
+static void
+ede_cfb64_test(unsigned char *cfb_cipher)
+{
+ int n;
+ des_key_schedule ks;
+
+ des_set_key_checked(&cfb_key, ks);
+ memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv));
+ n = 0;
+ des_ede3_cfb64_encrypt(plain, cfb_buf1, 12, ks, ks, ks, &cfb_tmp, &n,
+ DES_ENCRYPT);
+ des_ede3_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]),
+ sizeof(plain) - 12, ks, ks, ks,
+ &cfb_tmp, &n, DES_ENCRYPT);
+ if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0)
+ fail_cfb_buf("ede_cfb_encrypt encrypt error", cfb_buf1);
+ memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv));
+ n = 0;
+ des_ede3_cfb64_encrypt(cfb_buf1, cfb_buf2, (long) 17, ks, ks, ks,
+ &cfb_tmp, &n, DES_DECRYPT);
+ des_ede3_cfb64_encrypt(&(cfb_buf1[17]), &(cfb_buf2[17]),
+ sizeof(plain) - 17, ks, ks, ks,
+ &cfb_tmp, &n, DES_DECRYPT);
+ if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0)
+ fail_cfb_buf("ede_cfb_encrypt decrypt error", cfb_buf2);
+}
+#endif /* !defined(LIBDES_LIT) */
+
+ATF_TC_WITHOUT_HEAD(cbcm);
+#if defined(NO_DESCBCM)
+ATF_TC_BODY(cbcm, tc)
+{
+ atf_tc_skip("Test program built with NO_DESCBCM");
+}
+#else /* defined(NO_DESCBM) */
+ATF_TC_BODY(cbcm, tc)
+{
+ int i, j;
+ des_cblock iv3, iv2;
+ unsigned char cbc_in[40], cbc_out[40];
+ des_key_schedule ks, ks2, ks3;
+
+ if ((j = des_set_key_checked(&cbc_key, ks)) != 0) {
+ atf_tc_fail_nonfatal("Key error %d\n", j);
+ }
+ if ((j = des_set_key_checked(&cbc2_key, ks2)) != 0) {
+ atf_tc_fail_nonfatal("Key error %d\n", j);
+ }
+ if ((j = des_set_key_checked(&cbc3_key, ks3)) != 0) {
+ atf_tc_fail_nonfatal("Key error %d\n", j);
+ }
+ memset(cbc_out, 0, 40);
+ memset(cbc_in, 0, 40);
+ i = strlen((char *) cbc_data) + 1;
+ /* i=((i+7)/8)*8; */
+ memcpy(iv3, cbc_iv, sizeof(cbc_iv));
+ memset(iv2, '\0', sizeof iv2);
+
+ des_ede3_cbcm_encrypt(cbc_data, cbc_out, 16L, ks, ks2, ks3, &iv3, &iv2,
+ DES_ENCRYPT);
+ des_ede3_cbcm_encrypt(&cbc_data[16], &cbc_out[16], i - 16, ks, ks2, ks3,
+ &iv3, &iv2, DES_ENCRYPT);
+ /*
+ * if (memcmp(cbc_out,cbc3_ok, (unsigned int)(strlen((char
+ * *)cbc_data)+1+7)/8*8) != 0) { printf("des_ede3_cbc_encrypt encrypt
+ * error\n"); err=1; }
+ */
+ memcpy(iv3, cbc_iv, sizeof(cbc_iv));
+ memset(iv2, '\0', sizeof iv2);
+ des_ede3_cbcm_encrypt(cbc_out, cbc_in, i, ks, ks2, ks3, &iv3, &iv2,
+ DES_DECRYPT);
+ if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0) {
+ char buf[1024];
+ int n;
+
+ *buf = '\0';
+ for (n = 0; n < i; ++n) {
+ char buf2[16];
+ snprintf(buf2, sizeof(buf2), " %02x", cbc_data[n]);
+ strlcat(buf, buf2, sizeof(buf));
+ }
+ strlcat(buf, ", ", sizeof(buf));
+ for (n = 0; n < i; ++n) {
+ char buf2[16];
+ snprintf(buf2, sizeof(buf2), " %02x", cbc_in[n]);
+ strlcat(buf, buf2, sizeof(buf));
+ }
+
+ atf_tc_fail_nonfatal("des_ede3_cbcm_encrypt decrypt error: %s",
+ buf);
+ }
+}
+#endif /* defined(NO_DESCBM) */
+
+ATF_TC_WITHOUT_HEAD(ecb);
+ATF_TC_BODY(ecb, tc)
+{
+ int i;
+ des_cblock in, out, outin;
+ des_key_schedule ks;
+
+ for (i = 0; i < NUM_TESTS; i++) {
+ des_set_key_unchecked(&key_data[i], ks);
+ memcpy(in, plain_data[i], 8);
+ memset(out, 0, 8);
+ memset(outin, 0, 8);
+ des_ecb_encrypt(&in, &out, ks, DES_ENCRYPT);
+ des_ecb_encrypt(&out, &outin, ks, DES_DECRYPT);
+
+ if (memcmp(out, cipher_data[i], 8) != 0) {
+ atf_tc_fail_nonfatal("Encryption error %2d\nk=%s p=%s "
+ "o=%s act=%s\n", i + 1,
+ pt(key_data[i]), pt(in),
+ pt(cipher_data[i]), pt(out));
+ }
+ if (memcmp(in, outin, 8) != 0) {
+ atf_tc_fail_nonfatal("Decryption error %2d\nk=%s p=%s "
+ "o=%s act=%s\n", i + 1,
+ pt(key_data[i]), pt(out), pt(in),
+ pt(outin));
+ }
+ }
+}
+
+ATF_TC_WITHOUT_HEAD(ede_ecb);
+#if defined(LIBDES_LIT)
+ATF_TC_BODY(ede_ecb, tc)
+{
+ atf_tc_skip("Test program built with LIBDES_LIT");
+}
+#else /* defined(LIBDES_LIT) */
+ATF_TC_BODY(ede_ecb, tc)
+{
+ int i;
+ des_cblock in, out, outin;
+ des_key_schedule ks, ks2, ks3;
+
+ for (i = 0; i < (NUM_TESTS - 1); i++) {
+ des_set_key_unchecked(&key_data[i], ks);
+ des_set_key_unchecked(&key_data[i + 1], ks2);
+ des_set_key_unchecked(&key_data[i + 2], ks3);
+ memcpy(in, plain_data[i], 8);
+ memset(out, 0, 8);
+ memset(outin, 0, 8);
+ des_ecb2_encrypt(&in, &out, ks, ks2, DES_ENCRYPT);
+ des_ecb2_encrypt(&out, &outin, ks, ks2, DES_DECRYPT);
+
+ if (memcmp(out, cipher_ecb2[i], 8) != 0) {
+ atf_tc_fail_nonfatal("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i + 1, pt(key_data[i]), pt(in), pt(cipher_ecb2[i]),
+ pt(out));
+ }
+ if (memcmp(in, outin, 8) != 0) {
+ atf_tc_fail_nonfatal("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i + 1, pt(key_data[i]), pt(out), pt(in), pt(outin));
+ }
+ }
+}
+#endif /* defined(LIBDES_LIT) */
+
+ATF_TC_WITHOUT_HEAD(cbc);
+ATF_TC_BODY(cbc, tc)
+{
+ int j;
+ des_cblock iv3;
+ des_key_schedule ks;
+ unsigned char cbc_in[40], cbc_out[40];
+
+ if ((j = des_set_key_checked(&cbc_key, ks)) != 0)
+ atf_tc_fail_nonfatal("Key error %d\n", j);
+ memset(cbc_out, 0, 40);
+ memset(cbc_in, 0, 40);
+ memcpy(iv3, cbc_iv, sizeof(cbc_iv));
+ des_ncbc_encrypt(cbc_data, cbc_out, strlen((char *) cbc_data) + 1, ks,
+ &iv3, DES_ENCRYPT);
+ if (memcmp(cbc_out, cbc_ok, 32) != 0)
+ atf_tc_fail_nonfatal("cbc_encrypt encrypt error\n");
+ memcpy(iv3, cbc_iv, sizeof(cbc_iv));
+ des_ncbc_encrypt(cbc_out, cbc_in, strlen((char *) cbc_data) + 1, ks,
+ &iv3, DES_DECRYPT);
+ if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data)) != 0)
+ atf_tc_fail_nonfatal("cbc_encrypt decrypt error\n");
+}
+
+ATF_TC_WITHOUT_HEAD(desx_cbc);
+#if defined(LIBDES_LIT)
+ATF_TC_BODY(desx_cbc, tc)
+{
+ atf_tc_skip("Test program built with LIBDES_LIT");
+}
+#else /* defined(LIBDES_LIT) */
+ATF_TC_BODY(desx_cbc, tc)
+{
+ int j;
+ des_cblock iv3;
+ des_key_schedule ks;
+ unsigned char cbc_in[40], cbc_out[40];
+
+ if ((j = des_set_key_checked(&cbc_key, ks)) != 0) {
+ atf_tc_fail_nonfatal("Key error %d\n", j);
+ }
+ memset(cbc_out, 0, 40);
+ memset(cbc_in, 0, 40);
+ memcpy(iv3, cbc_iv, sizeof(cbc_iv));
+ des_xcbc_encrypt(cbc_data, cbc_out, strlen((char *) cbc_data) + 1, ks,
+ &iv3, &cbc2_key, &cbc3_key, DES_ENCRYPT);
+ if (memcmp(cbc_out, xcbc_ok, 32) != 0) {
+ atf_tc_fail_nonfatal("des_xcbc_encrypt encrypt error\n");
+ }
+ memcpy(iv3, cbc_iv, sizeof(cbc_iv));
+ des_xcbc_encrypt(cbc_out, cbc_in, strlen((char *) cbc_data) + 1, ks,
+ &iv3, &cbc2_key, &cbc3_key, DES_DECRYPT);
+ if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0) {
+ atf_tc_fail_nonfatal("des_xcbc_encrypt decrypt error\n");
+ }
+}
+#endif /* defined(LIBDES_LIT) */
+
+ATF_TC_WITHOUT_HEAD(ede_cbc);
+ATF_TC_BODY(ede_cbc, tc)
+{
+ int i, j;
+ des_cblock iv3;
+ des_key_schedule ks, ks2, ks3;
+ unsigned char cbc_in[40], cbc_out[40];
+
+ if ((j = des_set_key_checked(&cbc_key, ks)) != 0)
+ atf_tc_fail_nonfatal("Key error %d\n", j);
+ if ((j = des_set_key_checked(&cbc2_key, ks2)) != 0)
+ atf_tc_fail_nonfatal("Key error %d\n", j);
+ if ((j = des_set_key_checked(&cbc3_key, ks3)) != 0)
+ atf_tc_fail_nonfatal("Key error %d\n", j);
+ memset(cbc_out, 0, 40);
+ memset(cbc_in, 0, 40);
+ i = strlen((char *) cbc_data) + 1;
+ /* i=((i+7)/8)*8; */
+ memcpy(iv3, cbc_iv, sizeof(cbc_iv));
+
+ des_ede3_cbc_encrypt(cbc_data, cbc_out, 16L, ks, ks2, ks3, &iv3,
+ DES_ENCRYPT);
+ des_ede3_cbc_encrypt(&(cbc_data[16]), &(cbc_out[16]), i - 16, ks, ks2,
+ ks3, &iv3, DES_ENCRYPT);
+ if (memcmp(cbc_out, cbc3_ok, (unsigned int)
+ (strlen((char *) cbc_data) + 1 + 7) / 8 * 8) != 0)
+ atf_tc_fail_nonfatal("des_ede3_cbc_encrypt encrypt error\n");
+ memcpy(iv3, cbc_iv, sizeof(cbc_iv));
+ des_ede3_cbc_encrypt(cbc_out, cbc_in, i, ks, ks2, ks3, &iv3,
+ DES_DECRYPT);
+ if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0)
+ atf_tc_fail_nonfatal("des_ede3_cbc_encrypt decrypt error\n");
+}
+
+ATF_TC_WITHOUT_HEAD(pcbc);
+#if defined(LIBDES_LIT)
+ATF_TC_BODY(pcbc, tc)
+{
+ atf_tc_skip("Test program built with LIBDES_LIT");
+}
+#else /* defined(LIBDES_LIT) */
+ATF_TC_BODY(pcbc, tc)
+{
+ int j;
+ unsigned char cbc_in[40], cbc_out[40];
+ des_key_schedule ks;
+
+ if ((j = des_set_key_checked(&cbc_key, ks)) != 0) {
+ atf_tc_fail_nonfatal("Key error %d\n", j);
+ }
+ memset(cbc_out, 0, 40);
+ memset(cbc_in, 0, 40);
+ des_pcbc_encrypt(cbc_data, cbc_out, strlen((char *) cbc_data) + 1, ks,
+ &cbc_iv, DES_ENCRYPT);
+ if (memcmp(cbc_out, pcbc_ok, 32) != 0) {
+ atf_tc_fail_nonfatal("pcbc_encrypt encrypt error\n");
+ }
+ des_pcbc_encrypt(cbc_out, cbc_in, strlen((char *) cbc_data) + 1, ks, &cbc_iv,
+ DES_DECRYPT);
+ if (memcmp(cbc_in, cbc_data, strlen((char *) cbc_data) + 1) != 0) {
+ atf_tc_fail_nonfatal("pcbc_encrypt decrypt error\n");
+ }
+}
+#endif /* defined(LIBDES_LIT) */
+
+ATF_TC_WITHOUT_HEAD(cfb);
+#if defined(LIBDES_LIT)
+ATF_TC_BODY(cfb, tc)
+{
+ atf_tc_skip("Test program built with LIBDES_LIT");
+}
+#else /* defined(LIBDES_LIT) */
+ATF_TC_BODY(cfb, tc)
+{
+ size_t i;
+ des_key_schedule ks;
+
+ printf("cfb8\n");
+ cfb_test(8, cfb_cipher8);
+ printf("cfb16\n");
+ cfb_test(16, cfb_cipher16);
+ printf("cfb32\n");
+ cfb_test(32, cfb_cipher32);
+ printf("cfb48\n");
+ cfb_test(48, cfb_cipher48);
+ printf("cfb64\n");
+ cfb_test(64, cfb_cipher64);
+
+ printf("cfb64()\n");
+ cfb64_test(cfb_cipher64);
+
+ des_set_key_checked(&cfb_key, ks);
+ memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv));
+ for (i = 0; i < sizeof(plain); i++)
+ des_cfb_encrypt(&(plain[i]), &(cfb_buf1[i]),
+ 8, 1, ks, &cfb_tmp, DES_ENCRYPT);
+ if (memcmp(cfb_cipher8, cfb_buf1, sizeof(plain)) != 0)
+ atf_tc_fail_nonfatal("cfb_encrypt small encrypt error\n");
+ memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv));
+ for (i = 0; i < sizeof(plain); i++)
+ des_cfb_encrypt(&(cfb_buf1[i]), &(cfb_buf2[i]),
+ 8, 1, ks, &cfb_tmp, DES_DECRYPT);
+ if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0)
+ atf_tc_fail_nonfatal("cfb_encrypt small decrypt error\n");
+ printf("ede_cfb64()\n");
+ ede_cfb64_test(cfb_cipher64);
+}
+#endif /* defined(LIBDES_LIT) */
+
+ATF_TC_WITHOUT_HEAD(ofb);
+#if defined(LIBDES_LIT)
+ATF_TC_BODY(ofb, tc)
+{
+ atf_tc_skip("Test program built with LIBDES_LIT");
+}
+#else /* defined(LIBDES_LIT) */
+ATF_TC_BODY(ofb, tc)
+{
+ des_key_schedule ks;
+
+ des_set_key_checked(&ofb_key, ks);
+ memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv));
+ des_ofb_encrypt(plain, ofb_buf1, 64, sizeof(plain) / 8, ks, &ofb_tmp);
+ if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) {
+ atf_tc_fail_nonfatal("ofb_encrypt encrypt error: "
+ "%02X %02X %02X %02X %02X %02X %02X %02X, "
+ "%02X %02X %02X %02X %02X %02X %02X %02X",
+ ofb_buf1[8 + 0], ofb_buf1[8 + 1],
+ ofb_buf1[8 + 2], ofb_buf1[8 + 3],
+ ofb_buf1[8 + 4], ofb_buf1[8 + 5],
+ ofb_buf1[8 + 6], ofb_buf1[8 + 7],
+ ofb_buf1[8 + 0], ofb_cipher[8 + 1],
+ ofb_cipher[8 + 2], ofb_cipher[8 + 3],
+ ofb_buf1[8 + 4], ofb_cipher[8 + 5],
+ ofb_cipher[8 + 6], ofb_cipher[8 + 7]);
+ }
+ memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv));
+ des_ofb_encrypt(ofb_buf1, ofb_buf2, 64, sizeof(ofb_buf1) / 8, ks,
+ &ofb_tmp);
+ if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) {
+ atf_tc_fail_nonfatal("ofb_encrypt decrypt error: "
+ "%02X %02X %02X %02X %02X %02X %02X %02X, "
+ "%02X %02X %02X %02X %02X %02X %02X %02X",
+ ofb_buf2[8 + 0], ofb_buf2[8 + 1],
+ ofb_buf2[8 + 2], ofb_buf2[8 + 3],
+ ofb_buf2[8 + 4], ofb_buf2[8 + 5],
+ ofb_buf2[8 + 6], ofb_buf2[8 + 7],
+ plain[8 + 0], plain[8 + 1],
+ plain[8 + 2], plain[8 + 3],
+ plain[8 + 4], plain[8 + 5],
+ plain[8 + 6], plain[8 + 7]);
+ }
+}
+#endif /* defined(LIBDES_LIT) */
+
+ATF_TC_WITHOUT_HEAD(ofb64);
+#if defined(LIBDES_LIT)
+ATF_TC_BODY(ofb64, tc)
+{
+ atf_tc_skip("Test program built with LIBDES_LIT");
+}
+#else /* defined(LIBDES_LIT) */
+ATF_TC_BODY(ofb64, tc)
+{
+ int num;
+ size_t i;
+ des_key_schedule ks;
+
+ des_set_key_checked(&ofb_key, ks);
+ memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv));
+ memset(ofb_buf1, 0, sizeof(ofb_buf1));
+ memset(ofb_buf2, 0, sizeof(ofb_buf1));
+ num = 0;
+ for (i = 0; i < sizeof(plain); i++) {
+ des_ofb64_encrypt(&(plain[i]), &(ofb_buf1[i]), 1, ks, &ofb_tmp,
+ &num);
+ }
+ if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) {
+ atf_tc_fail_nonfatal("ofb64_encrypt encrypt error\n");
+ }
+ memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv));
+ num = 0;
+ des_ofb64_encrypt(ofb_buf1, ofb_buf2, sizeof(ofb_buf1), ks, &ofb_tmp, &num);
+ if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) {
+ atf_tc_fail_nonfatal("ofb64_encrypt decrypt error\n");
+ }
+}
+#endif /* defined(LIBDES_LIT) */
+
+ATF_TC_WITHOUT_HEAD(ede_ofb64);
+#if defined(LIBDES_LIT)
+ATF_TC_BODY(ede_ofb64, tc)
+{
+ atf_tc_skip("Test program built with LIBDES_LIT");
+}
+#else /* defined(LIBDES_LIT) */
+ATF_TC_BODY(ede_ofb64, tc)
+{
+ int num;
+ size_t i;
+ des_key_schedule ks;
+
+ des_set_key_checked(&ofb_key, ks);
+ memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv));
+ memset(ofb_buf1, 0, sizeof(ofb_buf1));
+ memset(ofb_buf2, 0, sizeof(ofb_buf1));
+ num = 0;
+ for (i = 0; i < sizeof(plain); i++) {
+ des_ede3_ofb64_encrypt(&(plain[i]), &(ofb_buf1[i]), 1, ks, ks, ks,
+ &ofb_tmp, &num);
+ }
+ if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) {
+ atf_tc_fail_nonfatal("ede_ofb64_encrypt encrypt error\n");
+ }
+ memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv));
+ num = 0;
+ des_ede3_ofb64_encrypt(ofb_buf1, ofb_buf2, sizeof(ofb_buf1), ks,
+ ks, ks, &ofb_tmp, &num);
+ if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) {
+ atf_tc_fail_nonfatal("ede_ofb64_encrypt decrypt error\n");
+ }
+}
+#endif /* defined(LIBDES_LIT) */
+
+ATF_TC_WITHOUT_HEAD(cbc_cksum);
+#if defined(LIBDES_LIT)
+ATF_TC_BODY(cbc_cksum, tc)
+{
+ atf_tc_skip("Test program built with LIBDES_LIT");
+}
+#else /* defined(LIBDES_LIT) */
+ATF_TC_BODY(cbc_cksum, tc)
+{
+ unsigned char cret[8];
+ des_key_schedule ks;
+ DES_LONG cs;
+
+ des_set_key_checked(&cbc_key, ks);
+ cs = des_cbc_cksum(cbc_data, &cret, strlen((char *) cbc_data), ks, &cbc_iv);
+ if (cs != cbc_cksum_ret) {
+ atf_tc_fail_nonfatal("bad return value (%08lX), should be %08lX\n",
+ (unsigned long) cs, (unsigned long) cbc_cksum_ret);
+ }
+ if (memcmp(cret, cbc_cksum_data, 8) != 0) {
+ atf_tc_fail_nonfatal("bad cbc_cksum block returned\n");
+ }
+}
+#endif /* defined(LIBDES_LIT) */
+
+ATF_TC_WITHOUT_HEAD(quad_cksum);
+#if defined(LIBDES_LIT)
+ATF_TC_BODY(quad_cksum, tc)
+{
+ atf_tc_skip("Test program built with LIBDES_LIT");
+}
+#else /* defined(LIBDES_LIT) */
+ATF_TC_BODY(quad_cksum, tc)
+{
+ DES_LONG cs, lqret[4];
+
+ cs = quad_cksum(cbc_data, (des_cblock *) lqret,
+ (long) strlen((char *) cbc_data), 2, (des_cblock *) cbc_iv);
+ if (cs != 0x70d7a63aL) {
+ atf_tc_fail_nonfatal("quad_cksum error, ret %08lx should be 70d7a63a\n",
+ (unsigned long) cs);
+ }
+ if (lqret[0] != 0x327eba8dL) {
+ atf_tc_fail_nonfatal("quad_cksum error, out[0] %08lx is not %08lx\n",
+ (unsigned long) lqret[0], 0x327eba8dUL);
+ }
+ if (lqret[1] != 0x201a49ccL) {
+ atf_tc_fail_nonfatal("quad_cksum error, out[1] %08lx is not %08lx\n",
+ (unsigned long) lqret[1], 0x201a49ccUL);
+ }
+ if (lqret[2] != 0x70d7a63aL) {
+ atf_tc_fail_nonfatal("quad_cksum error, out[2] %08lx is not %08lx\n",
+ (unsigned long) lqret[2], 0x70d7a63aUL);
+ }
+ if (lqret[3] != 0x501c2c26L) {
+ atf_tc_fail_nonfatal("quad_cksum error, out[3] %08lx is not %08lx\n",
+ (unsigned long) lqret[3], 0x501c2c26UL);
+ }
+}
+#endif /* defined(LIBDES_LIT) */
+
+ATF_TC_WITHOUT_HEAD(align);
+ATF_TC_BODY(align, tc)
+{
+ int i;
+ unsigned char cbc_in[40], cbc_out[40];
+ des_key_schedule ks;
+
+ printf("input word alignment test");
+ for (i = 0; i < 4; i++) {
+ printf(" %d", i);
+ des_ncbc_encrypt(&(cbc_out[i]), cbc_in,
+ strlen((char *) cbc_data) + 1, ks,
+ &cbc_iv, DES_ENCRYPT);
+ }
+
+ printf("\noutput word alignment test");
+ for (i = 0; i < 4; i++) {
+ printf(" %d", i);
+ des_ncbc_encrypt(cbc_out, &(cbc_in[i]),
+ strlen((char *) cbc_data) + 1, ks,
+ &cbc_iv, DES_ENCRYPT);
+ }
+}
+
+ATF_TC_WITHOUT_HEAD(fast_crypt);
+ATF_TC_BODY(fast_crypt, tc)
+{
+ char *str;
+
+ str = crypt("testing", "ef");
+ if (strcmp("efGnQx2725bI2", str) != 0)
+ atf_tc_fail_nonfatal("fast crypt error, %s should be efGnQx2725bI2\n", str);
+ str = crypt("bca76;23", "yA");
+ if (strcmp("yA1Rp/1hZXIJk", str) != 0)
+ atf_tc_fail_nonfatal("fast crypt error, %s should be yA1Rp/1hZXIJk\n", str);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, cbcm);
+ ATF_TP_ADD_TC(tp, ecb);
+ ATF_TP_ADD_TC(tp, ede_ecb);
+ ATF_TP_ADD_TC(tp, cbc);
+ ATF_TP_ADD_TC(tp, desx_cbc);
+ ATF_TP_ADD_TC(tp, ede_cbc);
+ ATF_TP_ADD_TC(tp, pcbc);
+ ATF_TP_ADD_TC(tp, cfb);
+ ATF_TP_ADD_TC(tp, ofb);
+ ATF_TP_ADD_TC(tp, ofb64);
+ ATF_TP_ADD_TC(tp, ede_ofb64);
+ ATF_TP_ADD_TC(tp, cbc_cksum);
+ ATF_TP_ADD_TC(tp, quad_cksum);
+ ATF_TP_ADD_TC(tp, align);
+ ATF_TP_ADD_TC(tp, fast_crypt);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libevent/t_event.sh b/contrib/netbsd-tests/lib/libevent/t_event.sh
new file mode 100755
index 0000000..1e4c9bc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libevent/t_event.sh
@@ -0,0 +1,67 @@
+# $NetBSD: t_event.sh,v 1.3 2010/11/29 18:21:15 pgoyette Exp $
+#
+# 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.
+#
+
+#
+# This is not great but rather than reimplementing the libevent
+# provided regression tests, we use an ATF wrapper around the test
+# program which carries out all the tests and prints an extensive
+# report.
+#
+
+atf_test_case kqueue
+kqueue_head() {
+ atf_set "descr" "Test libevent with kqueue backend"
+}
+kqueue_body() {
+ EVENT_NOPOLL=1 EVENT_NOSELECT=1 \
+ $(atf_get_srcdir)/h_event 2>&1 || atf_fail "check report"
+}
+
+atf_test_case poll
+poll_head() {
+ atf_set "descr" "Test libevent with poll backend"
+}
+poll_body() {
+ EVENT_NOKQUEUE=1 EVENT_NOSELECT=1 \
+ $(atf_get_srcdir)/h_event 2>&1 || atf_fail "check report"
+}
+
+atf_test_case select
+select_head() {
+ atf_set "descr" "Test libevent with select backend"
+}
+select_body() {
+ EVENT_NOKQUEUE=1 EVENT_NOPOLL=1 \
+ $(atf_get_srcdir)/h_event 2>&1 || atf_fail "check report"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case kqueue
+ atf_add_test_case poll
+ atf_add_test_case select
+}
diff --git a/contrib/netbsd-tests/lib/libexecinfo/t_backtrace.c b/contrib/netbsd-tests/lib/libexecinfo/t_backtrace.c
new file mode 100644
index 0000000..00f716e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libexecinfo/t_backtrace.c
@@ -0,0 +1,167 @@
+/* $NetBSD: t_backtrace.c,v 1.16 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_backtrace.c,v 1.16 2014/11/04 00:20:19 justin Exp $");
+
+#include <atf-c.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <execinfo.h>
+#include <unistd.h>
+
+#ifndef __arraycount
+#define __arraycount(a) (sizeof(a) / sizeof(a[0]))
+#endif
+
+void myfunc3(size_t ncalls);
+void myfunc2(size_t ncalls);
+void myfunc1(size_t origcalls, volatile size_t ncalls);
+void myfunc(size_t ncalls);
+
+volatile int prevent_inline;
+
+void
+myfunc3(size_t ncalls)
+{
+ static const struct {
+ const char *name;
+ bool is_optional;
+ } frames[] = {
+ { "myfunc", false },
+ { "atfu_backtrace_fmt_basic_body", false },
+ { "atf_tc_run", false },
+ { "atf_tp_run", true },
+ { "run_tc", true },
+ { "controlled_main", true },
+ { "atf_tp_main", false },
+ { "main", true },
+ { "___start", true },
+ };
+ size_t j, nptrs, min_frames, max_frames;
+ void *buffer[ncalls + 10];
+ char **strings;
+
+ min_frames = 0;
+ max_frames = 0;
+ for (j = 0; j < __arraycount(frames); ++j) {
+ if (!frames[j].is_optional)
+ ++min_frames;
+ ++max_frames;
+ }
+ nptrs = backtrace(buffer, __arraycount(buffer));
+ ATF_REQUIRE(nptrs != (size_t)-1);
+ strings = backtrace_symbols_fmt(buffer, nptrs, "%n");
+
+ ATF_CHECK(strings != NULL);
+
+ printf("got nptrs=%zu ncalls=%zu (min_frames: %zu, max_frames: %zu)\n",
+ nptrs, ncalls, min_frames, max_frames);
+ printf("backtrace is:\n");
+ for (j = 0; j < nptrs; j++) {
+ printf("#%zu: %s\n", j, strings[j]);
+ }
+
+ ATF_REQUIRE(nptrs >= ncalls + 2 + min_frames);
+ ATF_REQUIRE(nptrs <= ncalls + 2 + max_frames);
+ ATF_CHECK_STREQ(strings[0], "myfunc3");
+ ATF_CHECK_STREQ(strings[1], "myfunc2");
+
+ for (j = 2; j < ncalls + 2; j++)
+ ATF_CHECK_STREQ(strings[j], "myfunc1");
+
+ for (size_t i = 0; j < nptrs; i++, j++) {
+ if (frames[i].is_optional &&
+ strcmp(strings[j], frames[i].name)) {
+ --i;
+ continue;
+ }
+ ATF_CHECK_STREQ(strings[j], frames[i].name);
+ }
+
+ free(strings);
+
+ if (prevent_inline)
+ vfork();
+}
+
+void
+myfunc2(size_t ncalls)
+{
+ myfunc3(ncalls);
+
+ if (prevent_inline)
+ vfork();
+}
+
+void
+myfunc1(size_t origcalls, volatile size_t ncalls)
+{
+ if (ncalls > 1)
+ myfunc1(origcalls, ncalls - 1);
+ else
+ myfunc2(origcalls);
+
+ if (prevent_inline)
+ vfork();
+}
+
+void
+myfunc(size_t ncalls)
+{
+ myfunc1(ncalls, ncalls);
+
+ if (prevent_inline)
+ vfork();
+}
+
+ATF_TC(backtrace_fmt_basic);
+ATF_TC_HEAD(backtrace_fmt_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test backtrace_fmt(3)");
+ atf_tc_set_md_var(tc, "require.files", "/proc/self");
+}
+
+ATF_TC_BODY(backtrace_fmt_basic, tc)
+{
+ myfunc(12);
+
+ if (prevent_inline)
+ vfork();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, backtrace_fmt_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_acos.c b/contrib/netbsd-tests/lib/libm/t_acos.c
new file mode 100644
index 0000000..f051fb6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_acos.c
@@ -0,0 +1,105 @@
+/* $NetBSD: t_acos.c,v 1.10 2014/03/05 20:14:46 dsl Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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 <math.h>
+#include "t_libm.h"
+
+/*
+ * acos(3) and acosf(3)
+ */
+
+ATF_LIBM_TEST(acos_is_nan, "Test acos/acosf(x) == NaN, x = NaN, +/-Inf, ![-1..1]")
+{
+ static const double x[] = {
+ -1.000000001, 1.000000001,
+ -1.0000001, 1.0000001,
+ -1.1, 1.1,
+#ifndef __vax__
+ T_LIBM_NAN,
+ T_LIBM_MINUS_INF, T_LIBM_PLUS_INF,
+#endif
+ };
+ unsigned int i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+ T_LIBM_CHECK_NAN(i, acos, x[i]);
+ if (i < 2)
+ /* Values are too small for float */
+ continue;
+ T_LIBM_CHECK_NAN(i, acosf, x[i]);
+ }
+}
+
+ATF_LIBM_TEST(acos_inrange, "Test acos/acosf(x) for some valid values")
+{
+ static const struct {
+ double x;
+ double y;
+ } values[] = {
+ { -1, M_PI, },
+ { -0.99, 3.000053180265366, },
+ { -0.5, 2.094395102393195, },
+ { -0.1, 1.670963747956456, },
+ { 0, M_PI / 2, },
+ { 0.1, 1.470628905633337, },
+ { 0.5, 1.047197551196598, },
+ { 0.99, 0.141539473324427, },
+ };
+ unsigned int i;
+
+ /*
+ * Note that acos(x) might be calculated as atan2(sqrt(1-x*x),x).
+ * This means that acos(-1) is atan2(+0,-1), if the sign is wrong
+ * the value will be -M_PI (atan2(-0,-1)) not M_PI.
+ */
+
+ for (i = 0; i < __arraycount(values); i++) {
+ T_LIBM_CHECK(i, acos, values[i].x, values[i].y, 1.0e-15);
+ T_LIBM_CHECK(i, acosf, values[i].x, values[i].y, 1.0e-5);
+ }
+}
+
+ATF_LIBM_TEST(acos_is_plus_zero, "Test acosf(1.0) == +0.0")
+{
+ T_LIBM_CHECK_PLUS_ZERO(0, acos, 1.0);
+ T_LIBM_CHECK_PLUS_ZERO(0, acosf, 1.0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, acos_inrange);
+ ATF_TP_ADD_TC(tp, acos_is_nan);
+ ATF_TP_ADD_TC(tp, acos_is_plus_zero);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_asin.c b/contrib/netbsd-tests/lib/libm/t_asin.c
new file mode 100644
index 0000000..06de852
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_asin.c
@@ -0,0 +1,296 @@
+/* $NetBSD: t_asin.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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 <math.h>
+
+static const struct {
+ double x;
+ double y;
+} values[] = {
+ { -1.0, -M_PI / 2, },
+ { -0.9, -1.119769514998634, },
+ { -0.5, -M_PI / 6, },
+ { -0.1, -0.1001674211615598, },
+ { 0.1, 0.1001674211615598, },
+ { 0.5, M_PI / 6, },
+ { 0.9, 1.119769514998634, },
+ { 1.0, M_PI / 2, },
+};
+
+/*
+ * asin(3)
+ */
+ATF_TC(asin_nan);
+ATF_TC_HEAD(asin_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(NaN) == NaN");
+}
+
+ATF_TC_BODY(asin_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ if (isnan(asin(x)) == 0)
+ atf_tc_fail_nonfatal("asin(NaN) != NaN");
+}
+
+ATF_TC(asin_inf_neg);
+ATF_TC_HEAD(asin_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(-Inf) == NaN");
+}
+
+ATF_TC_BODY(asin_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ if (isnan(asin(x)) == 0)
+ atf_tc_fail_nonfatal("asin(-Inf) != NaN");
+}
+
+ATF_TC(asin_inf_pos);
+ATF_TC_HEAD(asin_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(+Inf) == NaN");
+}
+
+ATF_TC_BODY(asin_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ if (isnan(asin(x)) == 0)
+ atf_tc_fail_nonfatal("asin(+Inf) != NaN");
+}
+
+ATF_TC(asin_range);
+ATF_TC_HEAD(asin_range, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(x) == NaN, x < -1, x > 1");
+}
+
+ATF_TC_BODY(asin_range, tc)
+{
+ const double x[] = { -1.1, -1.000000001, 1.1, 1.000000001 };
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ if (isnan(asin(x[i])) == 0)
+ atf_tc_fail_nonfatal("asin(%f) != NaN", x[i]);
+ }
+}
+
+ATF_TC(asin_inrange);
+ATF_TC_HEAD(asin_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(x) for some values");
+}
+
+ATF_TC_BODY(asin_inrange, tc)
+{
+ const double eps = 1.0e-15;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ y = asin(values[i].x);
+ if (fabs(y - values[i].y) > eps)
+ atf_tc_fail_nonfatal("asin(%g) != %g",
+ values[i].x, values[i].y);
+ }
+}
+
+ATF_TC(asin_zero_neg);
+ATF_TC_HEAD(asin_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(asin_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = asin(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("asin(-0.0) != -0.0");
+}
+
+ATF_TC(asin_zero_pos);
+ATF_TC_HEAD(asin_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(asin_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = asin(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("asin(+0.0) != +0.0");
+}
+
+/*
+ * asinf(3)
+ */
+ATF_TC(asinf_nan);
+ATF_TC_HEAD(asinf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(NaN) == NaN");
+}
+
+ATF_TC_BODY(asinf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ if (isnan(asinf(x)) == 0)
+ atf_tc_fail_nonfatal("asinf(NaN) != NaN");
+}
+
+ATF_TC(asinf_inf_neg);
+ATF_TC_HEAD(asinf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(asinf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (isnan(asinf(x)) == 0)
+ atf_tc_fail_nonfatal("asinf(-Inf) != NaN");
+}
+
+ATF_TC(asinf_inf_pos);
+ATF_TC_HEAD(asinf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(+Inf) == NaN");
+}
+
+ATF_TC_BODY(asinf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ if (isnan(asinf(x)) == 0)
+ atf_tc_fail_nonfatal("asinf(+Inf) != NaN");
+}
+
+ATF_TC(asinf_range);
+ATF_TC_HEAD(asinf_range, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(x) == NaN, x < -1, x > 1");
+}
+
+ATF_TC_BODY(asinf_range, tc)
+{
+ const float x[] = { -1.1, -1.0000001, 1.1, 1.0000001 };
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ if (isnan(asinf(x[i])) == 0)
+ atf_tc_fail_nonfatal("asinf(%f) != NaN", x[i]);
+ }
+}
+
+ATF_TC(asinf_inrange);
+ATF_TC_HEAD(asinf_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(x) for some values");
+}
+
+ATF_TC_BODY(asinf_inrange, tc)
+{
+ const float eps = 1.0e-6;
+ float x;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ x = values[i].x;
+ y = values[i].y;
+ if (fabs(asinf(x) - y) > eps)
+ atf_tc_fail_nonfatal("asinf(%g) != %g", x, y);
+ }
+}
+
+ATF_TC(asinf_zero_neg);
+ATF_TC_HEAD(asinf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(asinf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = asinf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("asinf(-0.0) != -0.0");
+}
+
+ATF_TC(asinf_zero_pos);
+ATF_TC_HEAD(asinf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(asinf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = asinf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("asinf(+0.0) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, asin_nan);
+ ATF_TP_ADD_TC(tp, asin_inf_neg);
+ ATF_TP_ADD_TC(tp, asin_inf_pos);
+ ATF_TP_ADD_TC(tp, asin_range);
+ ATF_TP_ADD_TC(tp, asin_inrange);
+ ATF_TP_ADD_TC(tp, asin_zero_neg);
+ ATF_TP_ADD_TC(tp, asin_zero_pos);
+
+ ATF_TP_ADD_TC(tp, asinf_nan);
+ ATF_TP_ADD_TC(tp, asinf_inf_neg);
+ ATF_TP_ADD_TC(tp, asinf_inf_pos);
+ ATF_TP_ADD_TC(tp, asinf_range);
+ ATF_TP_ADD_TC(tp, asinf_inrange);
+ ATF_TP_ADD_TC(tp, asinf_zero_neg);
+ ATF_TP_ADD_TC(tp, asinf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_atan.c b/contrib/netbsd-tests/lib/libm/t_atan.c
new file mode 100644
index 0000000..c3aa15f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_atan.c
@@ -0,0 +1,101 @@
+/* $NetBSD: t_atan.c,v 1.15 2014/03/17 11:08:11 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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 <math.h>
+#include "t_libm.h"
+
+static const struct {
+ double x;
+ double y;
+} values[] = {
+#ifndef __vax__
+ /* vax has no +/- INF */
+ { T_LIBM_MINUS_INF, -M_PI / 2 },
+ { T_LIBM_PLUS_INF, M_PI / 2 },
+#endif
+ { -100, -1.560796660108231, },
+ { -10, -1.471127674303735, },
+ { -1, -M_PI / 4, },
+ { -0.1, -0.09966865249116204, },
+ { 0.1, 0.09966865249116204, },
+ { 1, M_PI / 4, },
+ { 10, 1.471127674303735, },
+ { 100, 1.560796660108231, },
+};
+
+/*
+ * atan(3)
+ */
+ATF_LIBM_TEST(atan_nan, "Test atan/atanf(NaN) == NaN")
+{
+#ifdef T_LIBM_NAN
+ T_LIBM_CHECK_NAN(0, atan, T_LIBM_NAN);
+ T_LIBM_CHECK_NAN(0, atanf, T_LIBM_NAN);
+#else
+ atf_tc_skip("no NaN on this machine");
+#endif
+}
+
+ATF_LIBM_TEST(atan_inrange, "Test atan/atanf(x) for some values")
+{
+ unsigned int i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ T_LIBM_CHECK(i, atan, values[i].x, values[i].y, 1.0e-15);
+ T_LIBM_CHECK(i, atanf, values[i].x, values[i].y, 1.0e-7);
+ }
+}
+
+ATF_LIBM_TEST(atan_zero_neg, "Test atan/atanf(-0.0) == -0.0")
+{
+
+ T_LIBM_CHECK_MINUS_ZERO(0, atan, -0.0);
+ T_LIBM_CHECK_MINUS_ZERO(0, atanf, -0.0);
+}
+
+ATF_LIBM_TEST(atan_zero_pos, "Test atan/atanf(+0.0) == +0.0")
+{
+
+ T_LIBM_CHECK_PLUS_ZERO(0, atan, +0.0);
+ T_LIBM_CHECK_PLUS_ZERO(0, atanf, +0.0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, atan_nan);
+ ATF_TP_ADD_TC(tp, atan_inrange);
+ ATF_TP_ADD_TC(tp, atan_zero_neg);
+ ATF_TP_ADD_TC(tp, atan_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_cbrt.c b/contrib/netbsd-tests/lib/libm/t_cbrt.c
new file mode 100644
index 0000000..b19413a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_cbrt.c
@@ -0,0 +1,374 @@
+/* $NetBSD: t_cbrt.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_cbrt.c,v 1.3 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <stdio.h>
+
+/*
+ * cbrt(3)
+ */
+ATF_TC(cbrt_nan);
+ATF_TC_HEAD(cbrt_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(NaN) == NaN");
+}
+
+ATF_TC_BODY(cbrt_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cbrt(x)) != 0);
+}
+
+ATF_TC(cbrt_pow);
+ATF_TC_HEAD(cbrt_pow, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(3) vs. pow(3)");
+}
+
+ATF_TC_BODY(cbrt_pow, tc)
+{
+ const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 };
+ const double eps = 1.0e-14;
+ double y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = cbrt(x[i]);
+ z = pow(x[i], 1.0 / 3.0);
+
+ if (fabs(y - z) > eps)
+ atf_tc_fail_nonfatal("cbrt(%0.03f) != "
+ "pow(%0.03f, 1/3)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(cbrt_inf_neg);
+ATF_TC_HEAD(cbrt_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(cbrt_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = cbrt(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) != 0);
+}
+
+ATF_TC(cbrt_inf_pos);
+ATF_TC_HEAD(cbrt_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(cbrt_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = cbrt(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(cbrt_zero_neg);
+ATF_TC_HEAD(cbrt_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(cbrt_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = cbrt(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("cbrt(-0.0) != -0.0");
+}
+
+ATF_TC(cbrt_zero_pos);
+ATF_TC_HEAD(cbrt_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(cbrt_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = cbrt(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("cbrt(+0.0) != +0.0");
+}
+
+/*
+ * cbrtf(3)
+ */
+ATF_TC(cbrtf_nan);
+ATF_TC_HEAD(cbrtf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(NaN) == NaN");
+}
+
+ATF_TC_BODY(cbrtf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cbrtf(x)) != 0);
+}
+
+ATF_TC(cbrtf_powf);
+ATF_TC_HEAD(cbrtf_powf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(3) vs. powf(3)");
+}
+
+ATF_TC_BODY(cbrtf_powf, tc)
+{
+ const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 };
+ const float eps = 1.0e-5;
+ float y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = cbrtf(x[i]);
+ z = powf(x[i], 1.0 / 3.0);
+
+ if (fabsf(y - z) > eps)
+ atf_tc_fail_nonfatal("cbrtf(%0.03f) != "
+ "powf(%0.03f, 1/3)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(cbrtf_inf_neg);
+ATF_TC_HEAD(cbrtf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(cbrtf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = cbrtf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) != 0);
+}
+
+ATF_TC(cbrtf_inf_pos);
+ATF_TC_HEAD(cbrtf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(cbrtf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = cbrtf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(cbrtf_zero_neg);
+ATF_TC_HEAD(cbrtf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(cbrtf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = cbrtf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("cbrtf(-0.0) != -0.0");
+}
+
+ATF_TC(cbrtf_zero_pos);
+ATF_TC_HEAD(cbrtf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(cbrtf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = cbrtf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("cbrtf(+0.0) != +0.0");
+}
+
+#if !defined(__FreeBSD__) || LDBL_PREC != 53
+/*
+ * cbrtl(3)
+ */
+ATF_TC(cbrtl_nan);
+ATF_TC_HEAD(cbrtl_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(NaN) == NaN");
+}
+
+ATF_TC_BODY(cbrtl_nan, tc)
+{
+ const long double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cbrtl(x)) != 0);
+}
+
+ATF_TC(cbrtl_powl);
+ATF_TC_HEAD(cbrtl_powl, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(3) vs. powl(3)");
+}
+
+ATF_TC_BODY(cbrtl_powl, tc)
+{
+ const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 };
+ const long double eps = 1.0e-15;
+ long double y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = cbrtl(x[i]);
+#ifdef __FreeBSD__
+ z = powl(x[i], (long double)1.0 / 3.0);
+#else
+ z = powl(x[i], 1.0 / 3.0);
+#endif
+
+ if (fabsl(y - z) > eps * fabsl(1 + x[i]))
+ atf_tc_fail_nonfatal("cbrtl(%0.03Lf) != "
+ "powl(%0.03Lf, 1/3)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(cbrtl_inf_neg);
+ATF_TC_HEAD(cbrtl_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(cbrtl_inf_neg, tc)
+{
+ const long double x = -1.0L / 0.0L;
+ long double y = cbrtl(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) != 0);
+}
+
+ATF_TC(cbrtl_inf_pos);
+ATF_TC_HEAD(cbrtl_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(cbrtl_inf_pos, tc)
+{
+ const long double x = 1.0L / 0.0L;
+ long double y = cbrtl(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(cbrtl_zero_neg);
+ATF_TC_HEAD(cbrtl_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(cbrtl_zero_neg, tc)
+{
+ const long double x = -0.0L;
+ long double y = cbrtl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("cbrtl(-0.0) != -0.0");
+}
+
+ATF_TC(cbrtl_zero_pos);
+ATF_TC_HEAD(cbrtl_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(cbrtl_zero_pos, tc)
+{
+ const long double x = 0.0L;
+ long double y = cbrtl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("cbrtl(+0.0) != +0.0");
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, cbrt_nan);
+ ATF_TP_ADD_TC(tp, cbrt_pow);
+ ATF_TP_ADD_TC(tp, cbrt_inf_neg);
+ ATF_TP_ADD_TC(tp, cbrt_inf_pos);
+ ATF_TP_ADD_TC(tp, cbrt_zero_neg);
+ ATF_TP_ADD_TC(tp, cbrt_zero_pos);
+
+ ATF_TP_ADD_TC(tp, cbrtf_nan);
+ ATF_TP_ADD_TC(tp, cbrtf_powf);
+ ATF_TP_ADD_TC(tp, cbrtf_inf_neg);
+ ATF_TP_ADD_TC(tp, cbrtf_inf_pos);
+ ATF_TP_ADD_TC(tp, cbrtf_zero_neg);
+ ATF_TP_ADD_TC(tp, cbrtf_zero_pos);
+
+#if !defined(__FreeBSD__) || LDBL_PREC != 53
+ ATF_TP_ADD_TC(tp, cbrtl_nan);
+ ATF_TP_ADD_TC(tp, cbrtl_powl);
+ ATF_TP_ADD_TC(tp, cbrtl_inf_neg);
+ ATF_TP_ADD_TC(tp, cbrtl_inf_pos);
+ ATF_TP_ADD_TC(tp, cbrtl_zero_neg);
+ ATF_TP_ADD_TC(tp, cbrtl_zero_pos);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_ceil.c b/contrib/netbsd-tests/lib/libm/t_ceil.c
new file mode 100644
index 0000000..b57f30e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_ceil.c
@@ -0,0 +1,931 @@
+/* $NetBSD: t_ceil.c,v 1.10 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_ceil.c,v 1.10 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <limits.h>
+#include <stdio.h>
+
+#ifdef __vax__
+#define SMALL_NUM 1.0e-38
+#else
+#define SMALL_NUM 1.0e-40
+#endif
+
+/*
+ * ceil(3)
+ */
+ATF_TC(ceil_basic);
+ATF_TC_HEAD(ceil_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of ceil(3)");
+}
+
+ATF_TC_BODY(ceil_basic, tc)
+{
+ const double x = 0.999999999999999;
+ const double y = 0.000000000000001;
+
+ ATF_CHECK(fabs(ceil(x) - 1) < SMALL_NUM);
+ ATF_CHECK(fabs(ceil(y) - 1) < SMALL_NUM);
+}
+
+ATF_TC(ceil_nan);
+ATF_TC_HEAD(ceil_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceil(NaN) == NaN");
+}
+
+ATF_TC_BODY(ceil_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(ceil(x)) != 0);
+}
+
+ATF_TC(ceil_inf_neg);
+ATF_TC_HEAD(ceil_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceil(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(ceil_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = ceil(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceil(-Inf) != -Inf");
+}
+
+ATF_TC(ceil_inf_pos);
+ATF_TC_HEAD(ceil_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceil(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(ceil_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = ceil(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceil(+Inf) != +Inf");
+}
+
+ATF_TC(ceil_zero_neg);
+ATF_TC_HEAD(ceil_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceil(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(ceil_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = ceil(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceil(-0.0) != -0.0");
+}
+
+ATF_TC(ceil_zero_pos);
+ATF_TC_HEAD(ceil_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceil(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(ceil_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = ceil(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceil(+0.0) != +0.0");
+}
+
+/*
+ * ceilf(3)
+ */
+ATF_TC(ceilf_basic);
+ATF_TC_HEAD(ceilf_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of ceilf(3)");
+}
+
+ATF_TC_BODY(ceilf_basic, tc)
+{
+ const float x = 0.9999999;
+ const float y = 0.0000001;
+
+ ATF_CHECK(fabsf(ceilf(x) - 1) < SMALL_NUM);
+ ATF_CHECK(fabsf(ceilf(y) - 1) < SMALL_NUM);
+}
+
+ATF_TC(ceilf_nan);
+ATF_TC_HEAD(ceilf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceilf(NaN) == NaN");
+}
+
+ATF_TC_BODY(ceilf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(ceilf(x)) != 0);
+}
+
+ATF_TC(ceilf_inf_neg);
+ATF_TC_HEAD(ceilf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceilf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(ceilf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = ceilf(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceilf(-Inf) != -Inf");
+}
+
+ATF_TC(ceilf_inf_pos);
+ATF_TC_HEAD(ceilf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceilf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(ceilf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = ceilf(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceilf(+Inf) != +Inf");
+}
+
+ATF_TC(ceilf_zero_neg);
+ATF_TC_HEAD(ceilf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceilf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(ceilf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = ceilf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceilf(-0.0) != -0.0");
+}
+
+ATF_TC(ceilf_zero_pos);
+ATF_TC_HEAD(ceilf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceilf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(ceilf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = ceilf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceilf(+0.0) != +0.0");
+}
+
+/*
+ * ceill(3)
+ */
+ATF_TC(ceill_basic);
+ATF_TC_HEAD(ceill_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of ceill(3)");
+}
+
+ATF_TC_BODY(ceill_basic, tc)
+{
+ const long double x = 0.9999999;
+ const long double y = 0.0000001;
+
+ ATF_CHECK(fabsl(ceill(x) - 1) < SMALL_NUM);
+ ATF_CHECK(fabsl(ceill(y) - 1) < SMALL_NUM);
+}
+
+ATF_TC(ceill_nan);
+ATF_TC_HEAD(ceill_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceill(NaN) == NaN");
+}
+
+ATF_TC_BODY(ceill_nan, tc)
+{
+ const long double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(ceill(x)) != 0);
+}
+
+ATF_TC(ceill_inf_neg);
+ATF_TC_HEAD(ceill_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceill(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(ceill_inf_neg, tc)
+{
+ const long double x = -1.0L / 0.0L;
+ long double y = ceill(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceill(-Inf) != -Inf");
+}
+
+ATF_TC(ceill_inf_pos);
+ATF_TC_HEAD(ceill_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceill(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(ceill_inf_pos, tc)
+{
+ const long double x = 1.0L / 0.0L;
+ long double y = ceill(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceill(+Inf) != +Inf");
+}
+
+ATF_TC(ceill_zero_neg);
+ATF_TC_HEAD(ceill_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceill(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(ceill_zero_neg, tc)
+{
+ const long double x = -0.0L;
+ long double y = ceill(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceill(-0.0) != -0.0");
+}
+
+ATF_TC(ceill_zero_pos);
+ATF_TC_HEAD(ceill_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceill(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(ceill_zero_pos, tc)
+{
+ const long double x = 0.0L;
+ long double y = ceill(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceill(+0.0) != +0.0");
+}
+
+/*
+ * floor(3)
+ */
+ATF_TC(floor_basic);
+ATF_TC_HEAD(floor_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of floor(3)");
+}
+
+ATF_TC_BODY(floor_basic, tc)
+{
+ const double x = 0.999999999999999;
+ const double y = 0.000000000000001;
+
+ ATF_CHECK(floor(x) < SMALL_NUM);
+ ATF_CHECK(floor(y) < SMALL_NUM);
+}
+
+ATF_TC(floor_nan);
+ATF_TC_HEAD(floor_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floor(NaN) == NaN");
+}
+
+ATF_TC_BODY(floor_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(floor(x)) != 0);
+}
+
+ATF_TC(floor_inf_neg);
+ATF_TC_HEAD(floor_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floor(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(floor_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = floor(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floor(-Inf) != -Inf");
+}
+
+ATF_TC(floor_inf_pos);
+ATF_TC_HEAD(floor_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floor(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(floor_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = floor(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floor(+Inf) != +Inf");
+}
+
+ATF_TC(floor_zero_neg);
+ATF_TC_HEAD(floor_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floor(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(floor_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = floor(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floor(-0.0) != -0.0");
+}
+
+ATF_TC(floor_zero_pos);
+ATF_TC_HEAD(floor_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floor(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(floor_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = floor(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floor(+0.0) != +0.0");
+}
+
+/*
+ * floorf(3)
+ */
+ATF_TC(floorf_basic);
+ATF_TC_HEAD(floorf_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of floorf(3)");
+}
+
+ATF_TC_BODY(floorf_basic, tc)
+{
+ const float x = 0.9999999;
+ const float y = 0.0000001;
+
+ ATF_CHECK(floorf(x) < SMALL_NUM);
+ ATF_CHECK(floorf(y) < SMALL_NUM);
+}
+
+ATF_TC(floorf_nan);
+ATF_TC_HEAD(floorf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorf(NaN) == NaN");
+}
+
+ATF_TC_BODY(floorf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(floorf(x)) != 0);
+}
+
+ATF_TC(floorf_inf_neg);
+ATF_TC_HEAD(floorf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(floorf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = floorf(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floorf(-Inf) != -Inf");
+}
+
+ATF_TC(floorf_inf_pos);
+ATF_TC_HEAD(floorf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(floorf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = floorf(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floorf(+Inf) != +Inf");
+}
+
+ATF_TC(floorf_zero_neg);
+ATF_TC_HEAD(floorf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(floorf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = floorf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floorf(-0.0) != -0.0");
+}
+
+ATF_TC(floorf_zero_pos);
+ATF_TC_HEAD(floorf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(floorf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = floorf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floorf(+0.0) != +0.0");
+}
+
+/*
+ * floorl(3)
+ */
+ATF_TC(floorl_basic);
+ATF_TC_HEAD(floorl_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of floorl(3)");
+}
+
+ATF_TC_BODY(floorl_basic, tc)
+{
+ const long double x = 0.9999999;
+ const long double y = 0.0000001;
+
+ ATF_CHECK(floorl(x) < SMALL_NUM);
+ ATF_CHECK(floorl(y) < SMALL_NUM);
+}
+
+ATF_TC(floorl_nan);
+ATF_TC_HEAD(floorl_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorl(NaN) == NaN");
+}
+
+ATF_TC_BODY(floorl_nan, tc)
+{
+ const long double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(floorl(x)) != 0);
+}
+
+ATF_TC(floorl_inf_neg);
+ATF_TC_HEAD(floorl_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorl(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(floorl_inf_neg, tc)
+{
+ const long double x = -1.0L / 0.0L;
+ long double y = floorl(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floorl(-Inf) != -Inf");
+}
+
+ATF_TC(floorl_inf_pos);
+ATF_TC_HEAD(floorl_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorl(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(floorl_inf_pos, tc)
+{
+ const long double x = 1.0L / 0.0L;
+ long double y = floorl(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floorl(+Inf) != +Inf");
+}
+
+ATF_TC(floorl_zero_neg);
+ATF_TC_HEAD(floorl_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorl(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(floorl_zero_neg, tc)
+{
+ const long double x = -0.0L;
+ long double y = floorl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floorl(-0.0) != -0.0");
+}
+
+ATF_TC(floorl_zero_pos);
+ATF_TC_HEAD(floorl_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorl(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(floorl_zero_pos, tc)
+{
+ const long double x = 0.0L;
+ long double y = floorl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floorl(+0.0) != +0.0");
+}
+
+/*
+ * trunc(3)
+ */
+ATF_TC(trunc_basic);
+ATF_TC_HEAD(trunc_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of trunc(3)");
+}
+
+ATF_TC_BODY(trunc_basic, tc)
+{
+ const double x = 0.999999999999999;
+ const double y = 0.000000000000001;
+
+ ATF_CHECK(trunc(x) < SMALL_NUM);
+ ATF_CHECK(trunc(y) < SMALL_NUM);
+}
+
+ATF_TC(trunc_nan);
+ATF_TC_HEAD(trunc_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test trunc(NaN) == NaN");
+}
+
+ATF_TC_BODY(trunc_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(trunc(x)) != 0);
+}
+
+ATF_TC(trunc_inf_neg);
+ATF_TC_HEAD(trunc_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test trunc(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(trunc_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = trunc(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("trunc(-Inf) != -Inf");
+}
+
+ATF_TC(trunc_inf_pos);
+ATF_TC_HEAD(trunc_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test trunc(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(trunc_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = trunc(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("trunc(+Inf) != +Inf");
+}
+
+ATF_TC(trunc_zero_neg);
+ATF_TC_HEAD(trunc_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test trunc(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(trunc_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = trunc(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("trunc(-0.0) != -0.0");
+}
+
+ATF_TC(trunc_zero_pos);
+ATF_TC_HEAD(trunc_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test trunc(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(trunc_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = trunc(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("trunc(+0.0) != +0.0");
+}
+
+/*
+ * truncf(3)
+ */
+ATF_TC(truncf_basic);
+ATF_TC_HEAD(truncf_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of truncf(3)");
+}
+
+ATF_TC_BODY(truncf_basic, tc)
+{
+ const float x = 0.9999999;
+ const float y = 0.0000001;
+
+ ATF_CHECK(truncf(x) < SMALL_NUM);
+ ATF_CHECK(truncf(y) < SMALL_NUM);
+}
+
+ATF_TC(truncf_nan);
+ATF_TC_HEAD(truncf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncf(NaN) == NaN");
+}
+
+ATF_TC_BODY(truncf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(truncf(x)) != 0);
+}
+
+ATF_TC(truncf_inf_neg);
+ATF_TC_HEAD(truncf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(truncf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = truncf(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("truncf(-Inf) != -Inf");
+}
+
+ATF_TC(truncf_inf_pos);
+ATF_TC_HEAD(truncf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(truncf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = truncf(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("truncf(+Inf) != +Inf");
+}
+
+ATF_TC(truncf_zero_neg);
+ATF_TC_HEAD(truncf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(truncf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = truncf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("truncf(-0.0) != -0.0");
+}
+
+ATF_TC(truncf_zero_pos);
+ATF_TC_HEAD(truncf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(truncf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = truncf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("truncf(+0.0) != +0.0");
+}
+
+/*
+ * truncl(3)
+ */
+ATF_TC(truncl_basic);
+ATF_TC_HEAD(truncl_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of truncl(3)");
+}
+
+ATF_TC_BODY(truncl_basic, tc)
+{
+ const long double x = 0.9999999;
+ const long double y = 0.0000001;
+
+ ATF_CHECK(truncl(x) < SMALL_NUM);
+ ATF_CHECK(truncl(y) < SMALL_NUM);
+}
+
+ATF_TC(truncl_nan);
+ATF_TC_HEAD(truncl_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncl(NaN) == NaN");
+}
+
+ATF_TC_BODY(truncl_nan, tc)
+{
+ const long double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(truncl(x)) != 0);
+}
+
+ATF_TC(truncl_inf_neg);
+ATF_TC_HEAD(truncl_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncl(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(truncl_inf_neg, tc)
+{
+ const long double x = -1.0L / 0.0L;
+ long double y = truncl(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("truncl(-Inf) != -Inf");
+}
+
+ATF_TC(truncl_inf_pos);
+ATF_TC_HEAD(truncl_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncl(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(truncl_inf_pos, tc)
+{
+ const long double x = 1.0L / 0.0L;
+ long double y = truncl(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("truncl(+Inf) != +Inf");
+}
+
+ATF_TC(truncl_zero_neg);
+ATF_TC_HEAD(truncl_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncl(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(truncl_zero_neg, tc)
+{
+ const long double x = -0.0L;
+ long double y = truncl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("truncl(-0.0) != -0.0");
+}
+
+ATF_TC(truncl_zero_pos);
+ATF_TC_HEAD(truncl_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncl(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(truncl_zero_pos, tc)
+{
+ const long double x = 0.0L;
+ long double y = truncl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("truncl(+0.0) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, ceil_basic);
+ ATF_TP_ADD_TC(tp, ceil_nan);
+ ATF_TP_ADD_TC(tp, ceil_inf_neg);
+ ATF_TP_ADD_TC(tp, ceil_inf_pos);
+ ATF_TP_ADD_TC(tp, ceil_zero_neg);
+ ATF_TP_ADD_TC(tp, ceil_zero_pos);
+
+ ATF_TP_ADD_TC(tp, ceilf_basic);
+ ATF_TP_ADD_TC(tp, ceilf_nan);
+ ATF_TP_ADD_TC(tp, ceilf_inf_neg);
+ ATF_TP_ADD_TC(tp, ceilf_inf_pos);
+ ATF_TP_ADD_TC(tp, ceilf_zero_neg);
+ ATF_TP_ADD_TC(tp, ceilf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, ceill_basic);
+ ATF_TP_ADD_TC(tp, ceill_nan);
+ ATF_TP_ADD_TC(tp, ceill_inf_neg);
+ ATF_TP_ADD_TC(tp, ceill_inf_pos);
+ ATF_TP_ADD_TC(tp, ceill_zero_neg);
+ ATF_TP_ADD_TC(tp, ceill_zero_pos);
+
+ ATF_TP_ADD_TC(tp, floor_basic);
+ ATF_TP_ADD_TC(tp, floor_nan);
+ ATF_TP_ADD_TC(tp, floor_inf_neg);
+ ATF_TP_ADD_TC(tp, floor_inf_pos);
+ ATF_TP_ADD_TC(tp, floor_zero_neg);
+ ATF_TP_ADD_TC(tp, floor_zero_pos);
+
+ ATF_TP_ADD_TC(tp, floorf_basic);
+ ATF_TP_ADD_TC(tp, floorf_nan);
+ ATF_TP_ADD_TC(tp, floorf_inf_neg);
+ ATF_TP_ADD_TC(tp, floorf_inf_pos);
+ ATF_TP_ADD_TC(tp, floorf_zero_neg);
+ ATF_TP_ADD_TC(tp, floorf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, floorl_basic);
+ ATF_TP_ADD_TC(tp, floorl_nan);
+ ATF_TP_ADD_TC(tp, floorl_inf_neg);
+ ATF_TP_ADD_TC(tp, floorl_inf_pos);
+ ATF_TP_ADD_TC(tp, floorl_zero_neg);
+ ATF_TP_ADD_TC(tp, floorl_zero_pos);
+
+ ATF_TP_ADD_TC(tp, trunc_basic);
+ ATF_TP_ADD_TC(tp, trunc_nan);
+ ATF_TP_ADD_TC(tp, trunc_inf_neg);
+ ATF_TP_ADD_TC(tp, trunc_inf_pos);
+ ATF_TP_ADD_TC(tp, trunc_zero_neg);
+ ATF_TP_ADD_TC(tp, trunc_zero_pos);
+
+ ATF_TP_ADD_TC(tp, truncf_basic);
+ ATF_TP_ADD_TC(tp, truncf_nan);
+ ATF_TP_ADD_TC(tp, truncf_inf_neg);
+ ATF_TP_ADD_TC(tp, truncf_inf_pos);
+ ATF_TP_ADD_TC(tp, truncf_zero_neg);
+ ATF_TP_ADD_TC(tp, truncf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, truncl_basic);
+ ATF_TP_ADD_TC(tp, truncl_nan);
+ ATF_TP_ADD_TC(tp, truncl_inf_neg);
+ ATF_TP_ADD_TC(tp, truncl_inf_pos);
+ ATF_TP_ADD_TC(tp, truncl_zero_neg);
+ ATF_TP_ADD_TC(tp, truncl_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_cos.c b/contrib/netbsd-tests/lib/libm/t_cos.c
new file mode 100644
index 0000000..d99d608
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_cos.c
@@ -0,0 +1,263 @@
+/* $NetBSD: t_cos.c,v 1.4 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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 <math.h>
+
+static const struct {
+ int angle;
+ double x;
+ double y;
+} angles[] = {
+ { -180, -3.141592653589793, -1.0000000000000000 },
+ { -135, -2.356194490192345, -0.7071067811865476 },
+ { -90, -1.570796326794897, 0.0000000000000000 },
+ { -45, -0.785398163397448, 0.7071067811865476 },
+ { 0, 0.000000000000000, 1.0000000000000000 },
+ { 30, 0.523598775598299, 0.8660254037844386 },
+ { 45, 0.785398163397448, 0.7071067811865476 },
+ { 60, 1.047197551196598, 0.5000000000000000 },
+ { 90, 1.570796326794897, 0.0000000000000000 },
+ { 120, 2.094395102393195, -0.5000000000000000 },
+ { 135, 2.356194490192345, -0.7071067811865476 },
+ { 150, 2.617993877991494, -0.8660254037844386 },
+ { 180, 3.141592653589793, -1.0000000000000000 },
+ { 270, 4.712388980384690, 0.0000000000000000 },
+ { 360, 6.283185307179586, 1.0000000000000000 }
+};
+
+/*
+ * cos(3)
+ */
+ATF_TC(cos_angles);
+ATF_TC_HEAD(cos_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(cos_angles, tc)
+{
+ const double eps = 1.0e-15;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ if (fabs(cos(angles[i].x) - angles[i].y) > eps)
+ atf_tc_fail_nonfatal("cos(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(cos_nan);
+ATF_TC_HEAD(cos_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cos(NaN) == NaN");
+}
+
+ATF_TC_BODY(cos_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cos(x)) != 0);
+}
+
+ATF_TC(cos_inf_neg);
+ATF_TC_HEAD(cos_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cos(-Inf) == NaN");
+}
+
+ATF_TC_BODY(cos_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ ATF_CHECK(isnan(cos(x)) != 0);
+}
+
+ATF_TC(cos_inf_pos);
+ATF_TC_HEAD(cos_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cos(+Inf) == NaN");
+}
+
+ATF_TC_BODY(cos_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(isnan(cos(x)) != 0);
+}
+
+
+ATF_TC(cos_zero_neg);
+ATF_TC_HEAD(cos_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cos(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(cos_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(cos(x) == 1.0);
+}
+
+ATF_TC(cos_zero_pos);
+ATF_TC_HEAD(cos_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cos(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(cos_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(cos(x) == 1.0);
+}
+
+/*
+ * cosf(3)
+ */
+ATF_TC(cosf_angles);
+ATF_TC_HEAD(cosf_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(cosf_angles, tc)
+{
+ const float eps = 1.0e-7;
+ float x, y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ x = angles[i].x;
+ y = angles[i].y;
+
+ if (fabsf(cosf(x) - y) > eps)
+ atf_tc_fail_nonfatal("cosf(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(cosf_nan);
+ATF_TC_HEAD(cosf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosf(NaN) == NaN");
+}
+
+ATF_TC_BODY(cosf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cosf(x)) != 0);
+}
+
+ATF_TC(cosf_inf_neg);
+ATF_TC_HEAD(cosf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(cosf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (isnan(cosf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("cosf(-Inf) != NaN");
+ }
+}
+
+ATF_TC(cosf_inf_pos);
+ATF_TC_HEAD(cosf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosf(+Inf) == NaN");
+}
+
+ATF_TC_BODY(cosf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ if (isnan(cosf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("cosf(+Inf) != NaN");
+ }
+}
+
+
+ATF_TC(cosf_zero_neg);
+ATF_TC_HEAD(cosf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosf(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(cosf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(cosf(x) == 1.0);
+}
+
+ATF_TC(cosf_zero_pos);
+ATF_TC_HEAD(cosf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosf(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(cosf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(cosf(x) == 1.0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, cos_angles);
+ ATF_TP_ADD_TC(tp, cos_nan);
+ ATF_TP_ADD_TC(tp, cos_inf_neg);
+ ATF_TP_ADD_TC(tp, cos_inf_pos);
+ ATF_TP_ADD_TC(tp, cos_zero_neg);
+ ATF_TP_ADD_TC(tp, cos_zero_pos);
+
+ ATF_TP_ADD_TC(tp, cosf_angles);
+ ATF_TP_ADD_TC(tp, cosf_nan);
+ ATF_TP_ADD_TC(tp, cosf_inf_neg);
+ ATF_TP_ADD_TC(tp, cosf_inf_pos);
+ ATF_TP_ADD_TC(tp, cosf_zero_neg);
+ ATF_TP_ADD_TC(tp, cosf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_cosh.c b/contrib/netbsd-tests/lib/libm/t_cosh.c
new file mode 100644
index 0000000..3f998de
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_cosh.c
@@ -0,0 +1,270 @@
+/* $NetBSD: t_cosh.c,v 1.6 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_cosh.c,v 1.6 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <stdio.h>
+
+static const struct {
+ double x;
+ double y;
+ double e;
+} values[] = {
+ { -10, 11013.23292010332, 1e4, },
+ { -2, 3.762195691083631, 1, },
+ { -1, 1.543080634815244, 1, },
+ { -0.05, 1.001250260438369, 1, },
+ { -0.001, 1.000000500000042, 1, },
+ { 0, 1, 1, },
+ { 0.001, 1.000000500000042, 1, },
+ { 0.05, 1.001250260438369, 1, },
+ { 1, 1.543080634815244, 1, },
+ { 2, 3.762195691083631, 1, },
+ { 10, 11013.23292010332, 1e4, },
+};
+
+/*
+ * cosh(3)
+ */
+ATF_TC(cosh_inrange);
+ATF_TC_HEAD(cosh_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "cosh(x) for some values");
+}
+
+ATF_TC_BODY(cosh_inrange, tc)
+{
+ double eps;
+ double x;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ x = values[i].x;
+ y = values[i].y;
+ eps = 1e-15 * values[i].e;
+
+ if (fabs(cosh(x) - y) > eps)
+ atf_tc_fail_nonfatal("cosh(%g) != %g\n", x, y);
+ }
+}
+
+ATF_TC(cosh_nan);
+ATF_TC_HEAD(cosh_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosh(NaN) == NaN");
+}
+
+ATF_TC_BODY(cosh_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cosh(x)) != 0);
+}
+
+ATF_TC(cosh_inf_neg);
+ATF_TC_HEAD(cosh_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosh(-Inf) == +Inf");
+}
+
+ATF_TC_BODY(cosh_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = cosh(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(cosh_inf_pos);
+ATF_TC_HEAD(cosh_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosh(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(cosh_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = cosh(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(cosh_zero_neg);
+ATF_TC_HEAD(cosh_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosh(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(cosh_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ if (cosh(x) != 1.0)
+ atf_tc_fail_nonfatal("cosh(-0.0) != 1.0");
+}
+
+ATF_TC(cosh_zero_pos);
+ATF_TC_HEAD(cosh_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosh(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(cosh_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ if (cosh(x) != 1.0)
+ atf_tc_fail_nonfatal("cosh(+0.0) != 1.0");
+}
+
+/*
+ * coshf(3)
+ */
+ATF_TC(coshf_inrange);
+ATF_TC_HEAD(coshf_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "coshf(x) for some values");
+}
+
+ATF_TC_BODY(coshf_inrange, tc)
+{
+ float eps;
+ float x;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ x = values[i].x;
+ y = values[i].y;
+ eps = 1e-6 * values[i].e;
+
+ if (fabsf(coshf(x) - y) > eps)
+ atf_tc_fail_nonfatal("coshf(%g) != %g\n", x, y);
+ }
+}
+
+ATF_TC(coshf_nan);
+ATF_TC_HEAD(coshf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coshf(NaN) == NaN");
+}
+
+ATF_TC_BODY(coshf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(coshf(x)) != 0);
+}
+
+ATF_TC(coshf_inf_neg);
+ATF_TC_HEAD(coshf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coshf(-Inf) == +Inf");
+}
+
+ATF_TC_BODY(coshf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = coshf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(coshf_inf_pos);
+ATF_TC_HEAD(coshf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coshf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(coshf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = coshf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(coshf_zero_neg);
+ATF_TC_HEAD(coshf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coshf(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(coshf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ if (coshf(x) != 1.0)
+ atf_tc_fail_nonfatal("coshf(-0.0) != 1.0");
+}
+
+ATF_TC(coshf_zero_pos);
+ATF_TC_HEAD(coshf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coshf(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(coshf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ if (coshf(x) != 1.0)
+ atf_tc_fail_nonfatal("coshf(+0.0) != 1.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, cosh_inrange);
+ ATF_TP_ADD_TC(tp, cosh_nan);
+ ATF_TP_ADD_TC(tp, cosh_inf_neg);
+ ATF_TP_ADD_TC(tp, cosh_inf_pos);
+ ATF_TP_ADD_TC(tp, cosh_zero_neg);
+ ATF_TP_ADD_TC(tp, cosh_zero_pos);
+
+ ATF_TP_ADD_TC(tp, coshf_inrange);
+ ATF_TP_ADD_TC(tp, coshf_nan);
+ ATF_TP_ADD_TC(tp, coshf_inf_neg);
+ ATF_TP_ADD_TC(tp, coshf_inf_pos);
+ ATF_TP_ADD_TC(tp, coshf_zero_neg);
+ ATF_TP_ADD_TC(tp, coshf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_erf.c b/contrib/netbsd-tests/lib/libm/t_erf.c
new file mode 100644
index 0000000..25bbae7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_erf.c
@@ -0,0 +1,299 @@
+/* $NetBSD: t_erf.c,v 1.2 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_erf.c,v 1.2 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+
+/*
+ * erf(3)
+ */
+ATF_TC(erf_nan);
+ATF_TC_HEAD(erf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erf(NaN) == NaN");
+}
+
+ATF_TC_BODY(erf_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(erf(x)) != 0);
+}
+
+ATF_TC(erf_inf_neg);
+ATF_TC_HEAD(erf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erf(-Inf) == -1.0");
+}
+
+ATF_TC_BODY(erf_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ if (erf(x) != -1.0)
+ atf_tc_fail_nonfatal("erf(-Inf) != -1.0");
+}
+
+ATF_TC(erf_inf_pos);
+ATF_TC_HEAD(erf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erf(+Inf) == 1.0");
+}
+
+ATF_TC_BODY(erf_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ if (erf(x) != 1.0)
+ atf_tc_fail_nonfatal("erf(+Inf) != 1.0");
+}
+
+ATF_TC(erf_zero_neg);
+ATF_TC_HEAD(erf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(erf_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = erf(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("erf(-0.0) != -0.0");
+}
+
+ATF_TC(erf_zero_pos);
+ATF_TC_HEAD(erf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(erf_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = erf(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("erf(+0.0) != +0.0");
+}
+
+/*
+ * erff(3)
+ */
+ATF_TC(erff_nan);
+ATF_TC_HEAD(erff_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erff(NaN) == NaN");
+}
+
+ATF_TC_BODY(erff_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(erff(x)) != 0);
+}
+
+ATF_TC(erff_inf_neg);
+ATF_TC_HEAD(erff_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erff(-Inf) == -1.0");
+}
+
+ATF_TC_BODY(erff_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (erff(x) != -1.0)
+ atf_tc_fail_nonfatal("erff(-Inf) != -1.0");
+}
+
+ATF_TC(erff_inf_pos);
+ATF_TC_HEAD(erff_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erff(+Inf) == 1.0");
+}
+
+ATF_TC_BODY(erff_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ if (erff(x) != 1.0)
+ atf_tc_fail_nonfatal("erff(+Inf) != 1.0");
+}
+
+ATF_TC(erff_zero_neg);
+ATF_TC_HEAD(erff_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erff(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(erff_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = erff(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("erff(-0.0) != -0.0");
+}
+
+ATF_TC(erff_zero_pos);
+ATF_TC_HEAD(erff_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erff(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(erff_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = erff(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("erff(+0.0) != +0.0");
+}
+
+/*
+ * erfc(3)
+ */
+ATF_TC(erfc_nan);
+ATF_TC_HEAD(erfc_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfc(NaN) == NaN");
+}
+
+ATF_TC_BODY(erfc_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(erfc(x)) != 0);
+}
+
+ATF_TC(erfc_inf_neg);
+ATF_TC_HEAD(erfc_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfc(-Inf) == 2.0");
+}
+
+ATF_TC_BODY(erfc_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ if (erfc(x) != 2.0)
+ atf_tc_fail_nonfatal("erfc(-Inf) != 2.0");
+}
+
+ATF_TC(erfc_inf_pos);
+ATF_TC_HEAD(erfc_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfc(+Inf) == +0.0");
+}
+
+ATF_TC_BODY(erfc_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = erfc(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("erfc(+Inf) != +0.0");
+}
+
+/*
+ * erfcf(3)
+ */
+ATF_TC(erfcf_nan);
+ATF_TC_HEAD(erfcf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfcf(NaN) == NaN");
+}
+
+ATF_TC_BODY(erfcf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(erfcf(x)) != 0);
+}
+
+ATF_TC(erfcf_inf_neg);
+ATF_TC_HEAD(erfcf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfcf(-Inf) == 2.0");
+}
+
+ATF_TC_BODY(erfcf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (erfcf(x) != 2.0)
+ atf_tc_fail_nonfatal("erfcf(-Inf) != 2.0");
+}
+
+ATF_TC(erfcf_inf_pos);
+ATF_TC_HEAD(erfcf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfcf(+Inf) == +0.0");
+}
+
+ATF_TC_BODY(erfcf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = erfcf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("erfcf(+Inf) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, erf_nan);
+ ATF_TP_ADD_TC(tp, erf_inf_neg);
+ ATF_TP_ADD_TC(tp, erf_inf_pos);
+ ATF_TP_ADD_TC(tp, erf_zero_neg);
+ ATF_TP_ADD_TC(tp, erf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, erff_nan);
+ ATF_TP_ADD_TC(tp, erff_inf_neg);
+ ATF_TP_ADD_TC(tp, erff_inf_pos);
+ ATF_TP_ADD_TC(tp, erff_zero_neg);
+ ATF_TP_ADD_TC(tp, erff_zero_pos);
+
+ ATF_TP_ADD_TC(tp, erfc_nan);
+ ATF_TP_ADD_TC(tp, erfc_inf_neg);
+ ATF_TP_ADD_TC(tp, erfc_inf_pos);
+
+ ATF_TP_ADD_TC(tp, erfcf_nan);
+ ATF_TP_ADD_TC(tp, erfcf_inf_neg);
+ ATF_TP_ADD_TC(tp, erfcf_inf_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_exp.c b/contrib/netbsd-tests/lib/libm/t_exp.c
new file mode 100644
index 0000000..7a8e9f8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_exp.c
@@ -0,0 +1,576 @@
+/* $NetBSD: t_exp.c,v 1.7 2014/03/17 11:08:11 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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 <math.h>
+#include "t_libm.h"
+
+/* y = exp(x) */
+static const struct {
+ double x;
+ double y;
+ double e;
+} exp_values[] = {
+ { -10, 0.4539992976248485e-4, 1e-4, },
+ { -5, 0.6737946999085467e-2, 1e-2, },
+ { -1, 0.3678794411714423, 1e-1, },
+ { -0.1, 0.9048374180359595, 1e-1, },
+ { 0, 1.0000000000000000, 1, },
+ { 0.1, 1.1051709180756477, 1, },
+ { 1, 2.7182818284590452, 1, },
+ { 5, 148.41315910257660, 1e2, },
+ { 10, 22026.465794806718, 1e4, },
+};
+
+/*
+ * exp2/exp2f(3)
+ */
+ATF_LIBM_TEST(exp2_is_nan, "Test exp2(x) == NaN")
+{
+#ifdef T_LIBM_NAN
+ T_LIBM_CHECK_NAN(0, exp2, T_LIBM_NAN);
+ T_LIBM_CHECK_NAN(0, exp2f, T_LIBM_NAN);
+#else
+ atf_tc_skip("no NaN on this machine");
+#endif
+}
+
+ATF_LIBM_TEST(exp2_is_plus_zero, "Test exp2(x) == +0.0")
+{
+#ifdef T_LIBM_MINUS_INF
+ T_LIBM_CHECK_PLUS_ZERO(0, exp2, T_LIBM_MINUS_INF);
+ T_LIBM_CHECK_PLUS_ZERO(0, exp2f, T_LIBM_MINUS_INF);
+#else
+ atf_tc_skip("no +/-Inf on this machine");
+#endif
+}
+
+ATF_LIBM_TEST(exp2_powers, "Test exp2(x) is correct for some integer x")
+{
+ static const struct {
+ double x;
+ double d_y;
+ double f_y;
+ } v[] = {
+ { +0.0, 1.0, 1.0 },
+ { -0.0, 1.0, 1.0 },
+ { 1, 0x1p1, 0x1p1 },
+ { 2, 0x1p2, 0x1p2 },
+ { 100, 0x1p100, 0x1p100 },
+ { 125, 0x1p125, 0x1p125 },
+ { 126, 0x1p126, 0x1p126 },
+#if __DBL_MAX_EXP__ > 129
+ { 127, 0x1p127, 0x1p127 },
+#endif
+#ifdef T_LIBM_PLUS_INF
+ { 128, 0x1p128, T_LIBM_PLUS_INF },
+ { 129, 0x1p129, T_LIBM_PLUS_INF },
+ { 1000, 0x1p1000, T_LIBM_PLUS_INF },
+ { 1020, 0x1p1020, T_LIBM_PLUS_INF },
+ { 1023, 0x1p1023, T_LIBM_PLUS_INF },
+ { 1024, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 1030, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 1050, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 2000, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 16383, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 16384, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 16385, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+#endif
+ { -1, 0x1p-1, 0x1p-1 },
+ { -2, 0x1p-2, 0x1p-2 },
+ { -100, 0x1p-100, 0x1p-100 },
+ { -127, 0x1p-127, 0x1p-127 },
+ { -128, 0x1p-128, 0x1p-128 },
+#if __LDBL_MIN_EXP__ < -129
+ { -300, 0x1p-300, 0.0},
+ { -400, 0x1p-400, 0.0},
+ {-1000, 0x1p-1000, 0.0},
+ {-1022, 0x1p-1022, 0.0},
+ /* These should be denormal numbers */
+ {-1023, 0x1p-1023, 0.0},
+ {-1024, 0x1p-1024, 0.0},
+ {-1040, 0x1p-1040, 0.0},
+ {-1060, 0x1p-1060, 0.0},
+ /* This is the smallest result gcc will allow */
+ {-1074, 0x1p-1074, 0.0},
+#endif
+ {-1075, 0x0, 0.0},
+ {-1080, 0x0, 0.0},
+ {-2000, 0x0, 0.0},
+ {-16382, 0x0, 0.0},
+ {-16383, 0x0, 0.0},
+ {-16384, 0x0, 0.0},
+ };
+ unsigned int i;
+
+#if defined(__FreeBSD__) && defined(__i386__)
+ atf_tc_expect_fail("a number of the assertions fail on i386");
+#endif
+
+ for (i = 0; i < __arraycount(v); i++) {
+ T_LIBM_CHECK(i, exp2, v[i].x, v[i].d_y, 0.0);
+ T_LIBM_CHECK(i, exp2f, v[i].x, v[i].f_y, 0.0);
+ }
+}
+
+ATF_LIBM_TEST(exp2_values, "Test exp2(x) is correct for some x")
+{
+ static const struct {
+ double x;
+ double y;
+ double d_eps;
+ double f_eps;
+ } v[] = {
+#if __DBL_MAX_EXP__ > 128
+ /* The largest double constant */
+ { 0x1.fffffffffffffp9, 0x1.ffffffffffd3ap1023,
+ 0x1p969, 0.0 },
+ /* The largest float constant */
+ { 0x1.fffffep6, 0x1.ffff4ep+127, 6e30, 0.0 },
+#endif
+#ifdef T_LIBM_PLUS_INF
+ { T_LIBM_PLUS_INF, T_LIBM_PLUS_INF, 0.0, 0.0 },
+#endif
+
+ /* The few values from the old tests */
+ /* Results from i386/amd64, d_eps needed on i386 */
+ { 1.1, 0x1.125fbee250664p+1, 0x1p-52, 0x1.8p-22 },
+ { 2.2, 0x1.2611186bae675p+2, 0x1p-51, 0x1.8p-21 },
+ { 3.3, 0x1.3b2c47bff8328p+3, 0x1p-50, 0x1.8p-20 },
+ { 4.4, 0x1.51cb453b9536ep+4, 0x1p-49, 0x1.8p-19 },
+ { 5.5, 0x1.6a09e667f3bcdp+5, 0x1p-48, 0x1.8p-18 },
+ { 6.6, 0x1.8406003b2ae5bp+6, 0x1p-47, 0x1.8p-17 },
+ /*
+ * These two currently fail for 'float'.
+ * 8.8 is definitely out by more than it should be.
+ */
+ { 7.7, 0x1.9fdf8bcce533ep+7, 0x1p-46, 0x1.8p-16 },
+ { 8.8, 0x1.bdb8cdadbe124p+8, 0x1p-45, 0x1.8p-15 },
+ };
+ unsigned int i;
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("Some of the cases produce failures on FreeBSD "
+ "due to the error epsilon being so small");
+#endif
+
+ for (i = 0; i < __arraycount(v); i++) {
+ T_LIBM_CHECK(i, exp2, v[i].x, v[i].y, v[i].d_eps);
+ if (i > 1)
+ T_LIBM_CHECK(i, exp2f, v[i].x, v[i].y, v[i].f_eps);
+ }
+}
+
+
+/*
+ * exp(3)
+ */
+ATF_TC(exp_nan);
+ATF_TC_HEAD(exp_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test exp(NaN) == NaN");
+}
+
+ATF_TC_BODY(exp_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ if (isnan(exp(x)) == 0)
+ atf_tc_fail_nonfatal("exp(NaN) != NaN");
+}
+
+ATF_TC(exp_inf_neg);
+ATF_TC_HEAD(exp_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test exp(-Inf) == +0.0");
+}
+
+ATF_TC_BODY(exp_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = exp(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("exp(-Inf) != +0.0");
+}
+
+ATF_TC(exp_inf_pos);
+ATF_TC_HEAD(exp_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test exp(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(exp_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = exp(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("exp(+Inf) != +Inf");
+}
+
+ATF_TC(exp_product);
+ATF_TC_HEAD(exp_product, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected exp(x)");
+}
+
+ATF_TC_BODY(exp_product, tc)
+{
+ double eps;
+ double x;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exp_values); i++) {
+ x = exp_values[i].x;
+ y = exp_values[i].y;
+ eps = 1e-15 * exp_values[i].e;
+
+ if (fabs(exp(x) - y) > eps)
+ atf_tc_fail_nonfatal("exp(%0.01f) != %18.18e", x, y);
+ }
+}
+
+ATF_TC(exp_zero_neg);
+ATF_TC_HEAD(exp_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test exp(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(exp_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ if (fabs(exp(x) - 1.0) > 0.0)
+ atf_tc_fail_nonfatal("exp(-0.0) != 1.0");
+}
+
+ATF_TC(exp_zero_pos);
+ATF_TC_HEAD(exp_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test exp(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(exp_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ if (fabs(exp(x) - 1.0) > 0.0)
+ atf_tc_fail_nonfatal("exp(+0.0) != 1.0");
+}
+
+/*
+ * expf(3)
+ */
+ATF_TC(expf_nan);
+ATF_TC_HEAD(expf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expf(NaN) == NaN");
+}
+
+ATF_TC_BODY(expf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ if (isnan(expf(x)) == 0)
+ atf_tc_fail_nonfatal("expf(NaN) != NaN");
+}
+
+ATF_TC(expf_inf_neg);
+ATF_TC_HEAD(expf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expf(-Inf) == +0.0");
+}
+
+ATF_TC_BODY(expf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = expf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expf(-Inf) != +0.0");
+}
+
+ATF_TC(expf_inf_pos);
+ATF_TC_HEAD(expf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(expf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = expf(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expf(+Inf) != +Inf");
+}
+
+ATF_TC(expf_product);
+ATF_TC_HEAD(expf_product, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected expf(x)");
+}
+
+ATF_TC_BODY(expf_product, tc)
+{
+ float eps;
+ float x;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exp_values); i++) {
+ x = exp_values[i].x;
+ y = exp_values[i].y;
+ eps = 1e-6 * exp_values[i].e;
+
+ if (fabsf(expf(x) - y) > eps)
+ atf_tc_fail_nonfatal("expf(%0.01f) != %18.18e", x, y);
+ }
+}
+
+ATF_TC(expf_zero_neg);
+ATF_TC_HEAD(expf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expf(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(expf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ if (fabsf(expf(x) - 1.0f) > 0.0)
+ atf_tc_fail_nonfatal("expf(-0.0) != 1.0");
+}
+
+ATF_TC(expf_zero_pos);
+ATF_TC_HEAD(expf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expf(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(expf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ if (fabsf(expf(x) - 1.0f) > 0.0)
+ atf_tc_fail_nonfatal("expf(+0.0) != 1.0");
+}
+
+/*
+ * expm1(3)
+ */
+ATF_TC(expm1_nan);
+ATF_TC_HEAD(expm1_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1(NaN) == NaN");
+}
+
+ATF_TC_BODY(expm1_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ if (isnan(expm1(x)) == 0)
+ atf_tc_fail_nonfatal("expm1(NaN) != NaN");
+}
+
+ATF_TC(expm1_inf_neg);
+ATF_TC_HEAD(expm1_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1(-Inf) == -1");
+}
+
+ATF_TC_BODY(expm1_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ if (expm1(x) != -1.0)
+ atf_tc_fail_nonfatal("expm1(-Inf) != -1.0");
+}
+
+ATF_TC(expm1_inf_pos);
+ATF_TC_HEAD(expm1_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(expm1_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = expm1(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expm1(+Inf) != +Inf");
+}
+
+ATF_TC(expm1_zero_neg);
+ATF_TC_HEAD(expm1_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(expm1_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = expm1(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("expm1(-0.0) != -0.0");
+}
+
+ATF_TC(expm1_zero_pos);
+ATF_TC_HEAD(expm1_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(expm1_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = expm1(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expm1(+0.0) != +0.0");
+}
+
+/*
+ * expm1f(3)
+ */
+ATF_TC(expm1f_nan);
+ATF_TC_HEAD(expm1f_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1f(NaN) == NaN");
+}
+
+ATF_TC_BODY(expm1f_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ if (isnan(expm1f(x)) == 0)
+ atf_tc_fail_nonfatal("expm1f(NaN) != NaN");
+}
+
+ATF_TC(expm1f_inf_neg);
+ATF_TC_HEAD(expm1f_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1f(-Inf) == -1");
+}
+
+ATF_TC_BODY(expm1f_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (expm1f(x) != -1.0)
+ atf_tc_fail_nonfatal("expm1f(-Inf) != -1.0");
+}
+
+ATF_TC(expm1f_inf_pos);
+ATF_TC_HEAD(expm1f_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1f(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(expm1f_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = expm1f(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expm1f(+Inf) != +Inf");
+}
+
+ATF_TC(expm1f_zero_neg);
+ATF_TC_HEAD(expm1f_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1f(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(expm1f_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = expm1f(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("expm1f(-0.0) != -0.0");
+}
+
+ATF_TC(expm1f_zero_pos);
+ATF_TC_HEAD(expm1f_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1f(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(expm1f_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = expm1f(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expm1f(+0.0) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, exp2_is_nan);
+ ATF_TP_ADD_TC(tp, exp2_is_plus_zero);
+ ATF_TP_ADD_TC(tp, exp2_values);
+ ATF_TP_ADD_TC(tp, exp2_powers);
+
+ ATF_TP_ADD_TC(tp, exp_nan);
+ ATF_TP_ADD_TC(tp, exp_inf_neg);
+ ATF_TP_ADD_TC(tp, exp_inf_pos);
+ ATF_TP_ADD_TC(tp, exp_product);
+ ATF_TP_ADD_TC(tp, exp_zero_neg);
+ ATF_TP_ADD_TC(tp, exp_zero_pos);
+
+ ATF_TP_ADD_TC(tp, expf_nan);
+ ATF_TP_ADD_TC(tp, expf_inf_neg);
+ ATF_TP_ADD_TC(tp, expf_inf_pos);
+ ATF_TP_ADD_TC(tp, expf_product);
+ ATF_TP_ADD_TC(tp, expf_zero_neg);
+ ATF_TP_ADD_TC(tp, expf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, expm1_nan);
+ ATF_TP_ADD_TC(tp, expm1_inf_neg);
+ ATF_TP_ADD_TC(tp, expm1_inf_pos);
+ ATF_TP_ADD_TC(tp, expm1_zero_neg);
+ ATF_TP_ADD_TC(tp, expm1_zero_pos);
+
+ ATF_TP_ADD_TC(tp, expm1f_nan);
+ ATF_TP_ADD_TC(tp, expm1f_inf_neg);
+ ATF_TP_ADD_TC(tp, expm1f_inf_pos);
+ ATF_TP_ADD_TC(tp, expm1f_zero_neg);
+ ATF_TP_ADD_TC(tp, expm1f_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_fmod.c b/contrib/netbsd-tests/lib/libm/t_fmod.c
new file mode 100644
index 0000000..7dac93d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_fmod.c
@@ -0,0 +1,63 @@
+/* $NetBSD: t_fmod.c,v 1.2 2014/02/27 17:26:02 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 <float.h>
+#include <math.h>
+
+ATF_TC(fmod);
+ATF_TC_HEAD(fmod, tc)
+{
+ atf_tc_set_md_var(tc, "descr","Check fmod family");
+}
+
+ATF_TC_BODY(fmod, tc)
+{
+ ATF_CHECK(fmodf(2.0, 1.0) == 0);
+ ATF_CHECK(fmod(2.0, 1.0) == 0);
+ ATF_CHECK(fmodl(2.0, 1.0) == 0);
+
+ ATF_CHECK(fmodf(2.0, 0.5) == 0);
+ ATF_CHECK(fmod(2.0, 0.5) == 0);
+ ATF_CHECK(fmodl(2.0, 0.5) == 0);
+
+ ATF_CHECK(fabsf(fmodf(1.0, 0.1) - 0.1f) <= 55 * FLT_EPSILON);
+ ATF_CHECK(fabs(fmod(1.0, 0.1) - 0.1) <= 55 * DBL_EPSILON);
+ ATF_CHECK(fabsl(fmodl(1.0, 0.1L) - 0.1L) <= 55 * LDBL_EPSILON);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fmod);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_infinity.c b/contrib/netbsd-tests/lib/libm/t_infinity.c
new file mode 100644
index 0000000..7ac1737
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_infinity.c
@@ -0,0 +1,119 @@
+/* $NetBSD: t_infinity.c,v 1.6 2012/09/26 07:24:38 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Martin Husemann <martin@NetBSD.org>.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_infinity.c,v 1.6 2012/09/26 07:24:38 jruoho Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <float.h>
+#include <stdlib.h>
+
+ATF_TC(infinity_float);
+ATF_TC_HEAD(infinity_float, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "check FPU generated infinite float values");
+}
+
+ATF_TC_BODY(infinity_float, tc)
+{
+ float v;
+
+ v = FLT_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+
+ v = -FLT_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+}
+
+ATF_TC(infinity_double);
+ATF_TC_HEAD(infinity_double, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "check FPU generated infinite double values");
+}
+
+ATF_TC_BODY(infinity_double, tc)
+{
+ double v;
+
+ v = DBL_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+
+ v = -DBL_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+}
+
+ATF_TC(infinity_long_double);
+ATF_TC_HEAD(infinity_long_double, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "check FPU generated infinite long double values");
+}
+
+ATF_TC_BODY(infinity_long_double, tc)
+{
+
+#ifndef LDBL_MAX
+ atf_tc_skip("no long double support on this architecture");
+ return;
+#else
+ long double v;
+
+ v = LDBL_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+
+ v = -LDBL_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, infinity_float);
+ ATF_TP_ADD_TC(tp, infinity_double);
+ ATF_TP_ADD_TC(tp, infinity_long_double);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_ldexp.c b/contrib/netbsd-tests/lib/libm/t_ldexp.c
new file mode 100644
index 0000000..eaf8a4b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_ldexp.c
@@ -0,0 +1,480 @@
+/* $NetBSD: t_ldexp.c,v 1.14 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_ldexp.c,v 1.14 2014/11/04 00:20:19 justin Exp $");
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+
+#include <math.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#define SKIP 9999
+#define FORMAT "%23.23lg"
+
+static const int exps[] = { 0, 1, -1, 100, -100 };
+
+struct ldexp_test {
+ double x;
+ int exp1;
+ int exp2;
+ const char *result;
+};
+
+struct ldexp_test ldexp_basic[] = {
+ { 1.0, 5, SKIP, " 32" },
+ { 1.0, 1022, SKIP, "4.4942328371557897693233e+307" },
+ { 1.0, 1023, -1, "4.4942328371557897693233e+307" },
+ { 1.0, 1023, SKIP, "8.9884656743115795386465e+307" },
+ { 1.0, 1022, 1, "8.9884656743115795386465e+307" },
+ { 1.0, -1022, 2045, "8.9884656743115795386465e+307" },
+ { 1.0, -5, SKIP, " 0.03125" },
+ { 1.0, -1021, SKIP, "4.4501477170144027661805e-308" },
+ { 1.0, -1022, 1, "4.4501477170144027661805e-308" },
+ { 1.0, -1022, SKIP, "2.2250738585072013830902e-308" },
+ { 1.0, -1021, -1, "2.2250738585072013830902e-308" },
+ { 1.0, 1023, -2045, "2.2250738585072013830902e-308" },
+ { 1.0, 1023, -1023, " 1" },
+ { 1.0, -1022, 1022, " 1" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_zero[] = {
+ { 0.0, -1, SKIP, " 0" },
+ { 0.0, 0, SKIP, " 0" },
+ { 0.0, 1, SKIP, " 0" },
+ { 0.0, 1024, SKIP, " 0" },
+ { 0.0, 1025, SKIP, " 0" },
+ { 0.0, -1023, SKIP, " 0" },
+ { 0.0, -1024, SKIP, " 0" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_infinity[] = {
+ { 1.0, 1024, -1, " inf" },
+ { 1.0, 1024, 0, " inf" },
+ { 1.0, 1024, 1, " inf" },
+ { -1.0, 1024, -1, " -inf" },
+ { -1.0, 1024, 0, " -inf" },
+ { -1.0, 1024, 1, " -inf" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_overflow[] = {
+ { 1.0, 1024, SKIP, " inf" },
+ { 1.0, 1023, 1, " inf" },
+ { 1.0, -1022, 2046, " inf" },
+ { 1.0, 1025, SKIP, " inf" },
+ { -1.0, 1024, SKIP, " -inf" },
+ { -1.0, 1023, 1, " -inf" },
+ { -1.0, -1022, 2046, " -inf" },
+ { -1.0, 1025, SKIP, " -inf" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_denormal[] = {
+ { 1.0, -1023, SKIP, "1.1125369292536006915451e-308" },
+ { 1.0, -1022, -1, "1.1125369292536006915451e-308" },
+ { 1.0, 1023, -2046, "1.1125369292536006915451e-308" },
+ { 1.0, -1024, SKIP, "5.5626846462680034577256e-309" },
+ { 1.0, -1074, SKIP, "4.9406564584124654417657e-324" },
+ { -1.0, -1023, SKIP, "-1.1125369292536006915451e-308" },
+ { -1.0, -1022, -1, "-1.1125369292536006915451e-308" },
+ { -1.0, 1023, -2046, "-1.1125369292536006915451e-308" },
+ { -1.0, -1024, SKIP, "-5.5626846462680034577256e-309" },
+ { -1.0, -1074, SKIP, "-4.9406564584124654417657e-324" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_underflow[] = {
+ { 1.0, -1075, SKIP, " 0" },
+ { 1.0, -1074, -1, " 0" },
+ { 1.0, 1023, -2098, " 0" },
+ { 1.0, -1076, SKIP, " 0" },
+ { -1.0, -1075, SKIP, " -0" },
+ { -1.0, -1074, -1, " -0" },
+ { -1.0, 1023, -2098, " -0" },
+ { -1.0, -1076, SKIP, " -0" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_denormal_large[] = {
+ { 1.0, -1028, 1024, " 0.0625" },
+ { 1.0, -1028, 1025, " 0.125" },
+ { 1.0, -1028, 1026, " 0.25" },
+ { 1.0, -1028, 1027, " 0.5" },
+ { 1.0, -1028, 1028, " 1" },
+ { 1.0, -1028, 1029, " 2" },
+ { 1.0, -1028, 1030, " 4" },
+ { 1.0, -1028, 1040, " 4096" },
+ { 1.0, -1028, 1050, " 4194304" },
+ { 1.0, -1028, 1060, " 4294967296" },
+ { 1.0, -1028, 1100, " 4722366482869645213696" },
+ { 1.0, -1028, 1200, "5.9863107065073783529623e+51" },
+ { 1.0, -1028, 1300, "7.5885503602567541832791e+81" },
+ { 1.0, -1028, 1400, "9.6196304190416209014353e+111" },
+ { 1.0, -1028, 1500, "1.2194330274671844653834e+142" },
+ { 1.0, -1028, 1600, "1.5458150092069033378781e+172" },
+ { 1.0, -1028, 1700, "1.9595533242629369747791e+202" },
+ { 1.0, -1028, 1800, "2.4840289476811342962384e+232" },
+ { 1.0, -1028, 1900, "3.1488807865122869393369e+262" },
+ { 1.0, -1028, 2000, "3.9916806190694396233127e+292" },
+ { 1.0, -1028, 2046, "2.808895523222368605827e+306" },
+ { 1.0, -1028, 2047, "5.6177910464447372116541e+306" },
+ { 1.0, -1028, 2048, "1.1235582092889474423308e+307" },
+ { 1.0, -1028, 2049, "2.2471164185778948846616e+307" },
+ { 1.0, -1028, 2050, "4.4942328371557897693233e+307" },
+ { 1.0, -1028, 2051, "8.9884656743115795386465e+307" },
+ { 0, 0, 0, NULL }
+};
+
+static void
+run_test(struct ldexp_test *table)
+{
+ char outbuf[64];
+ size_t i;
+ double v;
+
+ for (i = 0; table->result != NULL; table++, i++) {
+
+ v = ldexp(table->x, table->exp1);
+
+ if (table->exp2 == SKIP)
+ continue;
+
+ v = ldexp(v, table->exp2);
+
+ (void)snprintf(outbuf, sizeof(outbuf), FORMAT, v);
+
+ ATF_CHECK_STREQ_MSG(table->result, outbuf,
+ "Entry %zu:\n\tExp: \"%s\"\n\tAct: \"%s\"",
+ i, table->result, outbuf);
+ }
+}
+
+/*
+ * ldexp(3)
+ */
+ATF_TC(ldexp_exp2);
+ATF_TC_HEAD(ldexp_exp2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(x, n) == x * exp2(n)");
+}
+
+ATF_TC_BODY(ldexp_exp2, tc)
+{
+ const double n[] = { 1, 2, 3, 10, 50, 100 };
+#if __DBL_MIN_10_EXP__ <= -40
+ const double eps = 1.0e-40;
+#else
+ const double eps = __DBL_MIN__*4.0;
+#endif
+ const double x = 12.0;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(n); i++) {
+
+ y = ldexp(x, n[i]);
+
+ if (fabs(y - (x * exp2(n[i]))) > eps) {
+ atf_tc_fail_nonfatal("ldexp(%0.01f, %0.01f) "
+ "!= %0.01f * exp2(%0.01f)", x, n[i], x, n[i]);
+ }
+ }
+}
+
+ATF_TC(ldexp_nan);
+ATF_TC_HEAD(ldexp_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(NaN) == NaN");
+}
+
+ATF_TC_BODY(ldexp_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(isnan(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexp(x, exps[i]);
+ ATF_CHECK(isnan(y) != 0);
+ }
+}
+
+ATF_TC(ldexp_inf_neg);
+ATF_TC_HEAD(ldexp_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(ldexp_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(ldexp(x, exps[i]) == x);
+}
+
+ATF_TC(ldexp_inf_pos);
+ATF_TC_HEAD(ldexp_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(ldexp_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(ldexp(x, exps[i]) == x);
+}
+
+ATF_TC(ldexp_zero_neg);
+ATF_TC_HEAD(ldexp_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(ldexp_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexp(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) != 0);
+ }
+}
+
+ATF_TC(ldexp_zero_pos);
+ATF_TC_HEAD(ldexp_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(ldexp_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) == 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexp(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) == 0);
+ }
+}
+
+/*
+ * ldexpf(3)
+ */
+
+ATF_TC(ldexpf_exp2f);
+ATF_TC_HEAD(ldexpf_exp2f, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(x, n) == x * exp2f(n)");
+}
+
+ATF_TC_BODY(ldexpf_exp2f, tc)
+{
+ const float n[] = { 1, 2, 3, 10, 50, 100 };
+ const float eps = 1.0e-9;
+ const float x = 12.0;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(n); i++) {
+
+ y = ldexpf(x, n[i]);
+
+ if (fabsf(y - (x * exp2f(n[i]))) > eps) {
+ atf_tc_fail_nonfatal("ldexpf(%0.01f, %0.01f) "
+ "!= %0.01f * exp2f(%0.01f)", x, n[i], x, n[i]);
+ }
+ }
+}
+
+ATF_TC(ldexpf_nan);
+ATF_TC_HEAD(ldexpf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(NaN) == NaN");
+}
+
+ATF_TC_BODY(ldexpf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(isnan(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexpf(x, exps[i]);
+ ATF_CHECK(isnan(y) != 0);
+ }
+}
+
+ATF_TC(ldexpf_inf_neg);
+ATF_TC_HEAD(ldexpf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(ldexpf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(ldexpf(x, exps[i]) == x);
+}
+
+ATF_TC(ldexpf_inf_pos);
+ATF_TC_HEAD(ldexpf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(ldexpf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(ldexpf(x, exps[i]) == x);
+}
+
+ATF_TC(ldexpf_zero_neg);
+ATF_TC_HEAD(ldexpf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(ldexpf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexpf(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) != 0);
+ }
+}
+
+ATF_TC(ldexpf_zero_pos);
+ATF_TC_HEAD(ldexpf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(ldexpf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) == 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexpf(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) == 0);
+ }
+}
+
+#define TEST(name, desc) \
+ ATF_TC(name); \
+ ATF_TC_HEAD(name, tc) \
+ { \
+ \
+ atf_tc_set_md_var(tc, "descr", \
+ "Test ldexp(3) for " ___STRING(desc)); \
+ } \
+ ATF_TC_BODY(name, tc) \
+ { \
+ if (strcmp("vax", MACHINE_ARCH) == 0) \
+ atf_tc_skip("Test not valid for " MACHINE_ARCH); \
+ run_test(name); \
+ }
+
+TEST(ldexp_basic, basics)
+TEST(ldexp_zero, zero)
+TEST(ldexp_infinity, infinity)
+TEST(ldexp_overflow, overflow)
+TEST(ldexp_denormal, denormal)
+TEST(ldexp_denormal_large, large)
+TEST(ldexp_underflow, underflow)
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, ldexp_basic);
+ ATF_TP_ADD_TC(tp, ldexp_zero);
+ ATF_TP_ADD_TC(tp, ldexp_infinity);
+ ATF_TP_ADD_TC(tp, ldexp_overflow);
+ ATF_TP_ADD_TC(tp, ldexp_denormal);
+ ATF_TP_ADD_TC(tp, ldexp_underflow);
+ ATF_TP_ADD_TC(tp, ldexp_denormal_large);
+
+ ATF_TP_ADD_TC(tp, ldexp_exp2);
+ ATF_TP_ADD_TC(tp, ldexp_nan);
+ ATF_TP_ADD_TC(tp, ldexp_inf_neg);
+ ATF_TP_ADD_TC(tp, ldexp_inf_pos);
+ ATF_TP_ADD_TC(tp, ldexp_zero_neg);
+ ATF_TP_ADD_TC(tp, ldexp_zero_pos);
+
+ ATF_TP_ADD_TC(tp, ldexpf_exp2f);
+ ATF_TP_ADD_TC(tp, ldexpf_nan);
+ ATF_TP_ADD_TC(tp, ldexpf_inf_neg);
+ ATF_TP_ADD_TC(tp, ldexpf_inf_pos);
+ ATF_TP_ADD_TC(tp, ldexpf_zero_neg);
+ ATF_TP_ADD_TC(tp, ldexpf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_libm.h b/contrib/netbsd-tests/lib/libm/t_libm.h
new file mode 100644
index 0000000..34e3cb2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_libm.h
@@ -0,0 +1,62 @@
+/* $NetBSD: t_libm.h,v 1.6 2014/03/25 17:30:14 joerg Exp $ */
+
+/*
+ * Check result of fn(arg) is correct within the bounds.
+ * Should be ok to do the checks using 'double' for 'float' functions.
+ * On i386 float and double values are returned on the x87 stack and might
+ * be out of range for the function - so save and print as 'long double'.
+ * (otherwise you can get 'inf != inf' reported!)
+ */
+#define T_LIBM_CHECK(subtest, fn, arg, expect_, epsilon_) do { \
+ long double epsilon = epsilon_; \
+ long double expect = expect_; \
+ long double r = fn(arg); \
+ long double e = fabsl(r - expect); \
+ if (r != expect && e > epsilon) \
+ atf_tc_fail_nonfatal( \
+ "subtest %u: " #fn "(%g) is %Lg (%.14La) " \
+ "not %Lg (%.13La), error %Lg (%.6La) > %Lg", \
+ subtest, arg, r, r, expect, expect, e, e, epsilon); \
+ } while (0)
+
+/* Check that the result of fn(arg) is NaN */
+#ifndef __vax__
+#define T_LIBM_CHECK_NAN(subtest, fn, arg) do { \
+ double r = fn(arg); \
+ if (!isnan(r)) \
+ atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not NaN", \
+ subtest, arg, r); \
+ } while (0)
+#else
+/* vax doesn't support NaN */
+#define T_LIBM_CHECK_NAN(subtest, fn, arg) (void)(arg)
+#endif
+
+/* Check that the result of fn(arg) is +0.0 */
+#define T_LIBM_CHECK_PLUS_ZERO(subtest, fn, arg) do { \
+ double r = fn(arg); \
+ if (fabs(r) > 0.0 || signbit(r) != 0) \
+ atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not +0.0", \
+ subtest, arg, r); \
+ } while (0)
+
+/* Check that the result of fn(arg) is -0.0 */
+#define T_LIBM_CHECK_MINUS_ZERO(subtest, fn, arg) do { \
+ double r = fn(arg); \
+ if (fabs(r) > 0.0 || signbit(r) == 0) \
+ atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not -0.0", \
+ subtest, arg, r); \
+ } while (0)
+
+/* Some useful constants (for test vectors) */
+#ifndef __vax__ /* no NAN nor +/- INF on vax */
+#define T_LIBM_NAN (0.0 / 0.0)
+#define T_LIBM_PLUS_INF (+1.0 / 0.0)
+#define T_LIBM_MINUS_INF (-1.0 / 0.0)
+#endif
+
+/* One line definition of a simple test */
+#define ATF_LIBM_TEST(name, description) \
+ATF_TC(name); \
+ATF_TC_HEAD(name, tc) { atf_tc_set_md_var(tc, "descr", description); } \
+ATF_TC_BODY(name, tc)
diff --git a/contrib/netbsd-tests/lib/libm/t_log.c b/contrib/netbsd-tests/lib/libm/t_log.c
new file mode 100644
index 0000000..0164233
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_log.c
@@ -0,0 +1,884 @@
+/* $NetBSD: t_log.c,v 1.12 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_log.c,v 1.12 2014/11/04 00:20:19 justin Exp $");
+
+#include <atf-c.h>
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * log10(3)
+ */
+ATF_TC(log10_base);
+ATF_TC_HEAD(log10_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(10) == 1");
+}
+
+ATF_TC_BODY(log10_base, tc)
+{
+ ATF_CHECK(log10(10.0) == 1.0);
+}
+
+ATF_TC(log10_nan);
+ATF_TC_HEAD(log10_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(NaN) == NaN");
+}
+
+ATF_TC_BODY(log10_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log10(x)) != 0);
+}
+
+ATF_TC(log10_inf_neg);
+ATF_TC_HEAD(log10_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log10_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ const double y = log10(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(log10_inf_pos);
+ATF_TC_HEAD(log10_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log10_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(log10(x) == x);
+}
+
+ATF_TC(log10_one_pos);
+ATF_TC_HEAD(log10_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(1.0) == +0.0");
+}
+
+ATF_TC_BODY(log10_one_pos, tc)
+{
+ const double x = log10(1.0);
+ const double y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(log10_zero_neg);
+ATF_TC_HEAD(log10_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(-0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log10_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(log10(x) == -HUGE_VAL);
+}
+
+ATF_TC(log10_zero_pos);
+ATF_TC_HEAD(log10_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(+0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log10_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(log10(x) == -HUGE_VAL);
+}
+
+/*
+ * log10f(3)
+ */
+ATF_TC(log10f_base);
+ATF_TC_HEAD(log10f_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(10) == 1");
+}
+
+ATF_TC_BODY(log10f_base, tc)
+{
+ ATF_CHECK(log10f(10.0) == 1.0);
+}
+
+ATF_TC(log10f_nan);
+ATF_TC_HEAD(log10f_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(NaN) == NaN");
+}
+
+ATF_TC_BODY(log10f_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log10f(x)) != 0);
+}
+
+ATF_TC(log10f_inf_neg);
+ATF_TC_HEAD(log10f_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log10f_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ const float y = log10f(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(log10f_inf_pos);
+ATF_TC_HEAD(log10f_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log10f_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+#if defined(__alpha__)
+ atf_tc_expect_fail("PR port-alpha/46301");
+#endif
+
+ ATF_CHECK(log10f(x) == x);
+}
+
+ATF_TC(log10f_one_pos);
+ATF_TC_HEAD(log10f_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(1.0) == +0.0");
+}
+
+ATF_TC_BODY(log10f_one_pos, tc)
+{
+ const float x = log10f(1.0);
+ const float y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(log10f_zero_neg);
+ATF_TC_HEAD(log10f_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(-0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(log10f_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(log10f(x) == -HUGE_VALF);
+}
+
+ATF_TC(log10f_zero_pos);
+ATF_TC_HEAD(log10f_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(+0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(log10f_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(log10f(x) == -HUGE_VALF);
+}
+
+/*
+ * log1p(3)
+ */
+ATF_TC(log1p_nan);
+ATF_TC_HEAD(log1p_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(NaN) == NaN");
+}
+
+ATF_TC_BODY(log1p_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log1p(x)) != 0);
+}
+
+ATF_TC(log1p_inf_neg);
+ATF_TC_HEAD(log1p_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log1p_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ const double y = log1p(x);
+
+ if (isnan(y) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("log1p(-Inf) != NaN");
+ }
+}
+
+ATF_TC(log1p_inf_pos);
+ATF_TC_HEAD(log1p_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log1p_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(log1p(x) == x);
+}
+
+ATF_TC(log1p_one_neg);
+ATF_TC_HEAD(log1p_one_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(-1.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log1p_one_neg, tc)
+{
+ const double x = log1p(-1.0);
+
+ if (x != -HUGE_VAL) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("log1p(-1.0) != -HUGE_VAL");
+ }
+}
+
+ATF_TC(log1p_zero_neg);
+ATF_TC_HEAD(log1p_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(log1p_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(log1p(x) == x);
+}
+
+ATF_TC(log1p_zero_pos);
+ATF_TC_HEAD(log1p_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(log1p_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(log1p(x) == x);
+}
+
+/*
+ * log1pf(3)
+ */
+ATF_TC(log1pf_nan);
+ATF_TC_HEAD(log1pf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(NaN) == NaN");
+}
+
+ATF_TC_BODY(log1pf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log1pf(x)) != 0);
+}
+
+ATF_TC(log1pf_inf_neg);
+ATF_TC_HEAD(log1pf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log1pf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ const float y = log1pf(x);
+
+ if (isnan(y) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("log1pf(-Inf) != NaN");
+ }
+}
+
+ATF_TC(log1pf_inf_pos);
+ATF_TC_HEAD(log1pf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log1pf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ ATF_CHECK(log1pf(x) == x);
+}
+
+ATF_TC(log1pf_one_neg);
+ATF_TC_HEAD(log1pf_one_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(-1.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(log1pf_one_neg, tc)
+{
+ const float x = log1pf(-1.0);
+
+ if (x != -HUGE_VALF) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("log1pf(-1.0) != -HUGE_VALF");
+ }
+}
+
+ATF_TC(log1pf_zero_neg);
+ATF_TC_HEAD(log1pf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(log1pf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(log1pf(x) == x);
+}
+
+ATF_TC(log1pf_zero_pos);
+ATF_TC_HEAD(log1pf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(log1pf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(log1pf(x) == x);
+}
+
+/*
+ * log2(3)
+ */
+ATF_TC(log2_base);
+ATF_TC_HEAD(log2_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(2) == 1");
+}
+
+ATF_TC_BODY(log2_base, tc)
+{
+ ATF_CHECK(log2(2.0) == 1.0);
+}
+
+ATF_TC(log2_nan);
+ATF_TC_HEAD(log2_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(NaN) == NaN");
+}
+
+ATF_TC_BODY(log2_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log2(x)) != 0);
+}
+
+ATF_TC(log2_inf_neg);
+ATF_TC_HEAD(log2_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log2_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ const double y = log2(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(log2_inf_pos);
+ATF_TC_HEAD(log2_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log2_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(log2(x) == x);
+}
+
+ATF_TC(log2_one_pos);
+ATF_TC_HEAD(log2_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(1.0) == +0.0");
+}
+
+ATF_TC_BODY(log2_one_pos, tc)
+{
+ const double x = log2(1.0);
+ const double y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(log2_zero_neg);
+ATF_TC_HEAD(log2_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(-0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log2_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(log2(x) == -HUGE_VAL);
+}
+
+ATF_TC(log2_zero_pos);
+ATF_TC_HEAD(log2_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(+0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log2_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(log2(x) == -HUGE_VAL);
+}
+
+/*
+ * log2f(3)
+ */
+ATF_TC(log2f_base);
+ATF_TC_HEAD(log2f_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(2) == 1");
+}
+
+ATF_TC_BODY(log2f_base, tc)
+{
+ ATF_CHECK(log2f(2.0) == 1.0);
+}
+
+ATF_TC(log2f_nan);
+ATF_TC_HEAD(log2f_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(NaN) == NaN");
+}
+
+ATF_TC_BODY(log2f_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log2f(x)) != 0);
+}
+
+ATF_TC(log2f_inf_neg);
+ATF_TC_HEAD(log2f_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log2f_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ const float y = log2f(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(log2f_inf_pos);
+ATF_TC_HEAD(log2f_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log2f_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+#if defined(__alpha__)
+ atf_tc_expect_fail("PR port-alpha/46301");
+#endif
+
+ ATF_CHECK(log2f(x) == x);
+}
+
+ATF_TC(log2f_one_pos);
+ATF_TC_HEAD(log2f_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(1.0) == +0.0");
+}
+
+ATF_TC_BODY(log2f_one_pos, tc)
+{
+ const float x = log2f(1.0);
+ const float y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(log2f_zero_neg);
+ATF_TC_HEAD(log2f_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(-0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(log2f_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(log2f(x) == -HUGE_VALF);
+}
+
+ATF_TC(log2f_zero_pos);
+ATF_TC_HEAD(log2f_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(+0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(log2f_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(log2f(x) == -HUGE_VALF);
+}
+
+/*
+ * log(3)
+ */
+ATF_TC(log_base);
+ATF_TC_HEAD(log_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(e) == 1");
+}
+
+ATF_TC_BODY(log_base, tc)
+{
+ const double eps = 1.0e-38;
+
+ if (fabs(log(M_E) - 1.0) > eps)
+ atf_tc_fail_nonfatal("log(e) != 1");
+}
+
+ATF_TC(log_nan);
+ATF_TC_HEAD(log_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(NaN) == NaN");
+}
+
+ATF_TC_BODY(log_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log(x)) != 0);
+}
+
+ATF_TC(log_inf_neg);
+ATF_TC_HEAD(log_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ const double y = log(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(log_inf_pos);
+ATF_TC_HEAD(log_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(log(x) == x);
+}
+
+ATF_TC(log_one_pos);
+ATF_TC_HEAD(log_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(1.0) == +0.0");
+}
+
+ATF_TC_BODY(log_one_pos, tc)
+{
+ const double x = log(1.0);
+ const double y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(log_zero_neg);
+ATF_TC_HEAD(log_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(-0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(log(x) == -HUGE_VAL);
+}
+
+ATF_TC(log_zero_pos);
+ATF_TC_HEAD(log_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(+0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(log(x) == -HUGE_VAL);
+}
+
+/*
+ * logf(3)
+ */
+ATF_TC(logf_base);
+ATF_TC_HEAD(logf_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(e) == 1");
+}
+
+ATF_TC_BODY(logf_base, tc)
+{
+ const float eps = 1.0e-7;
+
+ if (fabsf(logf(M_E) - 1.0f) > eps)
+ atf_tc_fail_nonfatal("logf(e) != 1");
+}
+
+ATF_TC(logf_nan);
+ATF_TC_HEAD(logf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(NaN) == NaN");
+}
+
+ATF_TC_BODY(logf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(logf(x)) != 0);
+}
+
+ATF_TC(logf_inf_neg);
+ATF_TC_HEAD(logf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(logf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ const float y = logf(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(logf_inf_pos);
+ATF_TC_HEAD(logf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(logf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+#if defined(__alpha__)
+ atf_tc_expect_fail("PR port-alpha/46301");
+#endif
+
+ ATF_CHECK(logf(x) == x);
+}
+
+ATF_TC(logf_one_pos);
+ATF_TC_HEAD(logf_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(1.0) == +0.0");
+}
+
+ATF_TC_BODY(logf_one_pos, tc)
+{
+ const float x = logf(1.0);
+ const float y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(logf_zero_neg);
+ATF_TC_HEAD(logf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(-0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(logf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(logf(x) == -HUGE_VALF);
+}
+
+ATF_TC(logf_zero_pos);
+ATF_TC_HEAD(logf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(+0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(logf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(logf(x) == -HUGE_VALF);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, log10_base);
+ ATF_TP_ADD_TC(tp, log10_nan);
+ ATF_TP_ADD_TC(tp, log10_inf_neg);
+ ATF_TP_ADD_TC(tp, log10_inf_pos);
+ ATF_TP_ADD_TC(tp, log10_one_pos);
+ ATF_TP_ADD_TC(tp, log10_zero_neg);
+ ATF_TP_ADD_TC(tp, log10_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log10f_base);
+ ATF_TP_ADD_TC(tp, log10f_nan);
+ ATF_TP_ADD_TC(tp, log10f_inf_neg);
+ ATF_TP_ADD_TC(tp, log10f_inf_pos);
+ ATF_TP_ADD_TC(tp, log10f_one_pos);
+ ATF_TP_ADD_TC(tp, log10f_zero_neg);
+ ATF_TP_ADD_TC(tp, log10f_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log1p_nan);
+ ATF_TP_ADD_TC(tp, log1p_inf_neg);
+ ATF_TP_ADD_TC(tp, log1p_inf_pos);
+ ATF_TP_ADD_TC(tp, log1p_one_neg);
+ ATF_TP_ADD_TC(tp, log1p_zero_neg);
+ ATF_TP_ADD_TC(tp, log1p_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log1pf_nan);
+ ATF_TP_ADD_TC(tp, log1pf_inf_neg);
+ ATF_TP_ADD_TC(tp, log1pf_inf_pos);
+ ATF_TP_ADD_TC(tp, log1pf_one_neg);
+ ATF_TP_ADD_TC(tp, log1pf_zero_neg);
+ ATF_TP_ADD_TC(tp, log1pf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log2_base);
+ ATF_TP_ADD_TC(tp, log2_nan);
+ ATF_TP_ADD_TC(tp, log2_inf_neg);
+ ATF_TP_ADD_TC(tp, log2_inf_pos);
+ ATF_TP_ADD_TC(tp, log2_one_pos);
+ ATF_TP_ADD_TC(tp, log2_zero_neg);
+ ATF_TP_ADD_TC(tp, log2_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log2f_base);
+ ATF_TP_ADD_TC(tp, log2f_nan);
+ ATF_TP_ADD_TC(tp, log2f_inf_neg);
+ ATF_TP_ADD_TC(tp, log2f_inf_pos);
+ ATF_TP_ADD_TC(tp, log2f_one_pos);
+ ATF_TP_ADD_TC(tp, log2f_zero_neg);
+ ATF_TP_ADD_TC(tp, log2f_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log_base);
+ ATF_TP_ADD_TC(tp, log_nan);
+ ATF_TP_ADD_TC(tp, log_inf_neg);
+ ATF_TP_ADD_TC(tp, log_inf_pos);
+ ATF_TP_ADD_TC(tp, log_one_pos);
+ ATF_TP_ADD_TC(tp, log_zero_neg);
+ ATF_TP_ADD_TC(tp, log_zero_pos);
+
+ ATF_TP_ADD_TC(tp, logf_base);
+ ATF_TP_ADD_TC(tp, logf_nan);
+ ATF_TP_ADD_TC(tp, logf_inf_neg);
+ ATF_TP_ADD_TC(tp, logf_inf_pos);
+ ATF_TP_ADD_TC(tp, logf_one_pos);
+ ATF_TP_ADD_TC(tp, logf_zero_neg);
+ ATF_TP_ADD_TC(tp, logf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_modf.c b/contrib/netbsd-tests/lib/libm/t_modf.c
new file mode 100644
index 0000000..a856b15
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_modf.c
@@ -0,0 +1,68 @@
+/* $NetBSD: t_modf.c,v 1.1 2014/06/16 12:54:43 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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 <float.h>
+#include <math.h>
+
+ATF_TC(modf);
+ATF_TC_HEAD(modf, tc)
+{
+ atf_tc_set_md_var(tc, "descr","Check modf family");
+}
+
+ATF_TC_BODY(modf, tc)
+{
+ float basef;
+ double base;
+ long double basel;
+ ATF_CHECK(modff(1.0, &basef) == 0.0);
+ ATF_CHECK(basef == 1.0);
+ ATF_CHECK(modf(1.0, &base) == 0.0);
+ ATF_CHECK(base == 1.0);
+ ATF_CHECK(modfl(1.0, &basel) == 0.0);
+ ATF_CHECK(basel == 1.0);
+
+ ATF_CHECK(modff(-1 - FLT_EPSILON, &basef) == -FLT_EPSILON);
+ ATF_CHECK(basef == -1.0);
+ ATF_CHECK(modf(-1 - DBL_EPSILON, &base) == -DBL_EPSILON);
+ ATF_CHECK(base == -1.0);
+ ATF_CHECK(modfl(-1 - LDBL_EPSILON, &basel) == -LDBL_EPSILON);
+ ATF_CHECK(basel == -1.0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, modf);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_pow.c b/contrib/netbsd-tests/lib/libm/t_pow.c
new file mode 100644
index 0000000..a8ae6f0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_pow.c
@@ -0,0 +1,673 @@
+/* $NetBSD: t_pow.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_pow.c,v 1.3 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+
+#ifdef __FreeBSD__
+#define isinff isinf
+#endif
+
+/*
+ * pow(3)
+ */
+ATF_TC(pow_nan_x);
+ATF_TC_HEAD(pow_nan_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(NaN, y) == NaN");
+}
+
+ATF_TC_BODY(pow_nan_x, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(pow(x, 2.0)) != 0);
+}
+
+ATF_TC(pow_nan_y);
+ATF_TC_HEAD(pow_nan_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(x, NaN) == NaN");
+}
+
+ATF_TC_BODY(pow_nan_y, tc)
+{
+ const double y = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(pow(2.0, y)) != 0);
+}
+
+ATF_TC(pow_inf_neg_x);
+ATF_TC_HEAD(pow_inf_neg_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(-Inf, y) == +-Inf || +-0.0");
+}
+
+ATF_TC_BODY(pow_inf_neg_x, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double z;
+
+ /*
+ * If y is odd, y > 0, and x is -Inf, -Inf is returned.
+ * If y is even, y > 0, and x is -Inf, +Inf is returned.
+ */
+ z = pow(x, 3.0);
+
+ if (isinf(z) == 0 || signbit(z) == 0)
+ atf_tc_fail_nonfatal("pow(-Inf, 3.0) != -Inf");
+
+ z = pow(x, 4.0);
+
+ if (isinf(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(-Inf, 4.0) != +Inf");
+
+ /*
+ * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
+ * If y is even, y < 0, and x is -Inf, +0.0 is returned.
+ */
+ z = pow(x, -3.0);
+
+ if (fabs(z) > 0.0 || signbit(z) == 0)
+ atf_tc_fail_nonfatal("pow(-Inf, -3.0) != -0.0");
+
+ z = pow(x, -4.0);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(-Inf -4.0) != +0.0");
+}
+
+ATF_TC(pow_inf_neg_y);
+ATF_TC_HEAD(pow_inf_neg_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(x, -Inf) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(pow_inf_neg_y, tc)
+{
+ const double y = -1.0L / 0.0L;
+ double z;
+
+ /*
+ * If |x| < 1 and y is -Inf, +Inf is returned.
+ * If |x| > 1 and y is -Inf, +0.0 is returned.
+ */
+ z = pow(0.1, y);
+
+ if (isinf(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(0.1, -Inf) != +Inf");
+
+ z = pow(1.1, y);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(1.1, -Inf) != +0.0");
+}
+
+ATF_TC(pow_inf_pos_x);
+ATF_TC_HEAD(pow_inf_pos_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(+Inf, y) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(pow_inf_pos_x, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double z;
+
+ /*
+ * For y < 0, if x is +Inf, +0.0 is returned.
+ * For y > 0, if x is +Inf, +Inf is returned.
+ */
+ z = pow(x, -2.0);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(+Inf, -2.0) != +0.0");
+
+ z = pow(x, 2.0);
+
+ if (isinf(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(+Inf, 2.0) != +Inf");
+}
+
+ATF_TC(pow_inf_pos_y);
+ATF_TC_HEAD(pow_inf_pos_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(x, +Inf) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(pow_inf_pos_y, tc)
+{
+ const double y = 1.0L / 0.0L;
+ double z;
+
+ /*
+ * If |x| < 1 and y is +Inf, +0.0 is returned.
+ * If |x| > 1 and y is +Inf, +Inf is returned.
+ */
+ z = pow(0.1, y);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(0.1, +Inf) != +0.0");
+
+ z = pow(1.1, y);
+
+ if (isinf(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(1.1, +Inf) != +Inf");
+}
+
+ATF_TC(pow_one_neg_x);
+ATF_TC_HEAD(pow_one_neg_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(-1.0, +-Inf) == 1.0");
+}
+
+ATF_TC_BODY(pow_one_neg_x, tc)
+{
+ const double infp = 1.0L / 0.0L;
+ const double infn = -1.0L / 0.0L;
+
+ /*
+ * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
+ */
+ ATF_REQUIRE(isinf(infp) != 0);
+ ATF_REQUIRE(isinf(infn) != 0);
+
+ if (pow(-1.0, infp) != 1.0) {
+ atf_tc_expect_fail("PR lib/45372");
+ atf_tc_fail_nonfatal("pow(-1.0, +Inf) != 1.0");
+ }
+
+ if (pow(-1.0, infn) != 1.0) {
+ atf_tc_expect_fail("PR lib/45372");
+ atf_tc_fail_nonfatal("pow(-1.0, -Inf) != 1.0");
+ }
+}
+
+ATF_TC(pow_one_pos_x);
+ATF_TC_HEAD(pow_one_pos_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(1.0, y) == 1.0");
+}
+
+ATF_TC_BODY(pow_one_pos_x, tc)
+{
+ const double y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
+ const double z = 0.0L / 0.0L;
+ size_t i;
+
+ /*
+ * For any value of y (including NaN),
+ * if x is 1.0, 1.0 shall be returned.
+ */
+ if (pow(1.0, z) != 1.0)
+ atf_tc_fail_nonfatal("pow(1.0, NaN) != 1.0");
+
+ for (i = 0; i < __arraycount(y); i++) {
+
+ if (pow(1.0, y[i]) != 1.0)
+ atf_tc_fail_nonfatal("pow(1.0, %0.01f) != 1.0", y[i]);
+ }
+}
+
+ATF_TC(pow_zero_x);
+ATF_TC_HEAD(pow_zero_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(+-0.0, y) == +-0.0 || HUGE");
+}
+
+ATF_TC_BODY(pow_zero_x, tc)
+{
+ double z;
+
+ /*
+ * If x is +0.0 or -0.0, y > 0, and y
+ * is an odd integer, x is returned.
+ */
+ z = pow(+0.0, 3.0);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(+0.0, 3.0) != +0.0");
+
+ z = pow(-0.0, 3.0);
+
+ if (fabs(z) > 0.0 || signbit(z) == 0)
+ atf_tc_fail_nonfatal("pow(-0.0, 3.0) != -0.0");
+
+ /*
+ * If y > 0 and not an odd integer,
+ * if x is +0.0 or -0.0, +0.0 is returned.
+ */
+ z = pow(+0.0, 4.0);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(+0.0, 4.0) != +0.0");
+
+ z = pow(-0.0, 4.0);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(-0.0, 4.0) != +0.0");
+
+ /*
+ * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
+ * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
+ */
+ z = pow(+0.0, -4.0);
+
+ if (z != HUGE_VAL) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("pow(+0.0, -4.0) != HUGE_VAL");
+ }
+
+ z = pow(-0.0, -4.0);
+
+ if (z != HUGE_VAL) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("pow(-0.0, -4.0) != HUGE_VAL");
+ }
+
+ z = pow(+0.0, -5.0);
+
+ if (z != HUGE_VAL) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("pow(+0.0, -5.0) != HUGE_VAL");
+ }
+
+ z = pow(-0.0, -5.0);
+
+ if (z != -HUGE_VAL)
+ atf_tc_fail_nonfatal("pow(-0.0, -5.0) != -HUGE_VAL");
+}
+
+ATF_TC(pow_zero_y);
+ATF_TC_HEAD(pow_zero_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(x, +-0.0) == 1.0");
+}
+
+ATF_TC_BODY(pow_zero_y, tc)
+{
+ const double x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
+ const double z = 0.0L / 0.0L;
+ size_t i;
+
+ /*
+ * For any value of x (including NaN),
+ * if y is +0.0 or -0.0, 1.0 is returned.
+ */
+ if (pow(z, +0.0) != 1.0)
+ atf_tc_fail_nonfatal("pow(NaN, +0.0) != 1.0");
+
+ if (pow(z, -0.0) != 1.0)
+ atf_tc_fail_nonfatal("pow(NaN, -0.0) != 1.0");
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ if (pow(x[i], +0.0) != 1.0)
+ atf_tc_fail_nonfatal("pow(%0.01f, +0.0) != 1.0", x[i]);
+
+ if (pow(x[i], -0.0) != 1.0)
+ atf_tc_fail_nonfatal("pow(%0.01f, -0.0) != 1.0", x[i]);
+ }
+}
+
+/*
+ * powf(3)
+ */
+ATF_TC(powf_nan_x);
+ATF_TC_HEAD(powf_nan_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(NaN, y) == NaN");
+}
+
+ATF_TC_BODY(powf_nan_x, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnanf(powf(x, 2.0)) != 0);
+}
+
+ATF_TC(powf_nan_y);
+ATF_TC_HEAD(powf_nan_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(x, NaN) == NaN");
+}
+
+ATF_TC_BODY(powf_nan_y, tc)
+{
+ const float y = 0.0L / 0.0L;
+
+ ATF_CHECK(isnanf(powf(2.0, y)) != 0);
+}
+
+ATF_TC(powf_inf_neg_x);
+ATF_TC_HEAD(powf_inf_neg_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(-Inf, y) == +-Inf || +-0.0");
+}
+
+ATF_TC_BODY(powf_inf_neg_x, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float z;
+
+ /*
+ * If y is odd, y > 0, and x is -Inf, -Inf is returned.
+ * If y is even, y > 0, and x is -Inf, +Inf is returned.
+ */
+ z = powf(x, 3.0);
+
+ if (isinff(z) == 0 || signbit(z) == 0)
+ atf_tc_fail_nonfatal("powf(-Inf, 3.0) != -Inf");
+
+ z = powf(x, 4.0);
+
+ if (isinff(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(-Inf, 4.0) != +Inf");
+
+ /*
+ * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
+ * If y is even, y < 0, and x is -Inf, +0.0 is returned.
+ */
+ z = powf(x, -3.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) == 0) {
+ atf_tc_expect_fail("PR lib/45372");
+ atf_tc_fail_nonfatal("powf(-Inf, -3.0) != -0.0");
+ }
+
+ z = powf(x, -4.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(-Inf -4.0) != +0.0");
+}
+
+ATF_TC(powf_inf_neg_y);
+ATF_TC_HEAD(powf_inf_neg_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(x, -Inf) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(powf_inf_neg_y, tc)
+{
+ const float y = -1.0L / 0.0L;
+ float z;
+
+ /*
+ * If |x| < 1 and y is -Inf, +Inf is returned.
+ * If |x| > 1 and y is -Inf, +0.0 is returned.
+ */
+ z = powf(0.1, y);
+
+ if (isinff(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(0.1, -Inf) != +Inf");
+
+ z = powf(1.1, y);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(1.1, -Inf) != +0.0");
+}
+
+ATF_TC(powf_inf_pos_x);
+ATF_TC_HEAD(powf_inf_pos_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(+Inf, y) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(powf_inf_pos_x, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float z;
+
+ /*
+ * For y < 0, if x is +Inf, +0.0 is returned.
+ * For y > 0, if x is +Inf, +Inf is returned.
+ */
+ z = powf(x, -2.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(+Inf, -2.0) != +0.0");
+
+ z = powf(x, 2.0);
+
+ if (isinff(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(+Inf, 2.0) != +Inf");
+}
+
+ATF_TC(powf_inf_pos_y);
+ATF_TC_HEAD(powf_inf_pos_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(x, +Inf) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(powf_inf_pos_y, tc)
+{
+ const float y = 1.0L / 0.0L;
+ float z;
+
+ /*
+ * If |x| < 1 and y is +Inf, +0.0 is returned.
+ * If |x| > 1 and y is +Inf, +Inf is returned.
+ */
+ z = powf(0.1, y);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(0.1, +Inf) != +0.0");
+
+ z = powf(1.1, y);
+
+ if (isinff(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(1.1, +Inf) != +Inf");
+}
+
+ATF_TC(powf_one_neg_x);
+ATF_TC_HEAD(powf_one_neg_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(-1.0, +-Inf) == 1.0");
+}
+
+ATF_TC_BODY(powf_one_neg_x, tc)
+{
+ const float infp = 1.0L / 0.0L;
+ const float infn = -1.0L / 0.0L;
+
+ /*
+ * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
+ */
+ ATF_REQUIRE(isinff(infp) != 0);
+ ATF_REQUIRE(isinff(infn) != 0);
+
+ if (powf(-1.0, infp) != 1.0) {
+ atf_tc_expect_fail("PR lib/45372");
+ atf_tc_fail_nonfatal("powf(-1.0, +Inf) != 1.0");
+ }
+
+ if (powf(-1.0, infn) != 1.0) {
+ atf_tc_expect_fail("PR lib/45372");
+ atf_tc_fail_nonfatal("powf(-1.0, -Inf) != 1.0");
+ }
+}
+
+ATF_TC(powf_one_pos_x);
+ATF_TC_HEAD(powf_one_pos_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(1.0, y) == 1.0");
+}
+
+ATF_TC_BODY(powf_one_pos_x, tc)
+{
+ const float y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
+ const float z = 0.0L / 0.0L;
+ size_t i;
+
+ /*
+ * For any value of y (including NaN),
+ * if x is 1.0, 1.0 shall be returned.
+ */
+ if (powf(1.0, z) != 1.0)
+ atf_tc_fail_nonfatal("powf(1.0, NaN) != 1.0");
+
+ for (i = 0; i < __arraycount(y); i++) {
+
+ if (powf(1.0, y[i]) != 1.0)
+ atf_tc_fail_nonfatal("powf(1.0, %0.01f) != 1.0", y[i]);
+ }
+}
+
+ATF_TC(powf_zero_x);
+ATF_TC_HEAD(powf_zero_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(+-0.0, y) == +-0.0 || HUGE");
+}
+
+ATF_TC_BODY(powf_zero_x, tc)
+{
+ float z;
+
+ /*
+ * If x is +0.0 or -0.0, y > 0, and y
+ * is an odd integer, x is returned.
+ */
+ z = powf(+0.0, 3.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(+0.0, 3.0) != +0.0");
+
+ z = powf(-0.0, 3.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) == 0)
+ atf_tc_fail_nonfatal("powf(-0.0, 3.0) != -0.0");
+
+ /*
+ * If y > 0 and not an odd integer,
+ * if x is +0.0 or -0.0, +0.0 is returned.
+ */
+ z = powf(+0.0, 4.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(+0.0, 4.0) != +0.0");
+
+ z = powf(-0.0, 4.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(-0.0, 4.0) != +0.0");
+
+ /*
+ * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
+ * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
+ */
+ z = powf(+0.0, -4.0);
+
+ if (z != HUGE_VALF) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("powf(+0.0, -4.0) != HUGE_VALF");
+ }
+
+ z = powf(-0.0, -4.0);
+
+ if (z != HUGE_VALF) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("powf(-0.0, -4.0) != HUGE_VALF");
+ }
+
+ z = powf(+0.0, -5.0);
+
+ if (z != HUGE_VALF) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("powf(+0.0, -5.0) != HUGE_VALF");
+ }
+
+ z = powf(-0.0, -5.0);
+
+ if (z != -HUGE_VALF)
+ atf_tc_fail_nonfatal("powf(-0.0, -5.0) != -HUGE_VALF");
+}
+
+ATF_TC(powf_zero_y);
+ATF_TC_HEAD(powf_zero_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(x, +-0.0) == 1.0");
+}
+
+ATF_TC_BODY(powf_zero_y, tc)
+{
+ const float x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
+ const float z = 0.0L / 0.0L;
+ size_t i;
+
+ /*
+ * For any value of x (including NaN),
+ * if y is +0.0 or -0.0, 1.0 is returned.
+ */
+ if (powf(z, +0.0) != 1.0)
+ atf_tc_fail_nonfatal("powf(NaN, +0.0) != 1.0");
+
+ if (powf(z, -0.0) != 1.0)
+ atf_tc_fail_nonfatal("powf(NaN, -0.0) != 1.0");
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ if (powf(x[i], +0.0) != 1.0)
+ atf_tc_fail_nonfatal("powf(%0.01f, +0.0) != 1.0",x[i]);
+
+ if (powf(x[i], -0.0) != 1.0)
+ atf_tc_fail_nonfatal("powf(%0.01f, -0.0) != 1.0",x[i]);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, pow_nan_x);
+ ATF_TP_ADD_TC(tp, pow_nan_y);
+ ATF_TP_ADD_TC(tp, pow_inf_neg_x);
+ ATF_TP_ADD_TC(tp, pow_inf_neg_y);
+ ATF_TP_ADD_TC(tp, pow_inf_pos_x);
+ ATF_TP_ADD_TC(tp, pow_inf_pos_y);
+ ATF_TP_ADD_TC(tp, pow_one_neg_x);
+ ATF_TP_ADD_TC(tp, pow_one_pos_x);
+ ATF_TP_ADD_TC(tp, pow_zero_x);
+ ATF_TP_ADD_TC(tp, pow_zero_y);
+
+ ATF_TP_ADD_TC(tp, powf_nan_x);
+ ATF_TP_ADD_TC(tp, powf_nan_y);
+ ATF_TP_ADD_TC(tp, powf_inf_neg_x);
+ ATF_TP_ADD_TC(tp, powf_inf_neg_y);
+ ATF_TP_ADD_TC(tp, powf_inf_pos_x);
+ ATF_TP_ADD_TC(tp, powf_inf_pos_y);
+ ATF_TP_ADD_TC(tp, powf_one_neg_x);
+ ATF_TP_ADD_TC(tp, powf_one_pos_x);
+ ATF_TP_ADD_TC(tp, powf_zero_x);
+ ATF_TP_ADD_TC(tp, powf_zero_y);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_precision.c b/contrib/netbsd-tests/lib/libm/t_precision.c
new file mode 100644
index 0000000..c01deba
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_precision.c
@@ -0,0 +1,77 @@
+/* $NetBSD: t_precision.c,v 1.2 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_precision.c,v 1.2 2014/11/04 00:20:19 justin Exp $");
+
+#include <atf-c.h>
+
+#include <float.h>
+#include <stdlib.h>
+
+ATF_TC(t_precision);
+
+ATF_TC_HEAD(t_precision, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Basic precision test for double and long double");
+}
+
+volatile double x = 1;
+volatile long double y = 1;
+
+ATF_TC_BODY(t_precision, tc)
+{
+ x += DBL_EPSILON;
+ ATF_CHECK(x != 1.0);
+ x -= 1;
+ ATF_CHECK(x == DBL_EPSILON);
+
+ x = 2;
+ x += DBL_EPSILON;
+ ATF_CHECK(x == 2.0);
+
+#if !defined(__FreeBSD__) || !defined(__i386__)
+ y += LDBL_EPSILON;
+ ATF_CHECK(y != 1.0L);
+ y -= 1;
+ ATF_CHECK(y == LDBL_EPSILON);
+ y = 2;
+ y += LDBL_EPSILON;
+ ATF_CHECK(y == 2.0L);
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_precision);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_round.c b/contrib/netbsd-tests/lib/libm/t_round.c
new file mode 100644
index 0000000..f47e1a0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_round.c
@@ -0,0 +1,85 @@
+/* $NetBSD: t_round.c,v 1.4 2013/11/11 23:57:34 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 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 <float.h>
+#include <math.h>
+
+/*
+ * This tests for a bug in the initial implementation where
+ * precision was lost in an internal substraction, leading to
+ * rounding into the wrong direction.
+ */
+
+/* 0.5 - EPSILON */
+#define VAL 0x0.7ffffffffffffcp0
+#define VALF 0x0.7fffff8p0
+#define VALL (0.5 - LDBL_EPSILON)
+
+#ifdef __vax__
+#define SMALL_NUM 1.0e-38
+#else
+#define SMALL_NUM 1.0e-40
+#endif
+
+ATF_TC(round_dir);
+ATF_TC_HEAD(round_dir, tc)
+{
+ atf_tc_set_md_var(tc, "descr","Check for rounding in wrong direction");
+}
+
+ATF_TC_BODY(round_dir, tc)
+{
+ double a = VAL, b, c;
+ float af = VALF, bf, cf;
+ long double al = VALL, bl, cl;
+
+ b = round(a);
+ bf = roundf(af);
+ bl = roundl(al);
+
+ ATF_CHECK(fabs(b) < SMALL_NUM);
+ ATF_CHECK(fabsf(bf) < SMALL_NUM);
+ ATF_CHECK(fabsl(bl) < SMALL_NUM);
+
+ c = round(-a);
+ cf = roundf(-af);
+ cl = roundl(-al);
+
+ ATF_CHECK(fabs(c) < SMALL_NUM);
+ ATF_CHECK(fabsf(cf) < SMALL_NUM);
+ ATF_CHECK(fabsl(cl) < SMALL_NUM);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, round_dir);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_scalbn.c b/contrib/netbsd-tests/lib/libm/t_scalbn.c
new file mode 100644
index 0000000..2d186cf
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_scalbn.c
@@ -0,0 +1,526 @@
+/* $NetBSD: t_scalbn.c,v 1.11 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_scalbn.c,v 1.11 2014/03/03 10:39:08 martin Exp $");
+
+#include <math.h>
+#include <limits.h>
+#include <float.h>
+#include <errno.h>
+
+#include <atf-c.h>
+
+static const int exps[] = { 0, 1, -1, 100, -100 };
+
+/* tests here do not require specific precision, so we just use double */
+struct testcase {
+ int exp;
+ double inval;
+ double result;
+ int error;
+};
+struct testcase test_vals[] = {
+ { 0, 1.00085, 1.00085, 0 },
+ { 0, 0.99755, 0.99755, 0 },
+ { 0, -1.00085, -1.00085, 0 },
+ { 0, -0.99755, -0.99755, 0 },
+ { 1, 1.00085, 2.0* 1.00085, 0 },
+ { 1, 0.99755, 2.0* 0.99755, 0 },
+ { 1, -1.00085, 2.0* -1.00085, 0 },
+ { 1, -0.99755, 2.0* -0.99755, 0 },
+
+ /*
+ * We could add more corner test cases here, but we would have to
+ * add some ifdefs for the exact format and use a reliable
+ * generator program - bail for now and only do trivial stuff above.
+ */
+};
+
+/*
+ * scalbn(3)
+ */
+ATF_TC(scalbn_val);
+ATF_TC_HEAD(scalbn_val, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn() for a few values");
+}
+
+ATF_TC_BODY(scalbn_val, tc)
+{
+ const struct testcase *tests = test_vals;
+ const size_t tcnt = __arraycount(test_vals);
+ size_t i;
+ double rv;
+
+ for (i = 0; i < tcnt; i++) {
+#ifdef __FreeBSD__
+ errno = 0;
+#endif
+ rv = scalbn(tests[i].inval, tests[i].exp);
+ ATF_CHECK_EQ_MSG(errno, tests[i].error,
+ "test %zu: errno %d instead of %d", i, errno,
+ tests[i].error);
+ ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*DBL_EPSILON,
+ "test %zu: return value %g instead of %g (difference %g)",
+ i, rv, tests[i].result, tests[i].result-rv);
+ }
+}
+
+ATF_TC(scalbn_nan);
+ATF_TC_HEAD(scalbn_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(NaN, n) == NaN");
+}
+
+ATF_TC_BODY(scalbn_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(isnan(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbn(x, exps[i]);
+ ATF_CHECK(isnan(y) != 0);
+ }
+}
+
+ATF_TC(scalbn_inf_neg);
+ATF_TC_HEAD(scalbn_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(-Inf, n) == -Inf");
+}
+
+ATF_TC_BODY(scalbn_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbn(x, exps[i]) == x);
+}
+
+ATF_TC(scalbn_inf_pos);
+ATF_TC_HEAD(scalbn_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(+Inf, n) == +Inf");
+}
+
+ATF_TC_BODY(scalbn_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbn(x, exps[i]) == x);
+}
+
+ATF_TC(scalbn_ldexp);
+ATF_TC_HEAD(scalbn_ldexp, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(x, n) == ldexp(x, n)");
+}
+
+ATF_TC_BODY(scalbn_ldexp, tc)
+{
+#if FLT_RADIX == 2
+ const double x = 2.91288191221812821;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbn(x, exps[i]);
+ ATF_CHECK_MSG(y == ldexp(x, exps[i]), "test %zu: exponent=%d, "
+ "y=%g, expected %g (diff: %g)", i, exps[i], y,
+ ldexp(x, exps[i]), y - ldexp(x, exps[i]));
+ }
+#endif
+}
+
+ATF_TC(scalbn_zero_neg);
+ATF_TC_HEAD(scalbn_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(-0.0, n) == -0.0");
+}
+
+ATF_TC_BODY(scalbn_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbn(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) != 0);
+ }
+}
+
+ATF_TC(scalbn_zero_pos);
+ATF_TC_HEAD(scalbn_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(+0.0, n) == +0.0");
+}
+
+ATF_TC_BODY(scalbn_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) == 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbn(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) == 0);
+ }
+}
+
+/*
+ * scalbnf(3)
+ */
+ATF_TC(scalbnf_val);
+ATF_TC_HEAD(scalbnf_val, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf() for a few values");
+}
+
+ATF_TC_BODY(scalbnf_val, tc)
+{
+ const struct testcase *tests = test_vals;
+ const size_t tcnt = __arraycount(test_vals);
+ size_t i;
+ double rv;
+
+ for (i = 0; i < tcnt; i++) {
+ rv = scalbnf(tests[i].inval, tests[i].exp);
+ ATF_CHECK_EQ_MSG(errno, tests[i].error,
+ "test %zu: errno %d instead of %d", i, errno,
+ tests[i].error);
+ ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*FLT_EPSILON,
+ "test %zu: return value %g instead of %g (difference %g)",
+ i, rv, tests[i].result, tests[i].result-rv);
+ }
+}
+
+ATF_TC(scalbnf_nan);
+ATF_TC_HEAD(scalbnf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(NaN, n) == NaN");
+}
+
+ATF_TC_BODY(scalbnf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(isnan(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnf(x, exps[i]);
+ ATF_CHECK(isnan(y) != 0);
+ }
+}
+
+ATF_TC(scalbnf_inf_neg);
+ATF_TC_HEAD(scalbnf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(-Inf, n) == -Inf");
+}
+
+ATF_TC_BODY(scalbnf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbnf(x, exps[i]) == x);
+}
+
+ATF_TC(scalbnf_inf_pos);
+ATF_TC_HEAD(scalbnf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(+Inf, n) == +Inf");
+}
+
+ATF_TC_BODY(scalbnf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbnf(x, exps[i]) == x);
+}
+
+ATF_TC(scalbnf_ldexpf);
+ATF_TC_HEAD(scalbnf_ldexpf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(x, n) == ldexpf(x, n)");
+}
+
+ATF_TC_BODY(scalbnf_ldexpf, tc)
+{
+#if FLT_RADIX == 2
+ const float x = 2.91288191221812821;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnf(x, exps[i]);
+ ATF_CHECK_MSG(y == ldexpf(x, exps[i]),
+ "test %zu: exponent=%d, y=%g ldexpf returns %g (diff: %g)",
+ i, exps[i], y, ldexpf(x, exps[i]), y-ldexpf(x, exps[i]));
+ }
+#endif
+}
+
+ATF_TC(scalbnf_zero_neg);
+ATF_TC_HEAD(scalbnf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(-0.0, n) == -0.0");
+}
+
+ATF_TC_BODY(scalbnf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnf(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) != 0);
+ }
+}
+
+ATF_TC(scalbnf_zero_pos);
+ATF_TC_HEAD(scalbnf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(+0.0, n) == +0.0");
+}
+
+ATF_TC_BODY(scalbnf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) == 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnf(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) == 0);
+ }
+}
+
+/*
+ * scalbnl(3)
+ */
+ATF_TC(scalbnl_val);
+ATF_TC_HEAD(scalbnl_val, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnl() for a few values");
+}
+
+ATF_TC_BODY(scalbnl_val, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ const struct testcase *tests = test_vals;
+ const size_t tcnt = __arraycount(test_vals);
+ size_t i;
+ long double rv;
+
+ for (i = 0; i < tcnt; i++) {
+ rv = scalbnl(tests[i].inval, tests[i].exp);
+ ATF_CHECK_EQ_MSG(errno, tests[i].error,
+ "test %zu: errno %d instead of %d", i, errno,
+ tests[i].error);
+ ATF_CHECK_MSG(fabsl(rv-(long double)tests[i].result)<2.0*LDBL_EPSILON,
+ "test %zu: return value %Lg instead of %Lg (difference %Lg)",
+ i, rv, (long double)tests[i].result, (long double)tests[i].result-rv);
+ }
+#endif
+}
+
+ATF_TC(scalbnl_nan);
+ATF_TC_HEAD(scalbnl_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnl(NaN, n) == NaN");
+}
+
+ATF_TC_BODY(scalbnl_nan, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ const long double x = 0.0L / 0.0L;
+ long double y;
+ size_t i;
+
+ if (isnan(x) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("(0.0L / 0.0L) != NaN");
+ }
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnl(x, exps[i]);
+ ATF_CHECK(isnan(y) != 0);
+ }
+#endif
+}
+
+ATF_TC(scalbnl_inf_neg);
+ATF_TC_HEAD(scalbnl_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnl(-Inf, n) == -Inf");
+}
+
+ATF_TC_BODY(scalbnl_inf_neg, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ const long double x = -1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbnl(x, exps[i]) == x);
+#endif
+}
+
+ATF_TC(scalbnl_inf_pos);
+ATF_TC_HEAD(scalbnl_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnl(+Inf, n) == +Inf");
+}
+
+ATF_TC_BODY(scalbnl_inf_pos, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ const long double x = 1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbnl(x, exps[i]) == x);
+#endif
+}
+
+ATF_TC(scalbnl_zero_neg);
+ATF_TC_HEAD(scalbnl_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnl(-0.0, n) == -0.0");
+}
+
+ATF_TC_BODY(scalbnl_zero_neg, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ const long double x = -0.0L;
+ long double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnl(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) != 0);
+ }
+#endif
+}
+
+ATF_TC(scalbnl_zero_pos);
+ATF_TC_HEAD(scalbnl_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnl(+0.0, n) == +0.0");
+}
+
+ATF_TC_BODY(scalbnl_zero_pos, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ const long double x = 0.0L;
+ long double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) == 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnl(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) == 0);
+ }
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, scalbn_val);
+ ATF_TP_ADD_TC(tp, scalbn_nan);
+ ATF_TP_ADD_TC(tp, scalbn_inf_neg);
+ ATF_TP_ADD_TC(tp, scalbn_inf_pos);
+ ATF_TP_ADD_TC(tp, scalbn_ldexp);
+ ATF_TP_ADD_TC(tp, scalbn_zero_neg);
+ ATF_TP_ADD_TC(tp, scalbn_zero_pos);
+
+ ATF_TP_ADD_TC(tp, scalbnf_val);
+ ATF_TP_ADD_TC(tp, scalbnf_nan);
+ ATF_TP_ADD_TC(tp, scalbnf_inf_neg);
+ ATF_TP_ADD_TC(tp, scalbnf_inf_pos);
+ ATF_TP_ADD_TC(tp, scalbnf_ldexpf);
+ ATF_TP_ADD_TC(tp, scalbnf_zero_neg);
+ ATF_TP_ADD_TC(tp, scalbnf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, scalbnl_val);
+ ATF_TP_ADD_TC(tp, scalbnl_nan);
+ ATF_TP_ADD_TC(tp, scalbnl_inf_neg);
+ ATF_TP_ADD_TC(tp, scalbnl_inf_pos);
+/* ATF_TP_ADD_TC(tp, scalbnl_ldexp); */
+ ATF_TP_ADD_TC(tp, scalbnl_zero_neg);
+ ATF_TP_ADD_TC(tp, scalbnl_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_sin.c b/contrib/netbsd-tests/lib/libm/t_sin.c
new file mode 100644
index 0000000..a82f49d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_sin.c
@@ -0,0 +1,263 @@
+/* $NetBSD: t_sin.c,v 1.4 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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 <math.h>
+
+static const struct {
+ int angle;
+ double x;
+ double y;
+} angles[] = {
+ { -180, -3.141592653589793, 0.0000000000000000 },
+ { -135, -2.356194490192345, -0.7071067811865476 },
+ { -90, -1.570796326794897, -1.0000000000000000 },
+ { -45, -0.785398163397448, -0.7071067811865476 },
+ { 0, 0.000000000000000, 0.0000000000000000 },
+ { 30, 0.523598775598299, 0.5000000000000000 },
+ { 45, 0.785398163397448, 0.7071067811865476 },
+ { 60, 1.047197551196598, 0.8660254037844386 },
+ { 90, 1.570796326794897, 1.0000000000000000 },
+ { 120, 2.094395102393195, 0.8660254037844386 },
+ { 135, 2.356194490192345, 0.7071067811865476 },
+ { 150, 2.617993877991494, 0.5000000000000000 },
+ { 180, 3.141592653589793, 0.0000000000000000 },
+ { 270, 4.712388980384690, -1.0000000000000000 },
+ { 360, 6.283185307179586, 0.0000000000000000 }
+};
+
+/*
+ * sin(3)
+ */
+ATF_TC(sin_angles);
+ATF_TC_HEAD(sin_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(sin_angles, tc)
+{
+ const double eps = 1.0e-15;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ if (fabs(sin(angles[i].x) - angles[i].y) > eps)
+ atf_tc_fail_nonfatal("sin(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(sin_nan);
+ATF_TC_HEAD(sin_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sin(NaN) == NaN");
+}
+
+ATF_TC_BODY(sin_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sin(x)) != 0);
+}
+
+ATF_TC(sin_inf_neg);
+ATF_TC_HEAD(sin_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sin(-Inf) == NaN");
+}
+
+ATF_TC_BODY(sin_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ ATF_CHECK(isnan(sin(x)) != 0);
+}
+
+ATF_TC(sin_inf_pos);
+ATF_TC_HEAD(sin_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sin(+Inf) == NaN");
+}
+
+ATF_TC_BODY(sin_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(isnan(sin(x)) != 0);
+}
+
+
+ATF_TC(sin_zero_neg);
+ATF_TC_HEAD(sin_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sin(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sin_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(sin(x) == x);
+}
+
+ATF_TC(sin_zero_pos);
+ATF_TC_HEAD(sin_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sin(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sin_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(sin(x) == x);
+}
+
+/*
+ * sinf(3)
+ */
+ATF_TC(sinf_angles);
+ATF_TC_HEAD(sinf_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(sinf_angles, tc)
+{
+ const float eps = 1.0e-6;
+ float x, y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ x = angles[i].x;
+ y = angles[i].y;
+
+ if (fabsf(sinf(x) - y) > eps)
+ atf_tc_fail_nonfatal("sinf(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(sinf_nan);
+ATF_TC_HEAD(sinf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinf(NaN) == NaN");
+}
+
+ATF_TC_BODY(sinf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sinf(x)) != 0);
+}
+
+ATF_TC(sinf_inf_neg);
+ATF_TC_HEAD(sinf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(sinf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (isnan(sinf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("sinf(-Inf) != NaN");
+ }
+}
+
+ATF_TC(sinf_inf_pos);
+ATF_TC_HEAD(sinf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinf(+Inf) == NaN");
+}
+
+ATF_TC_BODY(sinf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ if (isnan(sinf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("sinf(+Inf) != NaN");
+ }
+}
+
+
+ATF_TC(sinf_zero_neg);
+ATF_TC_HEAD(sinf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sinf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(sinf(x) == x);
+}
+
+ATF_TC(sinf_zero_pos);
+ATF_TC_HEAD(sinf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sinf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(sinf(x) == x);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sin_angles);
+ ATF_TP_ADD_TC(tp, sin_nan);
+ ATF_TP_ADD_TC(tp, sin_inf_neg);
+ ATF_TP_ADD_TC(tp, sin_inf_pos);
+ ATF_TP_ADD_TC(tp, sin_zero_neg);
+ ATF_TP_ADD_TC(tp, sin_zero_pos);
+
+ ATF_TP_ADD_TC(tp, sinf_angles);
+ ATF_TP_ADD_TC(tp, sinf_nan);
+ ATF_TP_ADD_TC(tp, sinf_inf_neg);
+ ATF_TP_ADD_TC(tp, sinf_inf_pos);
+ ATF_TP_ADD_TC(tp, sinf_zero_neg);
+ ATF_TP_ADD_TC(tp, sinf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_sinh.c b/contrib/netbsd-tests/lib/libm/t_sinh.c
new file mode 100644
index 0000000..d935f0e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_sinh.c
@@ -0,0 +1,273 @@
+/* $NetBSD: t_sinh.c,v 1.6 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_sinh.c,v 1.6 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <stdio.h>
+
+static const struct {
+ double x;
+ double y;
+ double e;
+} values[] = {
+ { -10, -11013.23287470339, 1e4, },
+ { -2, -3.626860407847019, 1, },
+ { -1, -1.175201193643801, 1, },
+ { -0.05, -0.050020835937655, 1, },
+ { -0.001,-0.001000000166667, 1, },
+ { 0.001, 0.001000000166667, 1, },
+ { 0.05, 0.050020835937655, 1, },
+ { 1, 1.175201193643801, 1, },
+ { 2, 3.626860407847019, 1, },
+ { 10, 11013.23287470339, 1e4, },
+};
+
+/*
+ * sinh(3)
+ */
+ATF_TC(sinh_inrange);
+ATF_TC_HEAD(sinh_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "sinh(x) for some values");
+}
+
+ATF_TC_BODY(sinh_inrange, tc)
+{
+ double eps;
+ double x;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ x = values[i].x;
+ y = values[i].y;
+ eps = 1e-15 * values[i].e;
+
+ if (fabs(sinh(x) - y) > eps)
+ atf_tc_fail_nonfatal("sinh(%g) != %g\n", x, y);
+ }
+}
+
+ATF_TC(sinh_nan);
+ATF_TC_HEAD(sinh_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinh(NaN) == NaN");
+}
+
+ATF_TC_BODY(sinh_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sinh(x)) != 0);
+}
+
+ATF_TC(sinh_inf_neg);
+ATF_TC_HEAD(sinh_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinh(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(sinh_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = sinh(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) != 0);
+}
+
+ATF_TC(sinh_inf_pos);
+ATF_TC_HEAD(sinh_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinh(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(sinh_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = sinh(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(sinh_zero_neg);
+ATF_TC_HEAD(sinh_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinh(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sinh_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = sinh(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("sinh(-0.0) != -0.0");
+}
+
+ATF_TC(sinh_zero_pos);
+ATF_TC_HEAD(sinh_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinh(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sinh_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = sinh(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("sinh(+0.0) != +0.0");
+}
+
+/*
+ * sinhf(3)
+ */
+ATF_TC(sinhf_inrange);
+ATF_TC_HEAD(sinhf_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "sinhf(x) for some values");
+}
+
+ATF_TC_BODY(sinhf_inrange, tc)
+{
+ float eps;
+ float x;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ x = values[i].x;
+ y = values[i].y;
+ eps = 1e-6 * values[i].e;
+
+ if (fabsf(sinhf(x) - y) > eps)
+ atf_tc_fail_nonfatal("sinhf(%g) != %g\n", x, y);
+ }
+}
+
+ATF_TC(sinhf_nan);
+ATF_TC_HEAD(sinhf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinhf(NaN) == NaN");
+}
+
+ATF_TC_BODY(sinhf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sinhf(x)) != 0);
+}
+
+ATF_TC(sinhf_inf_neg);
+ATF_TC_HEAD(sinhf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinhf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(sinhf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = sinhf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) != 0);
+}
+
+ATF_TC(sinhf_inf_pos);
+ATF_TC_HEAD(sinhf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinhf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(sinhf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = sinhf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(sinhf_zero_neg);
+ATF_TC_HEAD(sinhf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinhf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sinhf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = sinhf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("sinhf(-0.0) != -0.0");
+}
+
+ATF_TC(sinhf_zero_pos);
+ATF_TC_HEAD(sinhf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinhf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sinhf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = sinhf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("sinhf(+0.0) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sinh_inrange);
+ ATF_TP_ADD_TC(tp, sinh_nan);
+ ATF_TP_ADD_TC(tp, sinh_inf_neg);
+ ATF_TP_ADD_TC(tp, sinh_inf_pos);
+ ATF_TP_ADD_TC(tp, sinh_zero_neg);
+ ATF_TP_ADD_TC(tp, sinh_zero_pos);
+
+ ATF_TP_ADD_TC(tp, sinhf_inrange);
+ ATF_TP_ADD_TC(tp, sinhf_nan);
+ ATF_TP_ADD_TC(tp, sinhf_inf_neg);
+ ATF_TP_ADD_TC(tp, sinhf_inf_pos);
+ ATF_TP_ADD_TC(tp, sinhf_zero_neg);
+ ATF_TP_ADD_TC(tp, sinhf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_sqrt.c b/contrib/netbsd-tests/lib/libm/t_sqrt.c
new file mode 100644
index 0000000..1d551ec
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_sqrt.c
@@ -0,0 +1,368 @@
+/* $NetBSD: t_sqrt.c,v 1.7 2014/03/12 21:40:07 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_sqrt.c,v 1.7 2014/03/12 21:40:07 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <float.h>
+#include <stdio.h>
+
+/*
+ * sqrt(3)
+ */
+ATF_TC(sqrt_nan);
+ATF_TC_HEAD(sqrt_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(NaN) == NaN");
+}
+
+ATF_TC_BODY(sqrt_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sqrt(x)) != 0);
+}
+
+ATF_TC(sqrt_pow);
+ATF_TC_HEAD(sqrt_pow, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(3) vs. pow(3)");
+}
+
+ATF_TC_BODY(sqrt_pow, tc)
+{
+ const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
+#if __DBL_MIN_10_EXP__ <= -40
+ const double eps = 1.0e-40;
+#else
+ const double eps = __DBL_MIN__*4.0;
+#endif
+ double y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = sqrt(x[i]);
+ z = pow(x[i], 1.0 / 2.0);
+
+ if (fabs(y - z) > eps)
+ atf_tc_fail_nonfatal("sqrt(%0.03f) != "
+ "pow(%0.03f, 1/2)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(sqrt_inf_neg);
+ATF_TC_HEAD(sqrt_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(-Inf) == NaN");
+}
+
+ATF_TC_BODY(sqrt_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = sqrt(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(sqrt_inf_pos);
+ATF_TC_HEAD(sqrt_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(sqrt_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = sqrt(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(sqrt_zero_neg);
+ATF_TC_HEAD(sqrt_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sqrt_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = sqrt(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("sqrt(-0.0) != -0.0");
+}
+
+ATF_TC(sqrt_zero_pos);
+ATF_TC_HEAD(sqrt_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sqrt_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = sqrt(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("sqrt(+0.0) != +0.0");
+}
+
+/*
+ * sqrtf(3)
+ */
+ATF_TC(sqrtf_nan);
+ATF_TC_HEAD(sqrtf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(NaN) == NaN");
+}
+
+ATF_TC_BODY(sqrtf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sqrtf(x)) != 0);
+}
+
+ATF_TC(sqrtf_powf);
+ATF_TC_HEAD(sqrtf_powf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(3) vs. powf(3)");
+}
+
+ATF_TC_BODY(sqrtf_powf, tc)
+{
+ const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
+ const float eps = 1.0e-30;
+ volatile float y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = sqrtf(x[i]);
+ z = powf(x[i], 1.0 / 2.0);
+
+ if (fabsf(y - z) > eps)
+ atf_tc_fail_nonfatal("sqrtf(%0.03f) != "
+ "powf(%0.03f, 1/2)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(sqrtf_inf_neg);
+ATF_TC_HEAD(sqrtf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(sqrtf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = sqrtf(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(sqrtf_inf_pos);
+ATF_TC_HEAD(sqrtf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(sqrtf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = sqrtf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(sqrtf_zero_neg);
+ATF_TC_HEAD(sqrtf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sqrtf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = sqrtf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("sqrtf(-0.0) != -0.0");
+}
+
+ATF_TC(sqrtf_zero_pos);
+ATF_TC_HEAD(sqrtf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sqrtf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = sqrtf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("sqrtf(+0.0) != +0.0");
+}
+
+/*
+ * sqrtl(3)
+ */
+ATF_TC(sqrtl_nan);
+ATF_TC_HEAD(sqrtl_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(NaN) == NaN");
+}
+
+ATF_TC_BODY(sqrtl_nan, tc)
+{
+ const long double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sqrtl(x)) != 0);
+}
+
+ATF_TC(sqrtl_powl);
+ATF_TC_HEAD(sqrtl_powl, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(3) vs. powl(3)");
+}
+
+ATF_TC_BODY(sqrtl_powl, tc)
+{
+ const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
+ const long double eps = 5.0*DBL_EPSILON; /* XXX powl == pow for now */
+ volatile long double y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = sqrtl(x[i]);
+ z = powl(x[i], 1.0 / 2.0);
+
+ if (fabsl(y - z) > eps)
+ atf_tc_fail_nonfatal("sqrtl(%0.03Lf) != "
+ "powl(%0.03Lf, 1/2)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(sqrtl_inf_neg);
+ATF_TC_HEAD(sqrtl_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(-Inf) == NaN");
+}
+
+ATF_TC_BODY(sqrtl_inf_neg, tc)
+{
+ const long double x = -1.0L / 0.0L;
+ long double y = sqrtl(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(sqrtl_inf_pos);
+ATF_TC_HEAD(sqrtl_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(sqrtl_inf_pos, tc)
+{
+ const long double x = 1.0L / 0.0L;
+ long double y = sqrtl(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(sqrtl_zero_neg);
+ATF_TC_HEAD(sqrtl_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sqrtl_zero_neg, tc)
+{
+ const long double x = -0.0L;
+ long double y = sqrtl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("sqrtl(-0.0) != -0.0");
+}
+
+ATF_TC(sqrtl_zero_pos);
+ATF_TC_HEAD(sqrtl_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sqrtl_zero_pos, tc)
+{
+ const long double x = 0.0L;
+ long double y = sqrtl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("sqrtl(+0.0) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sqrt_nan);
+ ATF_TP_ADD_TC(tp, sqrt_pow);
+ ATF_TP_ADD_TC(tp, sqrt_inf_neg);
+ ATF_TP_ADD_TC(tp, sqrt_inf_pos);
+ ATF_TP_ADD_TC(tp, sqrt_zero_neg);
+ ATF_TP_ADD_TC(tp, sqrt_zero_pos);
+
+ ATF_TP_ADD_TC(tp, sqrtf_nan);
+ ATF_TP_ADD_TC(tp, sqrtf_powf);
+ ATF_TP_ADD_TC(tp, sqrtf_inf_neg);
+ ATF_TP_ADD_TC(tp, sqrtf_inf_pos);
+ ATF_TP_ADD_TC(tp, sqrtf_zero_neg);
+ ATF_TP_ADD_TC(tp, sqrtf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, sqrtl_nan);
+ ATF_TP_ADD_TC(tp, sqrtl_powl);
+ ATF_TP_ADD_TC(tp, sqrtl_inf_neg);
+ ATF_TP_ADD_TC(tp, sqrtl_inf_pos);
+ ATF_TP_ADD_TC(tp, sqrtl_zero_neg);
+ ATF_TP_ADD_TC(tp, sqrtl_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_tan.c b/contrib/netbsd-tests/lib/libm/t_tan.c
new file mode 100644
index 0000000..807e3d1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_tan.c
@@ -0,0 +1,260 @@
+/* $NetBSD: t_tan.c,v 1.5 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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 <math.h>
+
+static const struct {
+ int angle;
+ double x;
+ double y;
+} angles[] = {
+ { -180, -3.141592653589793, 0.0000000000000000 },
+ { -135, -2.356194490192345, 1.0000000000000000 },
+ { -45, -0.785398163397448, -1.0000000000000000 },
+ { 0, 0.000000000000000, 0.0000000000000000 },
+ { 30, 0.523598775598299, 0.5773502691896258 },
+ { 45, 0.785398163397448, 1.0000000000000000 },
+ { 60, 1.047197551196598, 1.7320508075688773 },
+ { 120, 2.094395102393195, -1.7320508075688773 },
+ { 135, 2.356194490192345, -1.0000000000000000 },
+ { 150, 2.617993877991494, -0.5773502691896258 },
+ { 180, 3.141592653589793, 0.0000000000000000 },
+ { 360, 6.283185307179586, 0.0000000000000000 }
+};
+
+/*
+ * tan(3)
+ */
+ATF_TC(tan_angles);
+ATF_TC_HEAD(tan_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(tan_angles, tc)
+{
+ const double eps = 1.0e-14;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ if (fabs(tan(angles[i].x) - angles[i].y) > eps)
+ atf_tc_fail_nonfatal("tan(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(tan_nan);
+ATF_TC_HEAD(tan_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tan(NaN) == NaN");
+}
+
+ATF_TC_BODY(tan_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(tan(x)) != 0);
+}
+
+ATF_TC(tan_inf_neg);
+ATF_TC_HEAD(tan_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tan(-Inf) == NaN");
+}
+
+ATF_TC_BODY(tan_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ ATF_CHECK(isnan(tan(x)) != 0);
+}
+
+ATF_TC(tan_inf_pos);
+ATF_TC_HEAD(tan_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tan(+Inf) == NaN");
+}
+
+ATF_TC_BODY(tan_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(isnan(tan(x)) != 0);
+}
+
+
+ATF_TC(tan_zero_neg);
+ATF_TC_HEAD(tan_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tan(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(tan_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(tan(x) == x);
+}
+
+ATF_TC(tan_zero_pos);
+ATF_TC_HEAD(tan_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tan(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(tan_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(tan(x) == x);
+}
+
+/*
+ * tanf(3)
+ */
+ATF_TC(tanf_angles);
+ATF_TC_HEAD(tanf_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(tanf_angles, tc)
+{
+ const float eps = 1.0e-6;
+ float x, y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ x = angles[i].x;
+ y = angles[i].y;
+
+ if (fabsf(tanf(x) - y) > eps)
+ atf_tc_fail_nonfatal("tanf(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(tanf_nan);
+ATF_TC_HEAD(tanf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanf(NaN) == NaN");
+}
+
+ATF_TC_BODY(tanf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(tanf(x)) != 0);
+}
+
+ATF_TC(tanf_inf_neg);
+ATF_TC_HEAD(tanf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(tanf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (isnan(tanf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("tanf(-Inf) != NaN");
+ }
+}
+
+ATF_TC(tanf_inf_pos);
+ATF_TC_HEAD(tanf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanf(+Inf) == NaN");
+}
+
+ATF_TC_BODY(tanf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ if (isnan(tanf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("tanf(+Inf) != NaN");
+ }
+}
+
+
+ATF_TC(tanf_zero_neg);
+ATF_TC_HEAD(tanf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(tanf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(tanf(x) == x);
+}
+
+ATF_TC(tanf_zero_pos);
+ATF_TC_HEAD(tanf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(tanf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(tanf(x) == x);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, tan_angles);
+ ATF_TP_ADD_TC(tp, tan_nan);
+ ATF_TP_ADD_TC(tp, tan_inf_neg);
+ ATF_TP_ADD_TC(tp, tan_inf_pos);
+ ATF_TP_ADD_TC(tp, tan_zero_neg);
+ ATF_TP_ADD_TC(tp, tan_zero_pos);
+
+ ATF_TP_ADD_TC(tp, tanf_angles);
+ ATF_TP_ADD_TC(tp, tanf_nan);
+ ATF_TP_ADD_TC(tp, tanf_inf_neg);
+ ATF_TP_ADD_TC(tp, tanf_inf_pos);
+ ATF_TP_ADD_TC(tp, tanf_zero_neg);
+ ATF_TP_ADD_TC(tp, tanf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libm/t_tanh.c b/contrib/netbsd-tests/lib/libm/t_tanh.c
new file mode 100644
index 0000000..4cc4551
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_tanh.c
@@ -0,0 +1,207 @@
+/* $NetBSD: t_tanh.c,v 1.7 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_tanh.c,v 1.7 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+
+/*
+ * tanh(3)
+ */
+ATF_TC(tanh_nan);
+ATF_TC_HEAD(tanh_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanh(NaN) == NaN");
+}
+
+ATF_TC_BODY(tanh_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(tanh(x)) != 0);
+}
+
+ATF_TC(tanh_inf_neg);
+ATF_TC_HEAD(tanh_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanh(-Inf) == -1.0");
+}
+
+ATF_TC_BODY(tanh_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ ATF_CHECK(tanh(x) == -1.0);
+}
+
+ATF_TC(tanh_inf_pos);
+ATF_TC_HEAD(tanh_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanh(+Inf) == +1.0");
+}
+
+ATF_TC_BODY(tanh_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(tanh(x) == 1.0);
+}
+
+ATF_TC(tanh_zero_neg);
+ATF_TC_HEAD(tanh_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanh(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(tanh_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = tanh(x);
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) != 0);
+
+ ATF_REQUIRE_MSG(signbit(y) != 0,
+ "compiler bug, waiting for newer gcc import, see PR lib/44057");
+}
+
+ATF_TC(tanh_zero_pos);
+ATF_TC_HEAD(tanh_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanh(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(tanh_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = tanh(x);
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+/*
+ * tanhf(3)
+ */
+ATF_TC(tanhf_nan);
+ATF_TC_HEAD(tanhf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanhf(NaN) == NaN");
+}
+
+ATF_TC_BODY(tanhf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(tanhf(x)) != 0);
+}
+
+ATF_TC(tanhf_inf_neg);
+ATF_TC_HEAD(tanhf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanhf(-Inf) == -1.0");
+}
+
+ATF_TC_BODY(tanhf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ ATF_CHECK(tanhf(x) == -1.0);
+}
+
+ATF_TC(tanhf_inf_pos);
+ATF_TC_HEAD(tanhf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanhf(+Inf) == +1.0");
+}
+
+ATF_TC_BODY(tanhf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ ATF_CHECK(tanhf(x) == 1.0);
+}
+
+ATF_TC(tanhf_zero_neg);
+ATF_TC_HEAD(tanhf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanhf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(tanhf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = tanh(x);
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) != 0);
+
+ ATF_REQUIRE_MSG(signbit(y) != 0,
+ "compiler bug, waiting for newer gcc import, see PR lib/44057");
+}
+
+ATF_TC(tanhf_zero_pos);
+ATF_TC_HEAD(tanhf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanhf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(tanhf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = tanhf(x);
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, tanh_nan);
+ ATF_TP_ADD_TC(tp, tanh_inf_neg);
+ ATF_TP_ADD_TC(tp, tanh_inf_pos);
+ ATF_TP_ADD_TC(tp, tanh_zero_neg);
+ ATF_TP_ADD_TC(tp, tanh_zero_pos);
+
+ ATF_TP_ADD_TC(tp, tanhf_nan);
+ ATF_TP_ADD_TC(tp, tanhf_inf_neg);
+ ATF_TP_ADD_TC(tp, tanhf_inf_pos);
+ ATF_TP_ADD_TC(tp, tanhf_zero_neg);
+ ATF_TP_ADD_TC(tp, tanhf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libobjc/t_threads.m b/contrib/netbsd-tests/lib/libobjc/t_threads.m
new file mode 100644
index 0000000..a6bd720
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libobjc/t_threads.m
@@ -0,0 +1,136 @@
+/* $NetBSD: t_threads.m,v 1.2 2013/10/31 21:02:11 christos Exp $ */
+
+/*
+ * 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.
+ */
+
+/* Originally written by David Wetzel */
+
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include <objc/objc.h>
+#include <objc/thr.h>
+#include <objc/Object.h>
+#if __GNUC_PREREQ__(4,8)
+#include <objc/runtime.h>
+#endif
+
+static int IsMultithreaded = 0;
+static objc_mutex_t Mutex;
+static objc_condition_t Condition;
+
+@interface MyClass : Object
+{
+}
+-(void)start;
+#if __GNUC_PREREQ__(4,8)
+-init;
++new;
++alloc;
+-free;
+#endif
+@end
+
+@implementation MyClass
+-(void)start
+{
+ printf("detached thread started!\n");
+
+ objc_condition_signal(Condition);
+}
+#if __GNUC_PREREQ__(4,8)
+-init
+{
+ return self;
+}
+
++new
+{
+ return [[self alloc] init];
+}
+
++alloc
+{
+ return class_createInstance(self, 0);
+}
+
+-free
+{
+ return object_dispose(self);
+}
+#endif
+@end
+
+static void
+becomeMultiThreaded(void)
+{
+ printf("becoming multithreaded!\n");
+ IsMultithreaded++;
+}
+
+ATF_TC(thread_callback);
+ATF_TC_HEAD(thread_callback, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that the thread callback is only"
+ "called once");
+}
+ATF_TC_BODY(thread_callback, tc)
+{
+ id o = [MyClass new];
+ objc_thread_callback cb;
+ objc_thread_t rv;
+
+ cb = objc_set_thread_callback(becomeMultiThreaded);
+ printf("Old Callback: %p\n", cb);
+ ATF_CHECK(cb == 0);
+
+ Mutex = objc_mutex_allocate();
+ Condition = objc_condition_allocate();
+
+ ATF_CHECK_EQ(0, IsMultithreaded);
+
+ rv = objc_thread_detach(@selector(start), o, nil);
+ printf("detach value: %p\n", rv);
+ assert(rv != NULL);
+
+ objc_mutex_lock(Mutex);
+ objc_condition_wait(Condition, Mutex);
+ objc_mutex_unlock(Mutex);
+
+ ATF_CHECK_EQ(1, IsMultithreaded);
+ printf("Shutting down\n");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, thread_callback);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libposix/t_rename.c b/contrib/netbsd-tests/lib/libposix/t_rename.c
new file mode 100644
index 0000000..85b2b95
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libposix/t_rename.c
@@ -0,0 +1,89 @@
+/* $NetBSD: t_rename.c,v 1.2 2011/05/16 00:03:36 christos Exp $ */
+
+/*
+ * Copyright (c) 2001, 2008, 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.
+ */
+#define _NETBSD_SOURCE /* strlcat/random */
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008, 2010\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_rename.c,v 1.2 2011/05/16 00:03:36 christos Exp $");
+
+#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 "../../h_macros.h"
+
+ATF_TC(rename);
+ATF_TC_HEAD(rename, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks rename(2)");
+}
+ATF_TC_BODY(rename, tc)
+{
+ struct stat sb;
+
+ REQUIRE_LIBC(open("t1", O_CREAT | O_TRUNC | O_WRONLY, 0600), -1);
+ REQUIRE_LIBC(link("t1", "t2"), -1);
+
+ /* Check if rename to same name works as expected */
+ REQUIRE_LIBC(rename("t1", "t1"), -1);
+
+ /* Rename removed file? */
+ REQUIRE_LIBC(stat("t1", &sb), -1);
+
+ REQUIRE_LIBC(rename("t1", "t2"), -1);
+
+#if BSD_RENAME
+ /* check if rename of hardlinked file works the BSD way */
+ ATF_REQUIRE_MSG(stat("t1", &sb) != 0, "BSD rename should remove file t1");
+ ATF_REQUIRE_EQ(errno, ENOENT);
+#else
+ /* check if rename of hardlinked file works as the standard says */
+ REQUIRE_LIBC(stat("t1", &sb), -1);
+#endif
+ /* check if we get the expected error */
+ /* this also exercises icky shared libraries goo */
+ ATF_REQUIRE_MSG(rename("no/such/file/or/dir", "no/such/file/or/dir") != 0,
+ "No error renaming nonexistent file");
+ ATF_REQUIRE_EQ(errno, ENOENT);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, rename);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libppath/personnel.plist b/contrib/netbsd-tests/lib/libppath/personnel.plist
new file mode 100644
index 0000000..daec88c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libppath/personnel.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>John Doe</key>
+ <dict>
+ <key>children</key>
+ <array>
+ <string>Jane Doe</string>
+ <string>John Doe, Jr.</string>
+ </array>
+
+ <key>pets</key>
+ <array>
+ <string>Fido</string>
+ <string>Spot</string>
+ </array>
+
+ <key>job title</key>
+ <string>computer programmer</string>
+
+ <key>u.s. citizen</key>
+ <true/>
+ </dict>
+</dict>
+</plist>
diff --git a/contrib/netbsd-tests/lib/libppath/plist_to_c b/contrib/netbsd-tests/lib/libppath/plist_to_c
new file mode 100755
index 0000000..f471b4e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libppath/plist_to_c
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+prog=$(basename $0)
+usage()
+{
+ echo "usage: ${prog} symbol" 1>&2
+ exit 1
+}
+
+if [ $# -ne 1 ]; then
+ usage
+fi
+
+sed 's/\(["\]\)/\\\1/g' | \
+${AWK:-awk} -v sym=$1 '
+BEGIN { printf "const char " sym "[] = \""; }
+ { printf $0 "\\n"; }
+END { print "\";"; }'
+
+exit 0
diff --git a/contrib/netbsd-tests/lib/libppath/t_ppath.c b/contrib/netbsd-tests/lib/libppath/t_ppath.c
new file mode 100644
index 0000000..7330763
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libppath/t_ppath.c
@@ -0,0 +1,1548 @@
+/* $Id: t_ppath.c,v 1.1 2011/08/25 19:09:46 dyoung Exp $ */
+
+/* Copyright (c) 2010 David Young. All rights reserved. */
+
+#include <sys/cdefs.h>
+__RCSID("$Id: t_ppath.c,v 1.1 2011/08/25 19:09:46 dyoung Exp $");
+
+#include <assert.h>
+#include <atf-c.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ppath/ppath.h>
+#include "personnel.h"
+
+void test_ppath_extant_inc(void);
+void test_ppath_extant_dec(void);
+void test_ppath_component_extant_inc(void);
+void test_ppath_component_extant_dec(void);
+
+__strong_alias(ppath_extant_inc, test_ppath_extant_inc);
+__strong_alias(ppath_extant_dec, test_ppath_extant_dec);
+__strong_alias(ppath_component_extant_inc, test_ppath_component_extant_inc);
+__strong_alias(ppath_component_extant_dec, test_ppath_component_extant_dec);
+
+static uint64_t nppath = 0, nppath_component = 0;
+
+static bool
+dictionary_equals(prop_dictionary_t ld, prop_dictionary_t rd)
+{
+ bool eq;
+ char *lt, *rt;
+
+ lt = prop_dictionary_externalize(ld);
+ rt = prop_dictionary_externalize(rd);
+
+ assert(lt != NULL && rt != NULL);
+
+ eq = (strcmp(lt, rt) == 0);
+
+ free(lt);
+ free(rt);
+
+ return eq;
+}
+
+static void
+assert_no_ppath_extant(void)
+{
+ ATF_CHECK_EQ(nppath, 0);
+}
+
+static void
+assert_no_ppath_component_extant(void)
+{
+ ATF_CHECK_EQ(nppath_component, 0);
+}
+
+void
+test_ppath_extant_inc(void)
+{
+ if (++nppath == 0)
+ atf_tc_fail("count of extant paths overflowed");
+}
+
+void
+test_ppath_extant_dec(void)
+{
+ if (nppath-- == 0)
+ atf_tc_fail("count of extant path underflowed");
+}
+
+void
+test_ppath_component_extant_inc(void)
+{
+ if (++nppath_component == 0)
+ atf_tc_fail("count of extant path components overflowed");
+}
+
+void
+test_ppath_component_extant_dec(void)
+{
+ if (nppath_component-- == 0)
+ atf_tc_fail("count of extant path components underflowed");
+}
+
+ATF_TC(push_until_full);
+
+ATF_TC_HEAD(push_until_full, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_push() returns error "
+ "after ppath_t reaches maximum length");
+}
+
+ATF_TC_BODY(push_until_full, tc)
+{
+ ppath_t *p, *rp;
+ ppath_component_t *pc;
+ int i;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if ((pc = ppath_idx(0)) == NULL)
+ atf_tc_fail("ppath_idx failed");
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
+ rp = ppath_push(p, pc);
+ ATF_CHECK_EQ(rp, p);
+ }
+
+ rp = ppath_push(p, pc);
+ ATF_CHECK_EQ(rp, NULL);
+
+ rp = ppath_push(p, pc);
+ ATF_CHECK_EQ(rp, NULL);
+
+ ppath_component_release(pc);
+ ppath_release(p);
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(pop_until_empty);
+ATF_TC_HEAD(pop_until_empty, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_pop() returns error "
+ "after ppath_t is empty");
+}
+
+ATF_TC_BODY(pop_until_empty, tc)
+{
+ ppath_t *p, *rp;
+ ppath_component_t *pc, *rpc;
+ int i;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if ((pc = ppath_idx(0)) == NULL)
+ atf_tc_fail("ppath_idx failed");
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
+ rp = ppath_push(p, pc);
+ ATF_CHECK_EQ(rp, p);
+ }
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
+ rp = ppath_pop(p, &rpc);
+ ATF_CHECK_EQ(rp, p);
+ ATF_CHECK_EQ(rpc, pc);
+ ppath_component_release(rpc);
+ }
+
+ rp = ppath_pop(p, &rpc);
+ ATF_CHECK_EQ(rp, NULL);
+ rp = ppath_pop(p, &rpc);
+ ATF_CHECK_EQ(rp, NULL);
+
+ ppath_component_release(pc);
+ ppath_release(p);
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(length);
+
+ATF_TC_HEAD(length, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check that ppath_push() "
+ "and ppath_pop() affect ppath_length() correctly");
+}
+
+ATF_TC_BODY(length, tc)
+{
+ ppath_t *p, *rp;
+ ppath_component_t *pc;
+ unsigned int i, len;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if ((pc = ppath_idx(0)) == NULL)
+ atf_tc_fail("ppath_idx failed");
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
+ len = ppath_length(p);
+ ATF_CHECK_EQ(len, i);
+ rp = ppath_push(p, pc);
+ ATF_CHECK_EQ(rp, p);
+ }
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
+ len = ppath_length(p);
+ ATF_CHECK_EQ(len, PPATH_MAX_COMPONENTS - i);
+ rp = ppath_pop(p, NULL);
+ ATF_CHECK_EQ(rp, p);
+ }
+ ppath_component_release(pc);
+ ppath_release(p);
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(component_at);
+
+ATF_TC_HEAD(component_at, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check that ppath_component_at() "
+ "returns the expected component");
+}
+
+ATF_TC_BODY(component_at, tc)
+{
+ ppath_t *p, *rp;
+ ppath_component_t *pc;
+ unsigned int i;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
+ if ((pc = ppath_idx(i)) == NULL)
+ atf_tc_fail("ppath_idx failed");
+ rp = ppath_push(p, pc);
+ ppath_component_release(pc);
+ ATF_CHECK_EQ(rp, p);
+ }
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
+ pc = ppath_component_at(p, i);
+ ATF_CHECK_EQ(ppath_component_idx(pc), (int)i);
+ ppath_component_release(pc);
+ }
+ ppath_release(p);
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(get_idx_key);
+
+ATF_TC_HEAD(get_idx_key, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check that ppath_component_idx() "
+ "and ppath_component_key() return -1 and NULL, respectively, if "
+ "the component is a key or an index, respectively.");
+}
+
+ATF_TC_BODY(get_idx_key, tc)
+{
+ ppath_component_t *idx, *key;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((idx = ppath_idx(0)) == NULL)
+ atf_tc_fail("ppath_idx failed");
+ if ((key = ppath_key("key")) == NULL)
+ atf_tc_fail("ppath_idx failed");
+
+ ATF_CHECK_EQ(ppath_component_key(idx), NULL);
+ ATF_CHECK_EQ(ppath_component_idx(key), -1);
+
+ ppath_component_release(idx);
+ ppath_component_release(key);
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(ppath_copy);
+
+ATF_TC_HEAD(ppath_copy, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check that ppath_copy() "
+ "creates an exact replica of a path, and that no "
+ "resources are leaked.");
+}
+
+ATF_TC_BODY(ppath_copy, tc)
+{
+ ppath_component_t *pc, *cpc;
+ ppath_t *p, *cp, *rp;
+ unsigned int i;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
+ if ((pc = ppath_idx(i)) == NULL)
+ atf_tc_fail("ppath_idx failed");
+ rp = ppath_push(p, pc);
+ ppath_component_release(pc);
+ ATF_CHECK_EQ(rp, p);
+ }
+
+ if ((cp = ppath_copy(p)) == NULL)
+ atf_tc_fail("ppath_copy failed");
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
+ pc = ppath_component_at(p, i);
+ cpc = ppath_component_at(cp, i);
+ ATF_CHECK_EQ(pc, cpc);
+ ppath_component_release(pc);
+ ppath_component_release(cpc);
+ }
+
+ ppath_release(cp);
+ ppath_release(p);
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(replace);
+
+ATF_TC_HEAD(replace, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check that ppath_replace_idx() "
+ "and ppath_replace_key() produce the paths we expect without "
+ "leaking resources.");
+}
+
+ATF_TC_BODY(replace, tc)
+{
+ ppath_component_t *pc;
+ ppath_t *p, *cp, *rp;
+ unsigned int i;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ /* index replacement fails on an empty path */
+ rp = ppath_replace_idx(p, 0);
+ ATF_CHECK_EQ(rp, NULL);
+
+ /* key replacement fails on an empty path */
+ rp = ppath_replace_key(p, "key");
+ ATF_CHECK_EQ(rp, NULL);
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS; i++) {
+ if ((pc = ppath_idx(i)) == NULL)
+ atf_tc_fail("ppath_idx failed");
+ rp = ppath_push(p, pc);
+ ppath_component_release(pc);
+ ATF_CHECK_EQ(rp, p);
+ }
+
+ if ((cp = ppath_copy(p)) == NULL)
+ atf_tc_fail("ppath_copy failed");
+
+ rp = ppath_pop(cp, NULL);
+ ATF_CHECK_EQ(rp, cp);
+ rp = ppath_push_key(cp, "key");
+ ATF_CHECK_EQ(rp, cp);
+
+ ppath_replace_idx(p, 0);
+
+ if ((pc = ppath_component_at(p, PPATH_MAX_COMPONENTS - 1)) == NULL)
+ atf_tc_fail("ppath_idx failed");
+ ATF_CHECK_EQ(ppath_component_idx(pc), 0);
+ ppath_component_release(pc);
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS - 1; i++) {
+ if ((pc = ppath_component_at(p, i)) == NULL)
+ atf_tc_fail("ppath_idx failed");
+ ATF_CHECK_EQ(ppath_component_idx(pc), (int)i);
+ ppath_component_release(pc);
+ }
+
+ for (i = 0; i < PPATH_MAX_COMPONENTS - 1; i++) {
+ if ((pc = ppath_component_at(cp, i)) == NULL)
+ atf_tc_fail("ppath_idx failed");
+ ATF_CHECK_EQ(ppath_component_idx(pc), (int)i);
+ ppath_component_release(pc);
+ }
+
+ if ((pc = ppath_component_at(cp, PPATH_MAX_COMPONENTS - 1)) == NULL)
+ atf_tc_fail("ppath_idx failed");
+ if (ppath_component_key(pc) == NULL ||
+ strcmp(ppath_component_key(pc), "key") != 0)
+ atf_tc_fail("last path component expected to be \"key\"");
+ ppath_component_release(pc);
+ ppath_release(p);
+ ppath_release(cp);
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(copyset_object_twice_success);
+
+ATF_TC_HEAD(copyset_object_twice_success, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "check that after back-to-back ppath_copyset_object() calls, "
+ "changing the \"u.s. citizen\" property and the first property "
+ "in \"children\" in the \"John Doe\" record in the "
+ "\"personnel\" property list, the properties are changed "
+ "in the new dictionary and unchanged in the old dictionary");
+}
+
+ATF_TC_BODY(copyset_object_twice_success, tc)
+{
+ const char *s;
+ char *oext, *next;
+ int rc;
+ bool v = false;
+ prop_dictionary_t d, od;
+ prop_object_t nd = NULL, ond;
+ prop_object_t r, or;
+ ppath_t *p, *p2, *p3;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+ od = prop_dictionary_copy(d);
+
+ if (!dictionary_equals(od, d)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(d);
+ atf_tc_fail("dictionaries are unequal from the outset, argh! "
+ "original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ if ((p = ppath_create()) == NULL || (p2 = ppath_create()) == NULL ||
+ (p3 = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "u.s. citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ if (ppath_push_key(p2, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p2, "children") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_idx(p2, 0) == NULL)
+ atf_tc_fail("ppath_push_idx failed");
+
+ if (ppath_push_key(p3, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, true);
+
+ s = "";
+ rc = ppath_get_string(d, p2, &s);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_STREQ(s, "Jane Doe");
+
+ rc = ppath_copyset_bool(d, &nd, p, false);
+ ATF_CHECK_EQ(rc, 0);
+
+ rc = ppath_get_object(nd, p3, &r);
+ ATF_CHECK_EQ(rc, 0);
+
+ ond = nd;
+
+ rc = ppath_copyset_string(d, &nd, p2, "Martha Doe");
+ ATF_CHECK_EQ(rc, 0);
+
+ ATF_CHECK_EQ(nd, ond);
+
+ rc = ppath_get_object(nd, p3, &or);
+ ATF_CHECK_EQ(rc, 0);
+
+ ATF_CHECK_EQ(r, or);
+
+ v = true;
+ rc = ppath_get_bool(nd, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, false);
+
+ s = "";
+ rc = ppath_get_string(nd, p2, &s);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_STREQ(s, "Martha Doe");
+
+ if (!dictionary_equals(od, d)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(d);
+ atf_tc_fail("copydel modified original dictionary, "
+ "original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ if (dictionary_equals(od, nd)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(nd);
+ atf_tc_fail("copydel made no change to the new "
+ "dictionary, original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ rc = ppath_set_bool(od, p, false);
+ ATF_CHECK_EQ(rc, 0);
+
+ rc = ppath_set_string(od, p2, "Martha Doe");
+ ATF_CHECK_EQ(rc, 0);
+
+ if (!dictionary_equals(od, nd)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(nd);
+ atf_tc_fail("copydel made an out-of-bounds change to the new "
+ "dictionary, original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ ppath_release(p);
+ ppath_release(p2);
+ ppath_release(p3);
+ prop_object_release(d);
+ prop_object_release(od);
+ prop_object_release(nd);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(copydel_object_twice_success);
+
+ATF_TC_HEAD(copydel_object_twice_success, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "check that after back-to-back ppath_copydel_object() calls, "
+ "removing the \"u.s. citizen\" property and the first property "
+ "in \"children\" from the \"John Doe\" record in the "
+ "\"personnel\" property list, the properties are missing "
+ "from the new dictionary and unchanged in the old dictionary");
+}
+
+ATF_TC_BODY(copydel_object_twice_success, tc)
+{
+ const char *s;
+ char *oext, *next;
+ int rc;
+ bool v = false;
+ prop_dictionary_t d, od;
+ prop_object_t nd = NULL, ond;
+ prop_object_t r, or;
+ ppath_t *p, *p2, *p3;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+ od = prop_dictionary_copy(d);
+
+ if (!dictionary_equals(od, d)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(d);
+ atf_tc_fail("dictionaries are unequal from the outset, argh! "
+ "original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ if ((p = ppath_create()) == NULL || (p2 = ppath_create()) == NULL ||
+ (p3 = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "u.s. citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ if (ppath_push_key(p2, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p2, "children") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_idx(p2, 0) == NULL)
+ atf_tc_fail("ppath_push_idx failed");
+
+ if (ppath_push_key(p3, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, true);
+
+ s = "";
+ rc = ppath_get_string(d, p2, &s);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_STREQ(s, "Jane Doe");
+
+ rc = ppath_copydel_bool(d, &nd, p);
+ ATF_CHECK_EQ(rc, 0);
+
+ ond = nd;
+
+ rc = ppath_get_object(nd, p3, &r);
+ ATF_CHECK_EQ(rc, 0);
+
+ rc = ppath_copydel_string(d, &nd, p2);
+ ATF_CHECK_EQ(rc, 0);
+
+ ATF_CHECK_EQ(nd, ond);
+
+ rc = ppath_get_object(nd, p3, &or);
+ ATF_CHECK_EQ(rc, 0);
+
+ ATF_CHECK_EQ(r, or);
+
+ v = true;
+ rc = ppath_get_bool(nd, p, &v);
+ ATF_CHECK_EQ(rc, ENOENT);
+ ATF_CHECK_EQ(v, true);
+
+ if (!dictionary_equals(od, d)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(d);
+ atf_tc_fail("copydel modified original dictionary, "
+ "original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ if (dictionary_equals(od, nd)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(nd);
+ atf_tc_fail("copydel made no change to the new "
+ "dictionary, original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ rc = ppath_delete_bool(od, p);
+ ATF_CHECK_EQ(rc, 0);
+
+ rc = ppath_delete_string(od, p2);
+ ATF_CHECK_EQ(rc, 0);
+
+ if (!dictionary_equals(od, nd)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(nd);
+ atf_tc_fail("copydel made an out-of-bounds change to the new "
+ "dictionary, original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ ppath_release(p);
+ ppath_release(p2);
+ ppath_release(p3);
+ prop_object_release(d);
+ prop_object_release(od);
+ prop_object_release(nd);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(copydel_bool_success);
+
+ATF_TC_HEAD(copydel_bool_success, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_copydel_bool() deletes "
+ "the \"u.s. citizen\" property in the \"John Doe\" record in the "
+ "\"personnel\" property list and verifies the value is missing "
+ "from the new dictionary and unchanged in the old dictionary");
+}
+
+ATF_TC_BODY(copydel_bool_success, tc)
+{
+ char *oext, *next;
+ int rc;
+ bool v = false;
+ prop_dictionary_t d, od;
+ prop_object_t nd = NULL;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+ od = prop_dictionary_copy(d);
+
+ if (!dictionary_equals(od, d)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(d);
+ atf_tc_fail("dictionaries are unequal from the outset, argh! "
+ "original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "u.s. citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, true);
+
+ rc = ppath_copydel_bool(d, &nd, p);
+ ATF_CHECK_EQ(rc, 0);
+
+ v = true;
+ rc = ppath_get_bool(nd, p, &v);
+ ATF_CHECK_EQ(rc, ENOENT);
+ ATF_CHECK_EQ(v, true);
+
+ if (!dictionary_equals(od, d)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(d);
+ atf_tc_fail("copydel modified original dictionary, "
+ "original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ if (dictionary_equals(od, nd)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(nd);
+ atf_tc_fail("copydel made no change to the new "
+ "dictionary, original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ rc = ppath_delete_bool(od, p);
+ ATF_CHECK_EQ(rc, 0);
+
+ if (!dictionary_equals(od, nd)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(nd);
+ atf_tc_fail("copydel made an out-of-bounds change to the new "
+ "dictionary, original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ ppath_release(p);
+ prop_object_release(d);
+ prop_object_release(od);
+ prop_object_release(nd);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(copyset_bool_success);
+
+ATF_TC_HEAD(copyset_bool_success, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_copyset_bool() sets "
+ "the \"u.s. citizen\" property in the \"John Doe\" record in the "
+ "\"personnel\" property list to false and verifies the new value "
+ "in the new dictionary and that the old dictionary is unchanged");
+}
+
+ATF_TC_BODY(copyset_bool_success, tc)
+{
+ char *oext, *next;
+ int rc;
+ bool v = false;
+ prop_dictionary_t d, od;
+ prop_object_t nd = NULL;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+ od = prop_dictionary_copy(d);
+
+ if (!dictionary_equals(od, d)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(d);
+ atf_tc_fail("dictionaries are unequal from the outset, argh! "
+ "original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "u.s. citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, true);
+
+ rc = ppath_copyset_bool(d, &nd, p, false);
+ ATF_CHECK_EQ(rc, 0);
+
+ v = true;
+ rc = ppath_get_bool(nd, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, false);
+
+ if (!dictionary_equals(od, d)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(d);
+ atf_tc_fail("copyset modified original dictionary, "
+ "original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ if (dictionary_equals(od, nd)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(nd);
+ atf_tc_fail("copyset made no change to the new "
+ "dictionary, original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ rc = ppath_set_bool(nd, p, true);
+ ATF_CHECK_EQ(rc, 0);
+
+ if (!dictionary_equals(od, nd)) {
+ oext = prop_dictionary_externalize(od);
+ next = prop_dictionary_externalize(nd);
+ atf_tc_fail("copyset made an out-of-bounds change to the new "
+ "dictionary, original\n%s\nnew\n%s", oext, next);
+ free(oext);
+ free(next);
+ }
+
+ ppath_release(p);
+ prop_object_release(d);
+ prop_object_release(od);
+ prop_object_release(nd);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(set_bool_eftype);
+
+ATF_TC_HEAD(set_bool_eftype, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() does not "
+ "overwrite with a bool "
+ "the \"job title\" property in the \"John Doe\" record in "
+ "the "
+ "\"personnel\" property list");
+}
+
+ATF_TC_BODY(set_bool_eftype, tc)
+{
+ int rc;
+ bool v = false;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "job title") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, EFTYPE);
+ ATF_CHECK_EQ(v, false);
+
+ rc = ppath_set_bool(d, p, false);
+ ATF_CHECK_EQ(rc, EFTYPE);
+
+ v = true;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, EFTYPE);
+ ATF_CHECK_EQ(v, true);
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(set_bool_enoent);
+
+ATF_TC_HEAD(set_bool_enoent, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() does not create "
+ "the \"russian citizen\" property in the \"John Doe\" record in "
+ "the "
+ "\"personnel\" property list");
+}
+
+ATF_TC_BODY(set_bool_enoent, tc)
+{
+ int rc;
+ bool v = false;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "russian citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, ENOENT);
+ ATF_CHECK_EQ(v, false);
+
+ rc = ppath_set_bool(d, p, false);
+ ATF_CHECK_EQ(rc, ENOENT);
+
+ v = true;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, ENOENT);
+ ATF_CHECK_EQ(v, true);
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(create_bool_eexist);
+
+ATF_TC_HEAD(create_bool_eexist, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_create_bool() returns "
+ "EEXIST because the \"u.s. citizen\" property in the "
+ "\"John Doe\" record in the \"personnel\" property list "
+ "already exists");
+}
+
+ATF_TC_BODY(create_bool_eexist, tc)
+{
+ int rc;
+ bool v = false;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "u.s. citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, true);
+
+ rc = ppath_create_bool(d, p, false);
+ ATF_CHECK_EQ(rc, EEXIST);
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, true);
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(create_bool_success);
+
+ATF_TC_HEAD(create_bool_success, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_create_bool() creates "
+ "the \"russian citizen\" property in the \"John Doe\" record in "
+ "the \"personnel\" property list and sets it to false");
+}
+
+ATF_TC_BODY(create_bool_success, tc)
+{
+ int rc;
+ bool v = false;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "russian citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, ENOENT);
+ ATF_CHECK_EQ(v, false);
+
+ rc = ppath_create_bool(d, p, false);
+ ATF_CHECK_EQ(rc, 0);
+
+ v = true;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, false);
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(set_bool_success);
+
+ATF_TC_HEAD(set_bool_success, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_set_bool() sets "
+ "the \"u.s. citizen\" property in the \"John Doe\" record in the "
+ "\"personnel\" property list to false and verifies the new value");
+}
+
+ATF_TC_BODY(set_bool_success, tc)
+{
+ int rc;
+ bool v = false;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "u.s. citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, true);
+
+ rc = ppath_set_bool(d, p, v);
+ ATF_CHECK_EQ(rc, 0);
+
+ v = true;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, true);
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(get_bool_success);
+
+ATF_TC_HEAD(get_bool_success, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() fetches "
+ "the \"u.s. citizen\" property from the \"John Doe\" record in the "
+ "\"personnel\" property list, and compares it with the expected "
+ "value, true");
+}
+
+ATF_TC_BODY(get_bool_success, tc)
+{
+ int rc;
+ bool v = false;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "u.s. citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_EQ(v, true);
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(delete_bool_success);
+
+ATF_TC_HEAD(delete_bool_success, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() succeeds "
+ "for the path (\"John Doe\", \"u.s. citizen\") in the "
+ "\"personnel\" property list");
+}
+
+ATF_TC_BODY(delete_bool_success, tc)
+{
+ int rc;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "u.s. citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ rc = ppath_delete_bool(d, p);
+ ATF_CHECK_EQ(rc, 0);
+
+ rc = ppath_get_bool(d, p, NULL);
+ ATF_CHECK_EQ(rc, ENOENT);
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(delete_bool_eftype);
+
+ATF_TC_HEAD(delete_bool_eftype, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() returns "
+ "EFTYPE for the path (\"John Doe\", \"job title\") in the "
+ "\"personnel\" property list and does not delete the path");
+}
+
+ATF_TC_BODY(delete_bool_eftype, tc)
+{
+ int rc;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "job title") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ rc = ppath_delete_bool(d, p);
+ ATF_CHECK_EQ(rc, EFTYPE);
+
+ rc = ppath_get_object(d, p, NULL);
+ ATF_CHECK_EQ(rc, 0);
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(delete_bool_enoent);
+
+ATF_TC_HEAD(delete_bool_enoent, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_delete_bool() returns "
+ "ENOENT for the path (\"John Doe\", \"citizen\") in the "
+ "\"personnel\" property list");
+}
+
+ATF_TC_BODY(delete_bool_enoent, tc)
+{
+ int rc;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ rc = ppath_delete_bool(d, p);
+ ATF_CHECK_EQ(rc, ENOENT);
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(get_bool_enoent);
+
+ATF_TC_HEAD(get_bool_enoent, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() returns "
+ "ENOENT for the path (\"John Doe\", \"citizen\") in the "
+ "\"personnel\" property list, and the bool * argument is "
+ "unchanged");
+}
+
+ATF_TC_BODY(get_bool_enoent, tc)
+{
+ int rc;
+ bool v;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = true;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, ENOENT);
+ ATF_CHECK_EQ(v, true);
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, ENOENT);
+ ATF_CHECK_EQ(v, false);
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(get_bool_eftype);
+
+ATF_TC_HEAD(get_bool_eftype, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_get_bool() returns "
+ "EFTYPE for the path (\"John Doe\", \"job title\") in the "
+ "\"personnel\" property list, and the bool * argument is "
+ "unchanged");
+}
+
+ATF_TC_BODY(get_bool_eftype, tc)
+{
+ int rc;
+ bool v;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "job title") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = true;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, EFTYPE);
+ ATF_CHECK_EQ(v, true);
+
+ v = false;
+ rc = ppath_get_bool(d, p, &v);
+ ATF_CHECK_EQ(rc, EFTYPE);
+ ATF_CHECK_EQ(v, false);
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(get_string_eftype);
+
+ATF_TC_HEAD(get_string_eftype, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_get_string() returns "
+ "EFTYPE for the path (\"John Doe\", \"u.s. citizen\") in the "
+ "\"personnel\" property list, and the const char ** argument is "
+ "unchanged");
+}
+
+ATF_TC_BODY(get_string_eftype, tc)
+{
+ int rc;
+ const char *v;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "u.s. citizen") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = NULL;
+ rc = ppath_get_string(d, p, &v);
+ ATF_CHECK_EQ(rc, EFTYPE);
+ ATF_CHECK_EQ(v, NULL);
+
+ v = "xyz";
+ rc = ppath_get_string(d, p, &v);
+ ATF_CHECK_EQ(rc, EFTYPE);
+ ATF_CHECK_STREQ(v, "xyz");
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(get_string_enoent);
+
+ATF_TC_HEAD(get_string_enoent, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_get_string() returns "
+ "ENOENT for the path (\"John Doe\", \"title\") in the "
+ "\"personnel\" property list, and the const char ** argument is "
+ "unchanged");
+}
+
+ATF_TC_BODY(get_string_enoent, tc)
+{
+ int rc;
+ const char *v;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "title") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ v = NULL;
+ rc = ppath_get_string(d, p, &v);
+ ATF_CHECK_EQ(rc, ENOENT);
+ ATF_CHECK_EQ(v, NULL);
+
+ v = "xyz";
+ rc = ppath_get_string(d, p, &v);
+ ATF_CHECK_EQ(rc, ENOENT);
+ ATF_CHECK_STREQ(v, "xyz");
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TC(get_string_success);
+
+ATF_TC_HEAD(get_string_success, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "check ppath_get_string() fetches "
+ "the \"job title\" property from the \"John Doe\" record in the "
+ "\"personnel\" property list and compares it with the expected "
+ "value, \"computer programmer\"");
+}
+
+ATF_TC_BODY(get_string_success, tc)
+{
+ int rc;
+ const char *v = NULL;;
+ prop_dictionary_t d;
+ ppath_t *p;
+
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+
+ if ((d = prop_dictionary_internalize(personnel)) == NULL)
+ atf_tc_fail("prop_dictionary_internalize failed");
+
+ if ((p = ppath_create()) == NULL)
+ atf_tc_fail("ppath_create failed");
+
+ if (ppath_push_key(p, "John Doe") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+ if (ppath_push_key(p, "job title") == NULL)
+ atf_tc_fail("ppath_push_key failed");
+
+ rc = ppath_get_string(d, p, &v);
+ ATF_CHECK_EQ(rc, 0);
+ ATF_CHECK_STREQ(v, "computer programmer");
+
+ ppath_release(p);
+ prop_object_release(d);
+ assert_no_ppath_extant();
+ assert_no_ppath_component_extant();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, push_until_full);
+ ATF_TP_ADD_TC(tp, pop_until_empty);
+ ATF_TP_ADD_TC(tp, length);
+ ATF_TP_ADD_TC(tp, component_at);
+ ATF_TP_ADD_TC(tp, get_idx_key);
+ ATF_TP_ADD_TC(tp, ppath_copy);
+ ATF_TP_ADD_TC(tp, replace);
+
+ ATF_TP_ADD_TC(tp, delete_bool_eftype);
+ ATF_TP_ADD_TC(tp, delete_bool_enoent);
+ ATF_TP_ADD_TC(tp, delete_bool_success);
+
+ ATF_TP_ADD_TC(tp, get_bool_eftype);
+ ATF_TP_ADD_TC(tp, get_bool_enoent);
+ ATF_TP_ADD_TC(tp, get_bool_success);
+
+ ATF_TP_ADD_TC(tp, copydel_bool_success);
+ ATF_TP_ADD_TC(tp, copydel_object_twice_success);
+ ATF_TP_ADD_TC(tp, copyset_object_twice_success);
+ ATF_TP_ADD_TC(tp, copyset_bool_success);
+ ATF_TP_ADD_TC(tp, create_bool_eexist);
+ ATF_TP_ADD_TC(tp, create_bool_success);
+ ATF_TP_ADD_TC(tp, set_bool_enoent);
+ ATF_TP_ADD_TC(tp, set_bool_eftype);
+ ATF_TP_ADD_TC(tp, set_bool_success);
+
+ ATF_TP_ADD_TC(tp, get_string_eftype);
+ ATF_TP_ADD_TC(tp, get_string_enoent);
+ ATF_TP_ADD_TC(tp, get_string_success);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libprop/t_basic.c b/contrib/netbsd-tests/lib/libprop/t_basic.c
new file mode 100644
index 0000000..febf29d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libprop/t_basic.c
@@ -0,0 +1,203 @@
+/* $NetBSD: t_basic.c,v 1.4 2011/04/20 20:02:58 martin Exp $ */
+
+/*
+ * 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.
+ */
+
+/*
+ * Written by Jason Thorpe 5/26/2006.
+ * Public domain.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_basic.c,v 1.4 2011/04/20 20:02:58 martin Exp $");
+
+#include <stdlib.h>
+#include <string.h>
+#include <prop/proplib.h>
+
+#include <atf-c.h>
+
+static const char compare1[] =
+"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+"<plist version=\"1.0\">\n"
+"<dict>\n"
+" <key>false-val</key>\n"
+" <false/>\n"
+" <key>one</key>\n"
+" <integer>1</integer>\n"
+" <key>three</key>\n"
+" <array>\n"
+" <dict>\n"
+" <key>one</key>\n"
+" <integer>1</integer>\n"
+" <key>two</key>\n"
+" <string>number-two</string>\n"
+" </dict>\n"
+" <dict>\n"
+" <key>one</key>\n"
+" <integer>1</integer>\n"
+" <key>two</key>\n"
+" <string>number-two</string>\n"
+" </dict>\n"
+" <dict>\n"
+" <key>one</key>\n"
+" <integer>1</integer>\n"
+" <key>two</key>\n"
+" <string>number-two</string>\n"
+" </dict>\n"
+" </array>\n"
+" <key>true-val</key>\n"
+" <true/>\n"
+" <key>two</key>\n"
+" <string>number-two</string>\n"
+"</dict>\n"
+"</plist>\n";
+
+ATF_TC(prop_basic);
+ATF_TC_HEAD(prop_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of proplib(3)");
+}
+
+ATF_TC_BODY(prop_basic, tc)
+{
+ prop_dictionary_t dict;
+ char *ext1;
+
+ dict = prop_dictionary_create();
+ ATF_REQUIRE(dict != NULL);
+
+ {
+ prop_number_t num = prop_number_create_integer(1);
+ ATF_REQUIRE(num != NULL);
+
+ ATF_REQUIRE_EQ(prop_dictionary_set(dict, "one", num), true);
+ prop_object_release(num);
+ }
+
+ {
+ prop_string_t str = prop_string_create_cstring("number-two");
+ ATF_REQUIRE(str != NULL);
+
+ ATF_REQUIRE_EQ(prop_dictionary_set(dict, "two", str), true);
+ prop_object_release(str);
+ }
+
+ {
+ prop_array_t arr;
+ prop_dictionary_t dict_copy;
+ int i;
+
+ arr = prop_array_create();
+ ATF_REQUIRE(arr != NULL);
+
+ for (i = 0; i < 3; ++i) {
+ dict_copy = prop_dictionary_copy(dict);
+ ATF_REQUIRE(dict_copy != NULL);
+ ATF_REQUIRE_EQ(prop_array_add(arr, dict_copy), true);
+ prop_object_release(dict_copy);
+ }
+
+ ATF_REQUIRE_EQ(prop_dictionary_set(dict, "three", arr), true);
+ prop_object_release(arr);
+ }
+
+ {
+ prop_bool_t val = prop_bool_create(true);
+ ATF_REQUIRE(val != NULL);
+ ATF_REQUIRE_EQ(prop_dictionary_set(dict, "true-val", val), true);
+ prop_object_release(val);
+
+ val = prop_bool_create(false);
+ ATF_REQUIRE(val != NULL);
+ ATF_REQUIRE_EQ(prop_dictionary_set(dict, "false-val", val), true);
+ prop_object_release(val);
+ }
+
+ ext1 = prop_dictionary_externalize(dict);
+ ATF_REQUIRE(ext1 != NULL);
+ ATF_REQUIRE_STREQ(compare1, ext1);
+
+ {
+ prop_dictionary_t dict2;
+ char *ext2;
+
+ dict2 = prop_dictionary_internalize(ext1);
+ ATF_REQUIRE(dict2 != NULL);
+ ext2 = prop_dictionary_externalize(dict2);
+ ATF_REQUIRE(ext2 != NULL);
+ ATF_REQUIRE_STREQ(ext1, ext2);
+ prop_object_release(dict2);
+ free(ext2);
+ }
+
+ prop_object_release(dict);
+ free(ext1);
+}
+
+ATF_TC(prop_dictionary_equals);
+ATF_TC_HEAD(prop_dictionary_equals, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test prop_dictionary_equals(3)");
+}
+
+ATF_TC_BODY(prop_dictionary_equals, tc)
+{
+ prop_dictionary_t c, d;
+
+ /*
+ * Fixed, should not fail any more...
+ *
+ atf_tc_expect_death("PR lib/43964");
+ *
+ */
+
+ d = prop_dictionary_internalize(compare1);
+
+ ATF_REQUIRE(d != NULL);
+
+ c = prop_dictionary_copy(d);
+
+ ATF_REQUIRE(c != NULL);
+
+ if (prop_dictionary_equals(c, d) != true)
+ atf_tc_fail("dictionaries are not equal");
+
+ prop_object_release(c);
+ prop_object_release(d);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, prop_basic);
+ ATF_TP_ADD_TC(tp, prop_dictionary_equals);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/d_mach b/contrib/netbsd-tests/lib/libpthread/d_mach
new file mode 100644
index 0000000..f3c3981
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/d_mach
@@ -0,0 +1,92 @@
+above.warped.net
+anoncvs.cirr.com
+anoncvs.isc.netbsd.org
+anoncvs.leo.org
+anoncvs.netbsd.lt
+anoncvs.netbsd.ro
+anoncvs.netbsd.se
+antioche.antioche.eu.org
+boulder.tele.dk
+centaurus.4web.cz
+chur.math.ntnu.no
+cnftp.bjpu.edu.cn
+console.netbsd.org
+cvs.fi.netbsd.org
+cvs.mikrolahti.fi
+cvs.netbsd.org
+cvsup-netbsd.leo.org
+cvsup.netbsd.se
+cvsup.pasta.cs.uit.no
+ftp.bitcon.no
+ftp.chg.ru
+ftp.duth.gr
+ftp.estpak.ee
+ftp.fsn.hu
+ftp.funet.fi
+ftp.grondar.za
+ftp.leo.org
+ftp.netbsd.lt
+ftp.netbsd.org
+ftp.nluug.nl
+ftp.plig.org
+ftp.uni-erlangen.de
+ftp.xgate.co.kr
+gd.tuwien.ac.at
+gort.ludd.luth.se
+grappa.unix-ag.uni-kl.de
+info.wins.uva.nl
+irc.warped.net
+knug.youn.co.kr
+lala.iri.co.jp
+mail.jp.netbsd.org
+mail.kr.netbsd.org
+mail.netbsd.org
+melanoma.cs.rmit.edu.au
+mirror.aarnet.edu.au
+mirror.netbsd.com.br
+mirror03.inet.tele.dk
+moon.vub.ac.be
+nbwww.sergei.cc
+net.bsd.cz
+netbsd.3miasto.net
+netbsd.4ka.mipt.ru
+netbsd.apk.od.ua
+netbsd.csie.nctu.edu.tw
+netbsd.enderunix.org
+netbsd.ftp.fu-berlin.de
+netbsd.netlead.com.au
+netbsd.nsysu.edu.tw
+netbsd.pair.com
+netbsd.stevens-tech.edu
+netbsd.triada.bg
+netbsd.unix.net.nz
+netbsd.unixtech.be
+netbsd.vejas.lt
+netbsd.wagener-consulting.lu
+netbsd.zarco.org
+netbsdiso.interoute.net.uk
+netbsdwww.bitcon.no
+netbsdwww.cordef.com.pl
+netbsdwww.cs.rmit.edu.au
+netbsdwww.interoute.net.uk
+news.gw.com
+ns.netbsd.org
+pigu.iri.co.jp
+pluto.cdpa.nsysu.edu.tw
+projects.slowass.net
+server6.pasta.cs.uit.no
+skeleton.phys.spbu.ru
+snoopy.allbsd.org
+spike.allbsd.org
+sundry.netbsd.org
+tanya.sergei.cc
+web-a.fi.gw.com
+web-a.us.gw.com
+web.netbsd.mirror.arhea.net
+www.en.netbsd.de
+www.netbsd.cl
+www.netbsd.nl
+www.netbsd.org
+www.netbsd.ro
+zathras.netbsd.org
+zeppo.rediris.es
diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/dso/h_pthread_dlopen.c b/contrib/netbsd-tests/lib/libpthread/dlopen/dso/h_pthread_dlopen.c
new file mode 100644
index 0000000..63bf6a3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/dlopen/dso/h_pthread_dlopen.c
@@ -0,0 +1,86 @@
+/* $NetBSD: h_pthread_dlopen.c,v 1.1 2013/03/21 16:50:22 christos Exp $ */
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus.
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: h_pthread_dlopen.c,v 1.1 2013/03/21 16:50:22 christos Exp $");
+
+#if 0
+#include <atf-c.h>
+#else
+#include <assert.h>
+#define ATF_REQUIRE(a) assert(a)
+#endif
+#include <unistd.h>
+#include <pthread.h>
+
+int testf_dso_null(void);
+int testf_dso_mutex_lock(pthread_mutex_t *);
+int testf_dso_mutex_unlock(pthread_mutex_t *);
+int testf_dso_pthread_create(pthread_t *, const pthread_attr_t *,
+ void *(*)(void *), void *);
+
+int
+testf_dso_null(void)
+{
+ return 0xcafe;
+}
+
+int
+testf_dso_mutex_lock(pthread_mutex_t *mtx)
+{
+ ATF_REQUIRE(mtx != NULL);
+ ATF_REQUIRE(pthread_mutex_lock(mtx) == 0);
+
+ return 0xcafe;
+}
+
+int
+testf_dso_mutex_unlock(pthread_mutex_t *mtx)
+{
+ ATF_REQUIRE(mtx != NULL);
+ ATF_REQUIRE(pthread_mutex_unlock(mtx) == 0);
+
+ return 0xcafe;
+}
+
+int
+testf_dso_pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+ void *(*routine)(void *), void *arg)
+{
+ int ret;
+
+ ret = pthread_create(thread, attr, routine, arg);
+ ATF_REQUIRE(ret == 0);
+
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/t_dlopen.c b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dlopen.c
new file mode 100644
index 0000000..68e9835
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dlopen.c
@@ -0,0 +1,171 @@
+/* $NetBSD: t_dlopen.c,v 1.1 2013/03/21 16:50:21 christos Exp $ */
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_dlopen.c,v 1.1 2013/03/21 16:50:21 christos Exp $");
+
+#include <atf-c.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <unistd.h>
+
+ATF_TC(dlopen);
+
+ATF_TC_HEAD(dlopen, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test if dlopen can load -lpthread DSO");
+}
+
+#define DSO TESTDIR "/h_pthread_dlopen.so"
+
+ATF_TC_BODY(dlopen, tc)
+{
+ void *handle;
+ int (*testf_dso_null)(void);
+ handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL);
+ ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror());
+
+ testf_dso_null = dlsym(handle, "testf_dso_null");
+ ATF_REQUIRE_MSG(testf_dso_null != NULL, "dlsym fails: %s", dlerror());
+
+ ATF_REQUIRE(testf_dso_null() == 0xcafe);
+
+ ATF_REQUIRE(dlclose(handle) == 0);
+}
+
+ATF_TC(dlopen_mutex);
+
+ATF_TC_HEAD(dlopen_mutex, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test if dlopen can load -lpthread DSO without breaking mutex");
+}
+
+ATF_TC_BODY(dlopen_mutex, tc)
+{
+ pthread_mutex_t mtx;
+ void *handle;
+ int (*testf_dso_null)(void);
+
+ ATF_REQUIRE(pthread_mutex_init(&mtx, NULL) == 0);
+ ATF_REQUIRE(pthread_mutex_lock(&mtx) == 0);
+
+ handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL);
+ ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror());
+
+ testf_dso_null = dlsym(handle, "testf_dso_null");
+ ATF_REQUIRE_MSG(testf_dso_null != NULL, "dlsym fails: %s", dlerror());
+
+ ATF_REQUIRE(testf_dso_null() == 0xcafe);
+
+ ATF_REQUIRE(pthread_mutex_unlock(&mtx) == 0);
+
+ ATF_REQUIRE(dlclose(handle) == 0);
+
+ pthread_mutex_destroy(&mtx);
+}
+
+ATF_TC(dlopen_mutex_libc);
+
+ATF_TC_HEAD(dlopen_mutex_libc, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test if dlopen can load -lpthread DSO and use libc locked mutex");
+}
+
+ATF_TC_BODY(dlopen_mutex_libc, tc)
+{
+ pthread_mutex_t mtx;
+ void *handle;
+ int (*testf_dso_mutex_unlock)(pthread_mutex_t *);
+
+ ATF_REQUIRE(pthread_mutex_init(&mtx, NULL) == 0);
+ ATF_REQUIRE(pthread_mutex_lock(&mtx) == 0);
+
+ handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL);
+ ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror());
+
+ testf_dso_mutex_unlock = dlsym(handle, "testf_dso_mutex_unlock");
+ ATF_REQUIRE_MSG(testf_dso_mutex_unlock != NULL,
+ "dlsym fails: %s", dlerror());
+
+ ATF_REQUIRE(testf_dso_mutex_unlock(&mtx) == 0xcafe);
+
+ dlclose(handle);
+
+ pthread_mutex_destroy(&mtx);
+}
+
+ATF_TC(dlopen_mutex_libpthread);
+
+ATF_TC_HEAD(dlopen_mutex_libpthread, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test if dlopen can load -lpthread DSO and use "
+ "libpthread locked mutex");
+}
+
+ATF_TC_BODY(dlopen_mutex_libpthread, tc)
+{
+ pthread_mutex_t mtx;
+ void *handle;
+ int (*testf_dso_mutex_lock)(pthread_mutex_t *);
+
+ ATF_REQUIRE(pthread_mutex_init(&mtx, NULL) == 0);
+
+ handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL);
+ ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror());
+
+ testf_dso_mutex_lock = dlsym(handle, "testf_dso_mutex_lock");
+ ATF_REQUIRE_MSG(testf_dso_mutex_lock != NULL,
+ "dlsym fails: %s", dlerror());
+
+ ATF_REQUIRE(testf_dso_mutex_lock(&mtx) == 0xcafe);
+
+ ATF_REQUIRE(pthread_mutex_unlock(&mtx) == 0);
+
+ dlclose(handle);
+
+ pthread_mutex_destroy(&mtx);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, dlopen);
+ ATF_TP_ADD_TC(tp, dlopen_mutex);
+ ATF_TP_ADD_TC(tp, dlopen_mutex_libc);
+ ATF_TP_ADD_TC(tp, dlopen_mutex_libpthread);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/t_dso_pthread_create.c b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dso_pthread_create.c
new file mode 100644
index 0000000..ab8bec3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/dlopen/t_dso_pthread_create.c
@@ -0,0 +1,96 @@
+/* $NetBSD: t_dso_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $ */
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_dso_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $");
+
+#include <sys/resource.h>
+#include <atf-c.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#define DSO TESTDIR "/h_pthread_dlopen.so"
+
+void *
+routine(void *arg)
+{
+ ATF_REQUIRE((intptr_t)arg == 0xcafe);
+ return NULL;
+}
+
+ATF_TC(dso_pthread_create_dso);
+
+ATF_TC_HEAD(dso_pthread_create_dso, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test if non -lpthread main can call pthread_create() "
+ "in -lpthread DSO");
+}
+
+ATF_TC_BODY(dso_pthread_create_dso, tc)
+{
+ int ret;
+ pthread_t thread;
+ void *arg = (void *)0xcafe;
+ void *handle;
+ int (*testf_dso_pthread_create)(pthread_t *, pthread_attr_t *,
+ void *(*)(void *), void *);
+ struct rlimit rl;
+
+ atf_tc_expect_signal(6,
+ "calling pthread_create() requires -lpthread main");
+
+ rl.rlim_max = rl.rlim_cur = 0;
+ ATF_REQUIRE_EQ(setrlimit(RLIMIT_CORE, &rl), 0);
+
+ handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL);
+ ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror());
+
+ testf_dso_pthread_create = dlsym(handle, "testf_dso_pthread_create");
+ ATF_REQUIRE_MSG(testf_dso_pthread_create != NULL,
+ "dlsym fails: %s", dlerror());
+
+ ret = testf_dso_pthread_create(&thread, NULL, routine, arg);
+ ATF_REQUIRE(ret == 0);
+
+ ATF_REQUIRE(dlclose(handle) == 0);
+
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, dso_pthread_create_dso);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/dlopen/t_main_pthread_create.c b/contrib/netbsd-tests/lib/libpthread/dlopen/t_main_pthread_create.c
new file mode 100644
index 0000000..7ba89b3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/dlopen/t_main_pthread_create.c
@@ -0,0 +1,106 @@
+/* $NetBSD: t_main_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $ */
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Emmanuel Dreyfus
+ *
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_main_pthread_create.c,v 1.1 2013/03/21 16:50:21 christos Exp $");
+
+#include <atf-c.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#define DSO TESTDIR "/h_pthread_dlopen.so"
+
+void *
+routine(void *arg)
+{
+ ATF_REQUIRE((intptr_t)arg == 0xcafe);
+ return NULL;
+}
+
+ATF_TC(main_pthread_create_main);
+
+ATF_TC_HEAD(main_pthread_create_main, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test if -lpthread main can call pthread_create() in main()");
+}
+
+ATF_TC_BODY(main_pthread_create_main, tc)
+{
+ int ret;
+ pthread_t thread;
+ void *arg = (void *)0xcafe;
+
+ ret = pthread_create(&thread, NULL, routine, arg);
+ ATF_REQUIRE(ret == 0);
+}
+
+ATF_TC(main_pthread_create_dso);
+
+ATF_TC_HEAD(main_pthread_create_dso, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test if -lpthread main can call pthread_create() in DSO");
+}
+
+ATF_TC_BODY(main_pthread_create_dso, tc)
+{
+ int ret;
+ pthread_t thread;
+ void *arg = (void *)0xcafe;
+ void *handle;
+ int (*testf_dso_pthread_create)(pthread_t *, pthread_attr_t *,
+ void *(*)(void *), void *);
+
+ handle = dlopen(DSO, RTLD_NOW | RTLD_LOCAL);
+ ATF_REQUIRE_MSG(handle != NULL, "dlopen fails: %s", dlerror());
+
+ testf_dso_pthread_create = dlsym(handle, "testf_dso_pthread_create");
+ ATF_REQUIRE_MSG(testf_dso_pthread_create != NULL,
+ "dlsym fails: %s", dlerror());
+
+ ret = testf_dso_pthread_create(&thread, NULL, routine, arg);
+ ATF_REQUIRE(ret == 0);
+
+ ATF_REQUIRE(dlclose(handle) == 0);
+
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, main_pthread_create_main);
+ ATF_TP_ADD_TC(tp, main_pthread_create_dso);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/h_atexit.c b/contrib/netbsd-tests/lib/libpthread/h_atexit.c
new file mode 100644
index 0000000..29b8775
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/h_atexit.c
@@ -0,0 +1,203 @@
+/* $NetBSD: h_atexit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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.
+ */
+
+/*
+ * Program to test atexit(3) and __cxa_atexit()/__cxa_finalize().
+ *
+ * Written by Jason R. Thorpe, February 2003.
+ * Public domain.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_atexit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+extern int __cxa_atexit(void (*func)(void *), void *, void *);
+extern void __cxa_finalize(void *);
+
+#ifdef __FreeBSD__
+/*
+ * See comments in ../../lib/libc/stdlib/h_atexit.c about the deviation
+ * between FreeBSD and NetBSD with this helper program
+ */
+static void *dso_handle_1 = (void *)1;
+static void *dso_handle_2 = (void *)2;
+static void *dso_handle_3 = (void *)3;
+#else
+static int dso_handle_1;
+static int dso_handle_2;
+static int dso_handle_3;
+#endif
+
+static int arg_1;
+static int arg_2;
+static int arg_3;
+
+static int exiting_state;
+
+#define ASSERT(expr) \
+do { \
+ if ((expr) == 0) { \
+ write(STDERR_FILENO, __func__, strlen(__func__)); \
+ write(STDERR_FILENO, ": ", 2); \
+ write(STDERR_FILENO, __STRING(expr), \
+ strlen(__STRING(expr))); \
+ write(STDERR_FILENO, "\n", 1); \
+ my_abort(); \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SUCCESS() \
+do { \
+ write(STDOUT_FILENO, __func__, strlen(__func__)); \
+ write(STDOUT_FILENO, "\n", 1); \
+} while (/*CONSTCOND*/0)
+
+static void
+my_abort(void)
+{
+
+ kill(getpid(), SIGABRT);
+ /* NOTREACHED */
+}
+
+static void
+cxa_handler_5(void *arg)
+{
+ static int cxa_handler_5_called;
+
+ ASSERT(arg == (void *)&arg_1);
+ ASSERT(cxa_handler_5_called == 0);
+ ASSERT(exiting_state == 5);
+
+ exiting_state--;
+ cxa_handler_5_called = 1;
+ SUCCESS();
+}
+
+static void
+cxa_handler_4(void *arg)
+{
+ static int cxa_handler_4_called;
+
+ ASSERT(arg == (void *)&arg_1);
+ ASSERT(cxa_handler_4_called == 0);
+ ASSERT(exiting_state == 4);
+
+ exiting_state--;
+ cxa_handler_4_called = 1;
+ SUCCESS();
+}
+
+static void
+cxa_handler_3(void *arg)
+{
+ static int cxa_handler_3_called;
+
+ ASSERT(arg == (void *)&arg_2);
+ ASSERT(cxa_handler_3_called == 0);
+ ASSERT(exiting_state == 3);
+
+ exiting_state--;
+ cxa_handler_3_called = 1;
+ SUCCESS();
+}
+
+static void
+cxa_handler_2(void *arg)
+{
+ static int cxa_handler_2_called;
+
+ ASSERT(arg == (void *)&arg_3);
+ ASSERT(cxa_handler_2_called == 0);
+ ASSERT(exiting_state == 2);
+
+ exiting_state--;
+ cxa_handler_2_called = 1;
+ SUCCESS();
+}
+
+static void
+normal_handler_1(void)
+{
+ static int normal_handler_1_called;
+
+ ASSERT(normal_handler_1_called == 0);
+ ASSERT(exiting_state == 1);
+
+ exiting_state--;
+ normal_handler_1_called = 1;
+ SUCCESS();
+}
+
+static void
+normal_handler_0(void)
+{
+ static int normal_handler_0_called;
+
+ ASSERT(normal_handler_0_called == 0);
+ ASSERT(exiting_state == 0);
+
+ normal_handler_0_called = 1;
+ SUCCESS();
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ exiting_state = 5;
+
+#ifdef __FreeBSD__
+ ASSERT(0 == atexit(normal_handler_0));
+ ASSERT(0 == atexit(normal_handler_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, dso_handle_2));
+ ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, dso_handle_3));
+
+ __cxa_finalize(dso_handle_1);
+ __cxa_finalize(dso_handle_2);
+#else
+ ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2));
+ ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, &dso_handle_3));
+
+ __cxa_finalize(&dso_handle_1);
+ __cxa_finalize(&dso_handle_2);
+#endif
+ exit(0);
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/h_cancel.c b/contrib/netbsd-tests/lib/libpthread/h_cancel.c
new file mode 100644
index 0000000..b7a9363
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/h_cancel.c
@@ -0,0 +1,60 @@
+/* $NetBSD: h_cancel.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_cancel.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <unistd.h>
+
+int
+main(void)
+{
+ char str1[] = "You should see this.\n";
+ char str2[] = "You should not see this.\n";
+
+#ifdef __NetBSD__
+ printf("Cancellation test: Self-cancellation and disabling.\n");
+#endif
+
+ pthread_cancel(pthread_self());
+
+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
+ write(STDOUT_FILENO, str1, sizeof(str1)-1);
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+
+ write(STDOUT_FILENO, str2, sizeof(str2)-1);
+
+ exit(1);
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/h_common.h b/contrib/netbsd-tests/lib/libpthread/h_common.h
new file mode 100644
index 0000000..f4d03bc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/h_common.h
@@ -0,0 +1,12 @@
+#ifndef H_COMMON_H
+#define H_COMMON_H
+
+#include <string.h>
+
+#define PTHREAD_REQUIRE(x) \
+ do { \
+ int ret = (x); \
+ ATF_REQUIRE_MSG(ret == 0, "%s: %s", #x, strerror(ret)); \
+ } while (0)
+
+#endif // H_COMMON_H
diff --git a/contrib/netbsd-tests/lib/libpthread/h_exit.c b/contrib/netbsd-tests/lib/libpthread/h_exit.c
new file mode 100644
index 0000000..a37f88f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/h_exit.c
@@ -0,0 +1,47 @@
+/* $NetBSD: h_exit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_exit.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+int
+main(void)
+{
+ printf("Test of pthread_exit() in main thread only.\n");
+
+ pthread_exit(NULL);
+
+ printf("You shouldn't see this.");
+ exit(1);
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/h_resolv.c b/contrib/netbsd-tests/lib/libpthread/h_resolv.c
new file mode 100644
index 0000000..9c5fedc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/h_resolv.c
@@ -0,0 +1,208 @@
+/* $NetBSD: h_resolv.c,v 1.2 2010/11/03 16:10:22 christos Exp $ */
+
+/*-
+ * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_resolv.c,v 1.2 2010/11/03 16:10:22 christos Exp $");
+
+#include <pthread.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#include <string.h>
+#include <stringlist.h>
+
+#define NTHREADS 10
+#define NHOSTS 100
+#define WS " \t\n\r"
+
+static StringList *hosts = NULL;
+static int debug = 0;
+static int *ask = NULL;
+static int *got = NULL;
+
+static void usage(void) __attribute__((__noreturn__));
+static void load(const char *);
+static void resolvone(int);
+static void *resolvloop(void *);
+static void run(int *);
+
+static pthread_mutex_t stats = PTHREAD_MUTEX_INITIALIZER;
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr,
+ "Usage: %s [-d] [-h <nhosts>] [-n <nthreads>] <file> ...\n",
+ getprogname());
+ exit(1);
+}
+
+static void
+load(const char *fname)
+{
+ FILE *fp;
+ size_t len;
+ char *line;
+
+ if ((fp = fopen(fname, "r")) == NULL)
+ err(1, "Cannot open `%s'", fname);
+ while ((line = fgetln(fp, &len)) != NULL) {
+ char c = line[len];
+ char *ptr;
+ line[len] = '\0';
+ for (ptr = strtok(line, WS); ptr; ptr = strtok(NULL, WS))
+ sl_add(hosts, strdup(ptr));
+ line[len] = c;
+ }
+
+ (void)fclose(fp);
+}
+
+static void
+resolvone(int n)
+{
+ char buf[1024];
+ pthread_t self = pthread_self();
+ size_t i = (random() & 0x0fffffff) % hosts->sl_cur;
+ char *host = hosts->sl_str[i];
+ struct addrinfo *res;
+ int error, len;
+ if (debug) {
+ len = snprintf(buf, sizeof(buf), "%p: %d resolving %s %d\n",
+ self, n, host, (int)i);
+ (void)write(STDOUT_FILENO, buf, len);
+ }
+ error = getaddrinfo(host, NULL, NULL, &res);
+ if (debug) {
+ len = snprintf(buf, sizeof(buf), "%p: host %s %s\n",
+ self, host, error ? "not found" : "ok");
+ (void)write(STDOUT_FILENO, buf, len);
+ }
+ pthread_mutex_lock(&stats);
+ ask[i]++;
+ got[i] += error == 0;
+ pthread_mutex_unlock(&stats);
+ if (error == 0)
+ freeaddrinfo(res);
+}
+
+static void *
+resolvloop(void *p)
+{
+ int *nhosts = (int *)p;
+ if (*nhosts == 0)
+ return NULL;
+ do
+ resolvone(*nhosts);
+ while (--(*nhosts));
+ return NULL;
+}
+
+static void
+run(int *nhosts)
+{
+ pthread_t self = pthread_self();
+ if (pthread_create(&self, NULL, resolvloop, nhosts) != 0)
+ err(1, "pthread_create");
+}
+
+int
+main(int argc, char *argv[])
+{
+ int nthreads = NTHREADS;
+ int nhosts = NHOSTS;
+ int i, c, done, *nleft;
+ hosts = sl_init();
+
+ srandom(1234);
+
+ while ((c = getopt(argc, argv, "dh:n:")) != -1)
+ switch (c) {
+ case 'd':
+ debug++;
+ break;
+ case 'h':
+ nhosts = atoi(optarg);
+ break;
+ case 'n':
+ nthreads = atoi(optarg);
+ break;
+ default:
+ usage();
+ }
+
+ for (i = optind; i < argc; i++)
+ load(argv[i]);
+
+ if (hosts->sl_cur == 0)
+ usage();
+
+ if ((nleft = malloc(nthreads * sizeof(int))) == NULL)
+ err(1, "malloc");
+ if ((ask = calloc(hosts->sl_cur, sizeof(int))) == NULL)
+ err(1, "calloc");
+ if ((got = calloc(hosts->sl_cur, sizeof(int))) == NULL)
+ err(1, "calloc");
+
+
+ for (i = 0; i < nthreads; i++) {
+ nleft[i] = nhosts;
+ run(&nleft[i]);
+ }
+
+ for (done = 0; !done;) {
+ done = 1;
+ for (i = 0; i < nthreads; i++) {
+ if (nleft[i] != 0) {
+ done = 0;
+ break;
+ }
+ }
+ sleep(1);
+ }
+ c = 0;
+ for (i = 0; i < (int)hosts->sl_cur; i++) {
+ if (ask[i] != got[i] && got[i] != 0) {
+ warnx("Error: host %s ask %d got %d\n",
+ hosts->sl_str[i], ask[i], got[i]);
+ c++;
+ }
+ }
+ free(nleft);
+ free(ask);
+ free(got);
+ sl_free(hosts, 1);
+ return c;
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_atexit.sh b/contrib/netbsd-tests/lib/libpthread/t_atexit.sh
new file mode 100755
index 0000000..7b99618
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_atexit.sh
@@ -0,0 +1,49 @@
+# $NetBSD: t_atexit.sh,v 1.2 2010/11/07 17:51:20 jmmv Exp $
+#
+# 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.
+#
+
+atf_test_case atexit
+atexit_head()
+{
+ atf_set "descr" "Checks atexit functionality"
+}
+atexit_body()
+{
+ cat >expout <<EOF
+cxa_handler_5
+cxa_handler_4
+cxa_handler_3
+cxa_handler_2
+normal_handler_1
+normal_handler_0
+EOF
+ atf_check -o file:expout "$(atf_get_srcdir)/h_atexit"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case atexit
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_barrier.c b/contrib/netbsd-tests/lib/libpthread/t_barrier.c
new file mode 100644
index 0000000..a06cfd9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_barrier.c
@@ -0,0 +1,110 @@
+/* $NetBSD: t_barrier.c,v 1.2 2010/11/03 16:10:22 christos Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_barrier.c,v 1.2 2010/11/03 16:10:22 christos Exp $");
+
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+#define COUNT 5
+
+pthread_barrier_t barrier;
+pthread_mutex_t mutex;
+int serial_count;
+int after_barrier_count;
+
+static void *
+threadfunc(void *arg)
+{
+ int which = (int)(long)arg;
+ int rv;
+
+ printf("thread %d entering barrier\n", which);
+ rv = pthread_barrier_wait(&barrier);
+ printf("thread %d leaving barrier -> %d\n", which, rv);
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ after_barrier_count++;
+ if (rv == PTHREAD_BARRIER_SERIAL_THREAD)
+ serial_count++;
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+
+ return NULL;
+}
+
+ATF_TC(barrier);
+ATF_TC_HEAD(barrier, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks barriers");
+}
+ATF_TC_BODY(barrier, tc)
+{
+ int i;
+ pthread_t new[COUNT];
+ void *joinval;
+
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
+ PTHREAD_REQUIRE(pthread_barrier_init(&barrier, NULL, COUNT));
+
+ for (i = 0; i < COUNT; i++) {
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ ATF_REQUIRE_EQ(after_barrier_count, 0);
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ PTHREAD_REQUIRE(pthread_create(&new[i], NULL, threadfunc,
+ (void *)(long)i));
+ sleep(2);
+ }
+
+ for (i = 0; i < COUNT; i++) {
+ PTHREAD_REQUIRE(pthread_join(new[i], &joinval));
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ ATF_REQUIRE(after_barrier_count > i);
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ printf("main joined with thread %d\n", i);
+ }
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ ATF_REQUIRE_EQ(after_barrier_count, COUNT);
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ ATF_REQUIRE_EQ(serial_count, 1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, barrier);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_cancel.sh b/contrib/netbsd-tests/lib/libpthread/t_cancel.sh
new file mode 100755
index 0000000..4a0701e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_cancel.sh
@@ -0,0 +1,44 @@
+# $NetBSD: t_cancel.sh,v 1.1 2010/07/16 15:42:53 jmmv Exp $
+#
+# 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.
+#
+
+atf_test_case register_while_disabled
+register_while_disabled_head()
+{
+ atf_set "descr" "Checks that a cancellation registered while" \
+ "cancellation is enabled is not honored while cancellation is" \
+ "disabled"
+}
+register_while_disabled_body()
+{
+ atf_check -o inline:"You should see this.\n" \
+ "$(atf_get_srcdir)/h_cancel"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case register_while_disabled
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_cond.c b/contrib/netbsd-tests/lib/libpthread/t_cond.c
new file mode 100644
index 0000000..9f33c9e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_cond.c
@@ -0,0 +1,563 @@
+/* $NetBSD: t_cond.c,v 1.6 2014/09/03 16:23:24 gson Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_cond.c,v 1.6 2014/09/03 16:23:24 gson Exp $");
+
+#include <sys/time.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+static pthread_mutex_t mutex;
+static pthread_cond_t cond;
+static pthread_mutex_t static_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t static_cond = PTHREAD_COND_INITIALIZER;
+static int count, share, toggle, total;
+
+static void *
+signal_delay_wait_threadfunc(void *arg)
+{
+ int *shared = (int *) arg;
+
+ printf("2: Second thread.\n");
+
+ printf("2: Locking mutex\n");
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ printf("2: Got mutex.\n");
+ printf("Shared value: %d. Changing to 0.\n", *shared);
+ *shared = 0;
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ PTHREAD_REQUIRE(pthread_cond_signal(&cond));
+
+ return NULL;
+}
+
+ATF_TC(signal_delay_wait);
+ATF_TC_HEAD(signal_delay_wait, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks condition variables");
+}
+ATF_TC_BODY(signal_delay_wait, tc)
+{
+ pthread_t new;
+ void *joinval;
+ int sharedval;
+
+ printf("1: condition variable test 1\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
+ PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL));
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+
+ sharedval = 1;
+
+ PTHREAD_REQUIRE(pthread_create(&new, NULL, signal_delay_wait_threadfunc,
+ &sharedval));
+
+ printf("1: Before waiting.\n");
+ do {
+ sleep(2);
+ PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex));
+ printf("1: After waiting, in loop.\n");
+ } while (sharedval != 0);
+
+ printf("1: After the loop.\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+
+ printf("1: After releasing the mutex.\n");
+ PTHREAD_REQUIRE(pthread_join(new, &joinval));
+
+ printf("1: Thread joined.\n");
+}
+
+static void *
+signal_before_unlock_threadfunc(void *arg)
+{
+ int *shared = (int *) arg;
+
+ printf("2: Second thread.\n");
+
+ printf("2: Locking mutex\n");
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ printf("2: Got mutex.\n");
+ printf("Shared value: %d. Changing to 0.\n", *shared);
+ *shared = 0;
+
+ /* Signal first, then unlock, for a different test than #1. */
+ PTHREAD_REQUIRE(pthread_cond_signal(&cond));
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+
+ return NULL;
+}
+
+ATF_TC(signal_before_unlock);
+ATF_TC_HEAD(signal_before_unlock, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks condition variables: signal before unlocking mutex");
+}
+ATF_TC_BODY(signal_before_unlock, tc)
+{
+ pthread_t new;
+ void *joinval;
+ int sharedval;
+
+ printf("1: condition variable test 2\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
+ PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL));
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+
+ sharedval = 1;
+
+ PTHREAD_REQUIRE(pthread_create(&new, NULL,
+ signal_before_unlock_threadfunc, &sharedval));
+
+ printf("1: Before waiting.\n");
+ do {
+ sleep(2);
+ PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex));
+ printf("1: After waiting, in loop.\n");
+ } while (sharedval != 0);
+
+ printf("1: After the loop.\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+
+ printf("1: After releasing the mutex.\n");
+ PTHREAD_REQUIRE(pthread_join(new, &joinval));
+
+ printf("1: Thread joined.\n");
+}
+
+static void *
+signal_before_unlock_static_init_threadfunc(void *arg)
+{
+ int *shared = (int *) arg;
+
+ printf("2: Second thread.\n");
+
+ printf("2: Locking mutex\n");
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+ printf("2: Got mutex.\n");
+ printf("Shared value: %d. Changing to 0.\n", *shared);
+ *shared = 0;
+
+ /* Signal first, then unlock, for a different test than #1. */
+ PTHREAD_REQUIRE(pthread_cond_signal(&static_cond));
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
+
+ return NULL;
+}
+
+ATF_TC(signal_before_unlock_static_init);
+ATF_TC_HEAD(signal_before_unlock_static_init, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks condition variables: signal before unlocking "
+ "mutex, use static initializers");
+}
+ATF_TC_BODY(signal_before_unlock_static_init, tc)
+{
+ pthread_t new;
+ void *joinval;
+ int sharedval;
+
+ printf("1: condition variable test 3\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+
+ sharedval = 1;
+
+ PTHREAD_REQUIRE(pthread_create(&new, NULL,
+ signal_before_unlock_static_init_threadfunc, &sharedval));
+
+ printf("1: Before waiting.\n");
+ do {
+ sleep(2);
+ PTHREAD_REQUIRE(pthread_cond_wait(&static_cond, &static_mutex));
+ printf("1: After waiting, in loop.\n");
+ } while (sharedval != 0);
+
+ printf("1: After the loop.\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
+
+ printf("1: After releasing the mutex.\n");
+ PTHREAD_REQUIRE(pthread_join(new, &joinval));
+
+ printf("1: Thread joined.\n");
+}
+
+static void *
+signal_wait_race_threadfunc(void *arg)
+{
+ printf("2: Second thread.\n");
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+ printf("2: Before the loop.\n");
+ while (count>0) {
+ count--;
+ total++;
+ toggle = 0;
+ /* printf("2: Before signal %d.\n", count); */
+ PTHREAD_REQUIRE(pthread_cond_signal(&static_cond));
+ do {
+ PTHREAD_REQUIRE(pthread_cond_wait(&static_cond,
+ &static_mutex));
+ } while (toggle != 1);
+ }
+ printf("2: After the loop.\n");
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
+
+ return NULL;
+}
+
+ATF_TC(signal_wait_race);
+ATF_TC_HEAD(signal_wait_race, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks condition variables");
+}
+ATF_TC_BODY(signal_wait_race, tc)
+{
+ pthread_t new;
+ void *joinval;
+ int sharedval;
+
+ printf("1: condition variable test 4\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+
+ count = 50000;
+ toggle = 0;
+
+ PTHREAD_REQUIRE(pthread_create(&new, NULL, signal_wait_race_threadfunc,
+ &sharedval));
+
+ printf("1: Before waiting.\n");
+ while (count>0) {
+ count--;
+ total++;
+ toggle = 1;
+ /* printf("1: Before signal %d.\n", count); */
+ PTHREAD_REQUIRE(pthread_cond_signal(&static_cond));
+ do {
+ PTHREAD_REQUIRE(pthread_cond_wait(&static_cond,
+ &static_mutex));
+ } while (toggle != 0);
+ }
+ printf("1: After the loop.\n");
+
+ toggle = 1;
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
+ PTHREAD_REQUIRE(pthread_cond_signal(&static_cond));
+
+ printf("1: After releasing the mutex.\n");
+ PTHREAD_REQUIRE(pthread_join(new, &joinval));
+
+ printf("1: Thread joined. Final count = %d, total = %d\n",
+ count, total);
+
+ ATF_REQUIRE_EQ(count, 0);
+ ATF_REQUIRE_EQ(total, 50000);
+}
+
+static void *
+pthread_cond_timedwait_func(void *arg)
+{
+ struct timespec ts;
+ size_t i = 0;
+ int rv;
+
+ for (;;) {
+
+ if (i++ >= 10000)
+ pthread_exit(NULL);
+
+ (void)memset(&ts, 0, sizeof(struct timespec));
+
+ ATF_REQUIRE(clock_gettime(CLOCK_REALTIME, &ts) == 0);
+
+ /*
+ * Set to one second in the past:
+ * pthread_cond_timedwait(3) should
+ * return ETIMEDOUT immediately.
+ */
+ ts.tv_sec = ts.tv_sec - 1;
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+ rv = pthread_cond_timedwait(&static_cond, &static_mutex, &ts);
+
+ /*
+ * Sometimes we catch ESRCH.
+ * This should never happen.
+ */
+ ATF_REQUIRE(rv == ETIMEDOUT);
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
+ }
+}
+
+ATF_TC(cond_timedwait_race);
+ATF_TC_HEAD(cond_timedwait_race, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pthread_cond_timedwait(3)");
+
+}
+ATF_TC_BODY(cond_timedwait_race, tc)
+{
+ pthread_t tid[64];
+ size_t i;
+
+ for (i = 0; i < __arraycount(tid); i++) {
+
+ PTHREAD_REQUIRE(pthread_create(&tid[i], NULL,
+ pthread_cond_timedwait_func, NULL));
+ }
+
+ for (i = 0; i < __arraycount(tid); i++) {
+
+ PTHREAD_REQUIRE(pthread_join(tid[i], NULL));
+ }
+}
+
+static void *
+broadcast_threadfunc(void *arg)
+{
+ printf("2: Second thread.\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+ while (count>0) {
+ count--;
+ total++;
+ toggle = 0;
+ PTHREAD_REQUIRE(pthread_cond_signal(&static_cond));
+ do {
+ PTHREAD_REQUIRE(pthread_cond_wait(&static_cond,
+ &static_mutex));
+ } while (toggle != 1);
+ }
+ printf("2: After the loop.\n");
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
+
+ return NULL;
+}
+
+
+ATF_TC(broadcast);
+ATF_TC_HEAD(broadcast, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks condition variables: use pthread_cond_broadcast()");
+}
+ATF_TC_BODY(broadcast, tc)
+{
+ pthread_t new;
+ void *joinval;
+ int sharedval;
+
+ printf("1: condition variable test 5\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+
+ count = 50000;
+ toggle = 0;
+
+ PTHREAD_REQUIRE(pthread_create(&new, NULL, broadcast_threadfunc,
+ &sharedval));
+
+ printf("1: Before waiting.\n");
+ while (count>0) {
+ count--;
+ total++;
+ toggle = 1;
+ PTHREAD_REQUIRE(pthread_cond_broadcast(&static_cond));
+ do {
+ PTHREAD_REQUIRE(pthread_cond_wait(&static_cond,
+ &static_mutex));
+ } while (toggle != 0);
+ }
+ printf("1: After the loop.\n");
+
+ toggle = 1;
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
+ PTHREAD_REQUIRE(pthread_cond_signal(&static_cond));
+
+ printf("1: After releasing the mutex.\n");
+ PTHREAD_REQUIRE(pthread_join(new, &joinval));
+
+ printf("1: Thread joined. Final count = %d, total = %d\n", count,
+ total);
+
+ ATF_REQUIRE_EQ(count, 0);
+ ATF_REQUIRE_EQ(total, 50000);
+}
+
+static void *
+bogus_timedwaits_threadfunc(void *arg)
+{
+ return NULL;
+}
+
+ATF_TC(bogus_timedwaits);
+ATF_TC_HEAD(bogus_timedwaits, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks condition variables: bogus timedwaits");
+}
+ATF_TC_BODY(bogus_timedwaits, tc)
+{
+ pthread_t new;
+ struct timespec ts;
+ struct timeval tv;
+
+ printf("condition variable test 6: bogus timedwaits\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+
+ printf("unthreaded test (past)\n");
+ gettimeofday(&tv, NULL);
+ tv.tv_sec -= 2; /* Place the time in the past */
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+
+ ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex,
+ &ts), ETIMEDOUT, "pthread_cond_timedwait() (unthreaded) in the "
+ "past");
+
+ printf("unthreaded test (zero time)\n");
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+
+ ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex,
+ &ts), ETIMEDOUT, "pthread_cond_timedwait() (unthreaded) with zero "
+ "time");
+
+ PTHREAD_REQUIRE(pthread_create(&new, NULL, bogus_timedwaits_threadfunc,
+ NULL));
+ PTHREAD_REQUIRE(pthread_join(new, NULL));
+
+ printf("threaded test\n");
+ gettimeofday(&tv, NULL);
+ tv.tv_sec -= 2; /* Place the time in the past */
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+
+ ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex,
+ &ts), ETIMEDOUT, "pthread_cond_timedwait() (threaded) in the past");
+
+ printf("threaded test (zero time)\n");
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ TIMEVAL_TO_TIMESPEC(&tv, &ts);
+
+ ATF_REQUIRE_EQ_MSG(pthread_cond_timedwait(&static_cond, &static_mutex,
+ &ts), ETIMEDOUT, "pthread_cond_timedwait() (threaded) with zero "
+ "time");
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
+}
+
+static void
+unlock(void *arg)
+{
+ pthread_mutex_unlock((pthread_mutex_t *)arg);
+}
+
+static void *
+destroy_after_cancel_threadfunc(void *arg)
+{
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+
+ pthread_cleanup_push(unlock, &mutex);
+
+ while (1) {
+ share = 1;
+ PTHREAD_REQUIRE(pthread_cond_broadcast(&cond));
+ PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex));
+ }
+
+ pthread_cleanup_pop(0);
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+
+ return NULL;
+}
+
+ATF_TC(destroy_after_cancel);
+ATF_TC_HEAD(destroy_after_cancel, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks destroying a condition variable "
+ "after cancelling a wait");
+}
+ATF_TC_BODY(destroy_after_cancel, tc)
+{
+ pthread_t thread;
+
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
+ PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL));
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ PTHREAD_REQUIRE(pthread_create(&thread, NULL,
+ destroy_after_cancel_threadfunc, NULL));
+
+ while (share == 0) {
+ PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex));
+ }
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ PTHREAD_REQUIRE(pthread_cancel(thread));
+
+ PTHREAD_REQUIRE(pthread_join(thread, NULL));
+ PTHREAD_REQUIRE(pthread_cond_destroy(&cond));
+
+ PTHREAD_REQUIRE(pthread_mutex_destroy(&mutex));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, signal_delay_wait);
+ ATF_TP_ADD_TC(tp, signal_before_unlock);
+ ATF_TP_ADD_TC(tp, signal_before_unlock_static_init);
+ ATF_TP_ADD_TC(tp, signal_wait_race);
+ ATF_TP_ADD_TC(tp, cond_timedwait_race);
+ ATF_TP_ADD_TC(tp, broadcast);
+ ATF_TP_ADD_TC(tp, bogus_timedwaits);
+ ATF_TP_ADD_TC(tp, destroy_after_cancel);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_condwait.c b/contrib/netbsd-tests/lib/libpthread/t_condwait.c
new file mode 100644
index 0000000..17bbb89
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_condwait.c
@@ -0,0 +1,146 @@
+/* $NetBSD: t_condwait.c,v 1.4 2013/04/12 17:18:11 christos Exp $ */
+
+/*
+ * Copyright (c) 2013 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/cdefs.h>
+__RCSID("$NetBSD: t_condwait.c,v 1.4 2013/04/12 17:18:11 christos Exp $");
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "isqemu.h"
+
+#ifdef __FreeBSD__
+#include <sys/time.h>
+#endif
+
+#define WAITTIME 2 /* Timeout wait secound */
+
+static const int debug = 1;
+
+static void *
+run(void *param)
+{
+ struct timespec ts, to, te;
+ clockid_t clck;
+ pthread_condattr_t attr;
+ pthread_cond_t cond;
+ pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
+ int ret = 0;
+
+
+ clck = *(clockid_t *)param;
+ pthread_condattr_init(&attr);
+ pthread_condattr_setclock(&attr, clck); /* MONOTONIC or MONOTONIC */
+ pthread_cond_init(&cond, &attr);
+
+ ATF_REQUIRE_EQ((ret = pthread_mutex_lock(&m)), 0);
+
+ ATF_REQUIRE_EQ(clock_gettime(clck, &ts), 0);
+ to = ts;
+
+ if (debug)
+ printf("started: %lld.%09ld sec\n", (long long)to.tv_sec,
+ to.tv_nsec);
+
+ ts.tv_sec += WAITTIME; /* Timeout wait */
+
+ switch (ret = pthread_cond_timedwait(&cond, &m, &ts)) {
+ case ETIMEDOUT:
+ /* Timeout */
+ ATF_REQUIRE_EQ(clock_gettime(clck, &te), 0);
+ timespecsub(&te, &to, &to);
+ if (debug) {
+ printf("timeout: %lld.%09ld sec\n",
+ (long long)te.tv_sec, te.tv_nsec);
+ printf("elapsed: %lld.%09ld sec\n",
+ (long long)to.tv_sec, to.tv_nsec);
+ }
+ if (isQEMU()) {
+ double to_seconds = to.tv_sec + 1e-9 * to.tv_nsec;
+ ATF_REQUIRE(to_seconds >= WAITTIME * 0.9);
+ /* Loose upper limit because of qemu timing bugs */
+ ATF_REQUIRE(to_seconds < WAITTIME * 2.5);
+ } else {
+ ATF_REQUIRE_EQ(to.tv_sec, WAITTIME);
+ }
+ break;
+ default:
+ ATF_REQUIRE_MSG(0, "pthread_cond_timedwait: %s", strerror(ret));
+ }
+
+ ATF_REQUIRE_MSG(!(ret = pthread_mutex_unlock(&m)),
+ "pthread_mutex_unlock: %s", strerror(ret));
+ pthread_exit(&ret);
+}
+
+static void
+cond_wait(clockid_t clck, const char *msg) {
+ pthread_t child;
+
+ if (debug)
+ printf( "**** %s clock wait starting\n", msg);
+ ATF_REQUIRE_EQ(pthread_create(&child, NULL, run, &clck), 0);
+ ATF_REQUIRE_EQ(pthread_join(child, NULL), 0); /* wait for terminate */
+ if (debug)
+ printf( "**** %s clock wait ended\n", msg);
+}
+
+ATF_TC(cond_wait_real);
+ATF_TC_HEAD(cond_wait_real, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks pthread_cond_timedwait "
+ "with CLOCK_REALTIME");
+}
+
+ATF_TC_BODY(cond_wait_real, tc) {
+ cond_wait(CLOCK_REALTIME, "CLOCK_REALTIME");
+}
+
+ATF_TC(cond_wait_mono);
+ATF_TC_HEAD(cond_wait_mono, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks pthread_cond_timedwait "
+ "with CLOCK_MONOTONIC");
+}
+
+ATF_TC_BODY(cond_wait_mono, tc) {
+ cond_wait(CLOCK_MONOTONIC, "CLOCK_MONOTONIC");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, cond_wait_real);
+ ATF_TP_ADD_TC(tp, cond_wait_mono);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_detach.c b/contrib/netbsd-tests/lib/libpthread/t_detach.c
new file mode 100644
index 0000000..8922d5a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_detach.c
@@ -0,0 +1,95 @@
+/* $NetBSD: t_detach.c,v 1.1 2011/03/24 13:52:04 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_detach.c,v 1.1 2011/03/24 13:52:04 jruoho Exp $");
+
+#include <pthread.h>
+#include <errno.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+static void *func(void *);
+
+static void *
+func(void *arg)
+{
+ return NULL;
+}
+
+ATF_TC(pthread_detach);
+ATF_TC_HEAD(pthread_detach, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A test of pthread_detach(3)");
+}
+
+ATF_TC_BODY(pthread_detach, tc)
+{
+ const int state = PTHREAD_CREATE_JOINABLE;
+ pthread_attr_t attr;
+ pthread_t t;
+ int rv;
+
+ /*
+ * Create a joinable thread.
+ */
+ PTHREAD_REQUIRE(pthread_attr_init(&attr));
+ PTHREAD_REQUIRE(pthread_attr_setdetachstate(&attr, state));
+ PTHREAD_REQUIRE(pthread_create(&t, &attr, func, NULL));
+
+ /*
+ * Detach the thread and try to
+ * join it; EINVAL should follow.
+ */
+ PTHREAD_REQUIRE(pthread_detach(t));
+
+ rv = pthread_join(t, NULL);
+ ATF_REQUIRE(rv == EINVAL);
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("PR # 191906: fails with EINVAL, not ESRCH");
+#endif
+
+ /*
+ * As usual, ESRCH should follow if
+ * we try to detach an invalid thread.
+ */
+ rv = pthread_cancel(NULL);
+ ATF_REQUIRE(rv == ESRCH);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, pthread_detach);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_equal.c b/contrib/netbsd-tests/lib/libpthread/t_equal.c
new file mode 100644
index 0000000..bcda996
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_equal.c
@@ -0,0 +1,74 @@
+/* $NetBSD: t_equal.c,v 1.1 2011/03/24 12:40:59 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_equal.c,v 1.1 2011/03/24 12:40:59 jruoho Exp $");
+
+#include <pthread.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+static void *func(void *);
+
+static void *
+func(void *arg)
+{
+ return NULL;
+}
+
+ATF_TC(pthread_equal);
+ATF_TC_HEAD(pthread_equal, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A test of pthread_equal(3)");
+}
+
+ATF_TC_BODY(pthread_equal, tc)
+{
+ pthread_t t1, t2;
+
+ ATF_REQUIRE(pthread_create(&t1, NULL, func, NULL) == 0);
+ ATF_REQUIRE(pthread_create(&t2, NULL, func, NULL) == 0);
+
+ ATF_REQUIRE(pthread_equal(t1, t1) != 0);
+ ATF_REQUIRE(pthread_equal(t2, t2) != 0);
+ ATF_REQUIRE(pthread_equal(t1, t2) == 0);
+
+ ATF_REQUIRE(pthread_join(t1, NULL) == 0);
+ ATF_REQUIRE(pthread_join(t2, NULL) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, pthread_equal);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_exit.sh b/contrib/netbsd-tests/lib/libpthread/t_exit.sh
new file mode 100755
index 0000000..7fbd689
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_exit.sh
@@ -0,0 +1,41 @@
+# $NetBSD: t_exit.sh,v 1.1 2010/07/16 15:42:53 jmmv Exp $
+#
+# 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.
+#
+
+atf_test_case main_thread
+main_thread_head()
+{
+ atf_set "descr" "Checks calling pthread_exit() in the main thread"
+}
+main_thread_body()
+{
+ atf_check -o ignore "$(atf_get_srcdir)/h_exit"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case main_thread
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_fork.c b/contrib/netbsd-tests/lib/libpthread/t_fork.c
new file mode 100644
index 0000000..a58c1a6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_fork.c
@@ -0,0 +1,115 @@
+/* $NetBSD: t_fork.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_fork.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+/*
+ * Written by Love Hörnquist Åstrand <lha@NetBSD.org>, March 2003.
+ * Public domain.
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+static pid_t parent;
+static int thread_survived = 0;
+
+static void *
+print_pid(void *arg)
+{
+ sleep(3);
+
+ thread_survived = 1;
+ if (parent != getpid()) {
+#ifdef __FreeBSD__
+ _exit(1);
+#else
+ exit(1);
+#endif
+ }
+ return NULL;
+}
+
+ATF_TC(fork);
+ATF_TC_HEAD(fork, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that child process doesn't get threads");
+}
+ATF_TC_BODY(fork, tc)
+{
+ pthread_t p;
+ pid_t fork_pid;
+
+ parent = getpid();
+
+ PTHREAD_REQUIRE(pthread_create(&p, NULL, print_pid, NULL));
+
+ fork_pid = fork();
+ ATF_REQUIRE(fork_pid != -1);
+
+ if (fork_pid) {
+ int status;
+
+ PTHREAD_REQUIRE(pthread_join(p, NULL));
+ ATF_REQUIRE_MSG(thread_survived, "thread did not survive in parent");
+
+ waitpid(fork_pid, &status, 0);
+ ATF_REQUIRE_MSG(WIFEXITED(status), "child died wrongly");
+ ATF_REQUIRE_EQ_MSG(WEXITSTATUS(status), 0, "thread survived in child");
+ } else {
+ sleep(5);
+#ifdef __FreeBSD__
+ _exit(thread_survived ? 1 : 0);
+#else
+ exit(thread_survived ? 1 : 0);
+#endif
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, fork);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_fpu.c b/contrib/netbsd-tests/lib/libpthread/t_fpu.c
new file mode 100644
index 0000000..4047b1f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_fpu.c
@@ -0,0 +1,148 @@
+/* $NetBSD: t_fpu.c,v 1.2 2013/01/27 14:47:37 mbalmer Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_fpu.c,v 1.2 2013/01/27 14:47:37 mbalmer Exp $");
+
+/*
+ * This is adapted from part of csw/cstest of the MPD implementation by
+ * the University of Arizona CS department (http://www.cs.arizona.edu/sr/)
+ * which is in the public domain:
+ *
+ * "The MPD system is in the public domain and you may use and distribute it
+ * as you wish. We ask that you retain credits referencing the University
+ * of Arizona and that you identify any changes you make.
+ *
+ * We can't provide a warranty with MPD; it's up to you to determine its
+ * suitability and reliability for your needs. We would like to hear of
+ * any problems you encounter but we cannot promise a timely correction."
+ *
+ * It was changed to use pthread_create() and sched_yield() instead of
+ * the internal MPD context switching primitives by Ignatios Souvatzis
+ * <is@netbsd.org>.
+ */
+
+#include <math.h>
+#include <pthread.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+#define N_RECURSE 10
+
+static void recurse(void);
+
+int recursion_depth = 0;
+pthread_mutex_t recursion_depth_lock;
+
+static void *
+stir(void *p)
+{
+ double *q = (double *)p;
+ double x = *q++;
+ double y = *q++;
+ double z = *q++;
+
+ for (;;) {
+ x = sin ((y = cos (x + y + .4)) - (z = cos (x + z + .6)));
+ PTHREAD_REQUIRE(sched_yield());
+ }
+}
+
+static double
+mul3(double x, double y, double z)
+{
+ PTHREAD_REQUIRE(sched_yield());
+
+ return x * y * z;
+}
+
+static void *
+bar(void *p)
+{
+ double d;
+ int rc;
+
+ d = mul3(mul3(2., 3., 5.), mul3(7., 11., 13.), mul3(17., 19., 23.));
+ ATF_REQUIRE_EQ(d, 223092870.);
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&recursion_depth_lock));
+ rc = recursion_depth++;
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&recursion_depth_lock));
+
+ if (rc < N_RECURSE)
+ recurse();
+ else
+ atf_tc_pass();
+
+ /* NOTREACHED */
+ return NULL;
+}
+
+static void
+recurse(void) {
+ pthread_t s2;
+ pthread_create(&s2, 0, bar, 0);
+ sleep(20); /* XXX must be long enough for our slowest machine */
+}
+
+ATF_TC(fpu);
+ATF_TC_HEAD(fpu, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that thread context switches will leave the "
+ "floating point computations unharmed");
+}
+ATF_TC_BODY(fpu, tc)
+{
+ double stirseed[] = { 1.7, 3.2, 2.4 };
+ pthread_t s5;
+
+ printf("Testing threaded floating point computations...\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_init(&recursion_depth_lock, 0));
+
+ pthread_create(&s5, 0, stir, stirseed);
+ recurse();
+
+ atf_tc_fail("exiting from main");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, fpu);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_join.c b/contrib/netbsd-tests/lib/libpthread/t_join.c
new file mode 100644
index 0000000..71b6775
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_join.c
@@ -0,0 +1,181 @@
+/* $NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $");
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdint.h>
+
+#include <atf-c.h>
+
+#ifdef __FreeBSD__
+#include <pthread_np.h>
+#endif
+
+#include "h_common.h"
+
+#ifdef CHECK_STACK_ALIGNMENT
+extern int check_stack_alignment(void);
+#endif
+
+#define STACKSIZE 65536
+
+static bool error;
+
+static void *threadfunc1(void *);
+static void *threadfunc2(void *);
+
+ATF_TC(pthread_join);
+ATF_TC_HEAD(pthread_join, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks basic error conditions in pthread_join(3)");
+}
+
+ATF_TC_BODY(pthread_join, tc)
+{
+ pthread_t thread;
+
+ PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc1, NULL));
+ PTHREAD_REQUIRE(pthread_join(thread, NULL));
+}
+
+static void *
+threadfunc1(void *arg)
+{
+ pthread_t thread[25];
+ pthread_t caller;
+ void *val = NULL;
+ uintptr_t i;
+ int rv;
+ pthread_attr_t attr;
+
+ caller = pthread_self();
+
+#ifdef CHECK_STACK_ALIGNMENT
+ /*
+ * Check alignment of thread stack, if supported.
+ */
+ ATF_REQUIRE(check_stack_alignment());
+#endif
+
+ /*
+ * The behavior is undefined, but should error
+ * out, if we try to join the calling thread.
+ */
+ rv = pthread_join(caller, NULL);
+
+ /*
+ * The specification recommends EDEADLK.
+ */
+ ATF_REQUIRE(rv != 0);
+ ATF_REQUIRE_EQ(rv, EDEADLK);
+
+ ATF_REQUIRE(pthread_attr_init(&attr) == 0);
+
+ for (i = 0; i < __arraycount(thread); i++) {
+
+ error = true;
+
+ ATF_REQUIRE(pthread_attr_setstacksize(&attr, STACKSIZE * (i + 1)) == 0);
+
+ rv = pthread_create(&thread[i], &attr, threadfunc2, (void *)i);
+
+ ATF_REQUIRE_EQ(rv, 0);
+
+ /*
+ * Check join and exit condition.
+ */
+ PTHREAD_REQUIRE(pthread_join(thread[i], &val));
+
+ ATF_REQUIRE_EQ(error, false);
+
+ ATF_REQUIRE(val != NULL);
+ ATF_REQUIRE(val == (void *)(i + 1));
+
+ /*
+ * Once the thread has returned, ESRCH should
+ * again follow if we try to join it again.
+ */
+ rv = pthread_join(thread[i], NULL);
+
+ ATF_REQUIRE_EQ(rv, ESRCH);
+
+ /*
+ * Try to detach the exited thread.
+ */
+ rv = pthread_detach(thread[i]);
+
+ ATF_REQUIRE(rv != 0);
+ }
+
+ ATF_REQUIRE(pthread_attr_destroy(&attr) == 0);
+
+ pthread_exit(NULL);
+
+ return NULL;
+}
+
+static void *
+threadfunc2(void *arg)
+{
+ static uintptr_t i = 0;
+ uintptr_t j;
+ pthread_attr_t attr;
+ size_t stacksize;
+
+ j = (uintptr_t)arg;
+
+#ifdef __FreeBSD__
+ pthread_attr_init(&attr);
+#endif
+ ATF_REQUIRE(pthread_attr_get_np(pthread_self(), &attr) == 0);
+ ATF_REQUIRE(pthread_attr_getstacksize(&attr, &stacksize) == 0);
+ ATF_REQUIRE(stacksize == STACKSIZE * (j + 1));
+ ATF_REQUIRE(pthread_attr_destroy(&attr) == 0);
+
+ if (i++ == j)
+ error = false;
+
+ pthread_exit((void *)i);
+
+ return NULL;
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, pthread_join);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_kill.c b/contrib/netbsd-tests/lib/libpthread/t_kill.c
new file mode 100644
index 0000000..2fcdd99
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_kill.c
@@ -0,0 +1,147 @@
+/* $NetBSD: t_kill.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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.
+ */
+
+/*-
+ * Copyright (c)2004 YAMAMOTO Takashi,
+ * 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 AUTHOR 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 AUTHOR 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_kill.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+#include <pthread.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+#define NTHREAD 2
+
+struct threadinfo {
+ pthread_t id;
+ sig_atomic_t gotsignal;
+} th[NTHREAD];
+
+pthread_t mainthread;
+
+static void
+sighandler(int signo)
+{
+ pthread_t self;
+ int i;
+
+ self = pthread_self();
+ ATF_REQUIRE_MSG((self != mainthread) && (signo == SIGUSR1),
+ "unexpected signal");
+
+ for (i = 0; i < NTHREAD; i++)
+ if (self == th[i].id)
+ break;
+
+ ATF_REQUIRE_MSG(i != NTHREAD, "unknown thread");
+
+ th[i].gotsignal++;
+}
+
+static void *
+f(void *arg)
+{
+ struct threadinfo volatile *t = arg;
+
+ while (t->gotsignal < 1) {
+ /* busy loop */
+ }
+
+ return NULL;
+}
+
+ATF_TC(simple);
+ATF_TC_HEAD(simple, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks pthread_kill()");
+}
+ATF_TC_BODY(simple, tc)
+{
+ int i;
+ pthread_t self;
+
+ mainthread = pthread_self();
+
+ ATF_REQUIRE(signal(SIGUSR1, sighandler) != SIG_ERR);
+
+ for (i = 0; i < NTHREAD; i++) {
+ PTHREAD_REQUIRE(pthread_create(&th[i].id, NULL, f, &th[i]));
+ }
+
+ sched_yield();
+
+ self = pthread_self();
+ ATF_REQUIRE_EQ_MSG(self, mainthread, "thread id changed");
+
+ for (i = 0; i < NTHREAD; i++) {
+ PTHREAD_REQUIRE(pthread_kill(th[i].id, SIGUSR1));
+ }
+
+ for (i = 0; i < NTHREAD; i++) {
+ PTHREAD_REQUIRE(pthread_join(th[i].id, NULL));
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, simple);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_mutex.c b/contrib/netbsd-tests/lib/libpthread/t_mutex.c
new file mode 100644
index 0000000..eb371fa
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_mutex.c
@@ -0,0 +1,327 @@
+/* $NetBSD: t_mutex.c,v 1.7 2014/11/04 00:20:19 justin Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_mutex.c,v 1.7 2014/11/04 00:20:19 justin Exp $");
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+static pthread_mutex_t mutex;
+static pthread_mutex_t static_mutex = PTHREAD_MUTEX_INITIALIZER;
+static int global_x;
+
+static void *
+mutex1_threadfunc(void *arg)
+{
+ int *param;
+
+ printf("2: Second thread.\n");
+
+ param = arg;
+ printf("2: Locking mutex\n");
+ pthread_mutex_lock(&mutex);
+ printf("2: Got mutex. *param = %d\n", *param);
+ ATF_REQUIRE_EQ(*param, 20);
+ (*param)++;
+
+ pthread_mutex_unlock(&mutex);
+
+ return param;
+}
+
+ATF_TC(mutex1);
+ATF_TC_HEAD(mutex1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks mutexes");
+}
+ATF_TC_BODY(mutex1, tc)
+{
+ int x;
+ pthread_t new;
+ void *joinval;
+
+ printf("1: Mutex-test 1\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
+ x = 1;
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex1_threadfunc, &x));
+ printf("1: Before changing the value.\n");
+ sleep(2);
+ x = 20;
+ printf("1: Before releasing the mutex.\n");
+ sleep(2);
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ printf("1: After releasing the mutex.\n");
+ PTHREAD_REQUIRE(pthread_join(new, &joinval));
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ printf("1: Thread joined. X was %d. Return value (int) was %d\n",
+ x, *(int *)joinval);
+ ATF_REQUIRE_EQ(x, 21);
+ ATF_REQUIRE_EQ(*(int *)joinval, 21);
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+}
+
+static void *
+mutex2_threadfunc(void *arg)
+{
+ long count = *(int *)arg;
+
+ printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count);
+
+ while (count--) {
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ global_x++;
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ }
+
+ return (void *)count;
+}
+
+ATF_TC(mutex2);
+ATF_TC_HEAD(mutex2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks mutexes");
+#ifdef __NetBSD__
+#if defined(__powerpc__)
+ atf_tc_set_md_var(tc, "timeout", "40");
+#endif
+#endif
+}
+ATF_TC_BODY(mutex2, tc)
+{
+ int count, count2;
+ pthread_t new;
+ void *joinval;
+
+ printf("1: Mutex-test 2\n");
+
+#ifdef __NetBSD__
+#if defined(__powerpc__)
+ atf_tc_expect_timeout("PR port-powerpc/44387");
+#endif
+#endif
+
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
+
+ global_x = 0;
+ count = count2 = 10000000;
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex2_threadfunc, &count2));
+
+ printf("1: Thread %p\n", pthread_self());
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+
+ while (count--) {
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ global_x++;
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ }
+
+ PTHREAD_REQUIRE(pthread_join(new, &joinval));
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ printf("1: Thread joined. X was %d. Return value (long) was %ld\n",
+ global_x, (long)joinval);
+ ATF_REQUIRE_EQ(global_x, 20000000);
+
+#ifdef __NetBSD__
+#if defined(__powerpc__)
+ /* XXX force a timeout in ppc case since an un-triggered race
+ otherwise looks like a "failure" */
+ /* We sleep for longer than the timeout to make ATF not
+ complain about unexpected success */
+ sleep(41);
+#endif
+#endif
+}
+
+static void *
+mutex3_threadfunc(void *arg)
+{
+ long count = *(int *)arg;
+
+ printf("2: Second thread (%p). Count is %ld\n", pthread_self(), count);
+
+ while (count--) {
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+ global_x++;
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
+ }
+
+ return (void *)count;
+}
+
+ATF_TC(mutex3);
+ATF_TC_HEAD(mutex3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks mutexes using a static "
+ "initializer");
+#ifdef __NetBSD__
+#if defined(__powerpc__)
+ atf_tc_set_md_var(tc, "timeout", "40");
+#endif
+#endif
+}
+ATF_TC_BODY(mutex3, tc)
+{
+ int count, count2;
+ pthread_t new;
+ void *joinval;
+
+ printf("1: Mutex-test 3\n");
+
+#ifdef __NetBSD__
+#if defined(__powerpc__)
+ atf_tc_expect_timeout("PR port-powerpc/44387");
+#endif
+#endif
+
+ global_x = 0;
+ count = count2 = 10000000;
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+ PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex3_threadfunc, &count2));
+
+ printf("1: Thread %p\n", pthread_self());
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
+
+ while (count--) {
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+ global_x++;
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&static_mutex));
+ }
+
+ PTHREAD_REQUIRE(pthread_join(new, &joinval));
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&static_mutex));
+ printf("1: Thread joined. X was %d. Return value (long) was %ld\n",
+ global_x, (long)joinval);
+ ATF_REQUIRE_EQ(global_x, 20000000);
+
+#ifdef __NetBSD__
+#if defined(__powerpc__)
+ /* XXX force a timeout in ppc case since an un-triggered race
+ otherwise looks like a "failure" */
+ /* We sleep for longer than the timeout to make ATF not
+ complain about unexpected success */
+ sleep(41);
+#endif
+#endif
+}
+
+static void *
+mutex4_threadfunc(void *arg)
+{
+ int *param;
+
+ printf("2: Second thread.\n");
+
+ param = arg;
+ printf("2: Locking mutex\n");
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ printf("2: Got mutex. *param = %d\n", *param);
+ (*param)++;
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+
+ return param;
+}
+
+ATF_TC(mutex4);
+ATF_TC_HEAD(mutex4, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks mutexes");
+}
+ATF_TC_BODY(mutex4, tc)
+{
+ int x;
+ pthread_t new;
+ pthread_mutexattr_t mattr;
+ void *joinval;
+
+ printf("1: Mutex-test 4\n");
+
+ PTHREAD_REQUIRE(pthread_mutexattr_init(&mattr));
+ PTHREAD_REQUIRE(pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE));
+
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex, &mattr));
+
+ PTHREAD_REQUIRE(pthread_mutexattr_destroy(&mattr));
+
+ x = 1;
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ PTHREAD_REQUIRE(pthread_create(&new, NULL, mutex4_threadfunc, &x));
+
+ printf("1: Before recursively acquiring the mutex.\n");
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+
+ printf("1: Before releasing the mutex once.\n");
+ sleep(2);
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ printf("1: After releasing the mutex once.\n");
+
+ x = 20;
+
+ printf("1: Before releasing the mutex twice.\n");
+ sleep(2);
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ printf("1: After releasing the mutex twice.\n");
+
+ PTHREAD_REQUIRE(pthread_join(new, &joinval));
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ printf("1: Thread joined. X was %d. Return value (int) was %d\n",
+ x, *(int *)joinval);
+ ATF_REQUIRE_EQ(x, 21);
+ ATF_REQUIRE_EQ(*(int *)joinval, 21);
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, mutex1);
+ ATF_TP_ADD_TC(tp, mutex2);
+ ATF_TP_ADD_TC(tp, mutex3);
+ ATF_TP_ADD_TC(tp, mutex4);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_name.c b/contrib/netbsd-tests/lib/libpthread/t_name.c
new file mode 100644
index 0000000..d17895e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_name.c
@@ -0,0 +1,103 @@
+/* $NetBSD: t_name.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_name.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+#define NAME_TOO_LONG "12345678901234567890123456789012" /* 32 chars */
+#define NAME_JUST_RIGHT "1234567890123456789012345678901" /* 31 chars */
+
+#define CONST_NAME "xyzzy"
+char non_const_name[] = CONST_NAME;
+
+static void *
+threadfunc(void *arg)
+{
+ pthread_t self = pthread_self();
+ char retname[32];
+
+ PTHREAD_REQUIRE(pthread_getname_np(self, retname, sizeof(retname)));
+ ATF_REQUIRE_STREQ(retname, NAME_JUST_RIGHT);
+
+ PTHREAD_REQUIRE(pthread_setname_np(self, non_const_name, NULL));
+ (void) memset(non_const_name, 0, sizeof(non_const_name));
+ PTHREAD_REQUIRE(pthread_getname_np(self, retname, sizeof(retname)));
+ ATF_REQUIRE_STREQ(retname, CONST_NAME);
+
+ return NULL;
+}
+
+ATF_TC(name);
+ATF_TC_HEAD(name, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks pthread_{,attr}_{get,set}name_np() API");
+}
+ATF_TC_BODY(name, tc)
+{
+ pthread_t thr, self = pthread_self();
+ pthread_attr_t attr;
+ char retname[32];
+
+ PTHREAD_REQUIRE(pthread_attr_init(&attr));
+ PTHREAD_REQUIRE(pthread_attr_getname_np(&attr, retname,
+ sizeof(retname), NULL));
+ ATF_REQUIRE_EQ(retname[0], '\0');
+ ATF_REQUIRE_EQ(pthread_attr_setname_np(&attr, NAME_TOO_LONG, NULL), EINVAL);
+ PTHREAD_REQUIRE(pthread_attr_setname_np(&attr, "%s",
+ __UNCONST(NAME_JUST_RIGHT)));
+
+ (void) strcpy(retname, "foo");
+ PTHREAD_REQUIRE(pthread_getname_np(self, retname, sizeof(retname)));
+ ATF_REQUIRE_EQ(retname[0], '\0');
+
+ PTHREAD_REQUIRE(pthread_create(&thr, &attr, threadfunc, NULL));
+ PTHREAD_REQUIRE(pthread_join(thr, NULL));
+
+ ATF_REQUIRE_EQ(pthread_getname_np(thr, retname, sizeof(retname)), ESRCH);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, name);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_once.c b/contrib/netbsd-tests/lib/libpthread/t_once.c
new file mode 100644
index 0000000..e879077
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_once.c
@@ -0,0 +1,200 @@
+/* $NetBSD: t_once.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_once.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+static pthread_once_t once = PTHREAD_ONCE_INIT;
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+static int x;
+
+#define NTHREADS 25
+
+#ifdef __FreeBSD__
+#include <sys/time.h>
+#endif
+
+static void
+ofunc(void)
+{
+ printf("Variable x has value %d\n", x);
+ x++;
+}
+
+ATF_TC(once1);
+ATF_TC_HEAD(once1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks pthread_once()");
+}
+ATF_TC_BODY(once1, tc)
+{
+
+ printf("1: Test 1 of pthread_once()\n");
+
+ PTHREAD_REQUIRE(pthread_once(&once, ofunc));
+ PTHREAD_REQUIRE(pthread_once(&once, ofunc));
+
+ printf("1: X has value %d\n",x );
+ ATF_REQUIRE_EQ(x, 1);
+}
+
+static void
+once2_ofunc(void)
+{
+ x++;
+ printf("ofunc: Variable x has value %d\n", x);
+ x++;
+}
+
+static void *
+once2_threadfunc(void *arg)
+{
+ int num;
+
+ PTHREAD_REQUIRE(pthread_once(&once, once2_ofunc));
+
+ num = *(int *)arg;
+ printf("Thread %d sees x with value %d\n", num, x);
+ ATF_REQUIRE_EQ(x, 2);
+
+ return NULL;
+}
+
+ATF_TC(once2);
+ATF_TC_HEAD(once2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks pthread_once()");
+}
+ATF_TC_BODY(once2, tc)
+{
+ pthread_t threads[NTHREADS];
+ int id[NTHREADS];
+ int i;
+
+ printf("1: Test 2 of pthread_once()\n");
+
+ for (i=0; i < NTHREADS; i++) {
+ id[i] = i;
+ PTHREAD_REQUIRE(pthread_create(&threads[i], NULL, once2_threadfunc, &id[i]));
+ }
+
+ for (i=0; i < NTHREADS; i++)
+ PTHREAD_REQUIRE(pthread_join(threads[i], NULL));
+
+ printf("1: X has value %d\n",x );
+ ATF_REQUIRE_EQ(x, 2);
+}
+
+static void
+once3_cleanup(void *m)
+{
+ pthread_mutex_t *mu = m;
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(mu));
+}
+
+static void
+once3_ofunc(void)
+{
+ pthread_testcancel();
+}
+
+static void *
+once3_threadfunc(void *arg)
+{
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ pthread_cleanup_push(once3_cleanup, &mutex);
+ PTHREAD_REQUIRE(pthread_once(&once, once3_ofunc));
+ pthread_cleanup_pop(1);
+
+ return NULL;
+}
+
+static void
+handler(int sig, siginfo_t *info, void *ctx)
+{
+ atf_tc_fail("Signal handler was called; "
+ "main thread deadlocked in pthread_once()");
+}
+
+ATF_TC(once3);
+ATF_TC_HEAD(once3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks pthread_once()");
+}
+ATF_TC_BODY(once3, tc)
+{
+ pthread_t thread;
+ struct sigaction act;
+ struct itimerval it;
+ printf("Test 3 of pthread_once() (test versus cancellation)\n");
+
+ act.sa_sigaction = handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_SIGINFO;
+ sigaction(SIGALRM, &act, NULL);
+
+ timerclear(&it.it_value);
+ it.it_value.tv_usec = 500000;
+ timerclear(&it.it_interval);
+ setitimer(ITIMER_REAL, &it, NULL);
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ PTHREAD_REQUIRE(pthread_create(&thread, NULL, once3_threadfunc, NULL));
+ PTHREAD_REQUIRE(pthread_cancel(thread));
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ PTHREAD_REQUIRE(pthread_join(thread, NULL));
+
+ PTHREAD_REQUIRE(pthread_once(&once, ofunc));
+
+ /* Cancel timer */
+ timerclear(&it.it_value);
+ setitimer(ITIMER_REAL, &it, NULL);
+
+ printf("Test succeeded\n");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, once1);
+ ATF_TP_ADD_TC(tp, once2);
+ ATF_TP_ADD_TC(tp, once3);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_preempt.c b/contrib/netbsd-tests/lib/libpthread/t_preempt.c
new file mode 100644
index 0000000..7ec43b6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_preempt.c
@@ -0,0 +1,128 @@
+/* $NetBSD: t_preempt.c,v 1.2 2010/11/03 16:10:22 christos Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_preempt.c,v 1.2 2010/11/03 16:10:22 christos Exp $");
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+pthread_mutex_t mutex;
+pthread_cond_t cond;
+int started;
+
+#define HUGE_BUFFER 1<<20
+#define NTHREADS 1
+
+static void *
+threadfunc(void *arg)
+{
+ printf("2: Second thread.\n");
+
+ printf("2: Locking mutex\n");
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+ printf("2: Got mutex.\n");
+ started++;
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ PTHREAD_REQUIRE(pthread_cond_signal(&cond));
+ sleep(1);
+
+ return NULL;
+}
+
+ATF_TC(preempt1);
+ATF_TC_HEAD(preempt1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks kernel preemption during a large uiomove");
+}
+ATF_TC_BODY(preempt1, tc)
+{
+ int i;
+ ssize_t rv;
+ pthread_t new;
+ void *joinval;
+
+ char *mem;
+ int fd;
+
+ mem = malloc(HUGE_BUFFER);
+ ATF_REQUIRE_MSG(mem != NULL, "%s", strerror(errno));
+
+ fd = open("/dev/urandom", O_RDONLY, 0);
+ ATF_REQUIRE_MSG(fd != -1, "%s", strerror(errno));
+
+ printf("1: preempt test\n");
+
+ PTHREAD_REQUIRE(pthread_cond_init(&cond, NULL));
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
+
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex));
+
+ started = 0;
+
+ for (i = 0; i < NTHREADS; i++) {
+ PTHREAD_REQUIRE(pthread_create(&new, NULL, threadfunc, NULL));
+ }
+
+ while (started < NTHREADS) {
+ PTHREAD_REQUIRE(pthread_cond_wait(&cond, &mutex));
+ }
+
+ printf("1: Thread has started.\n");
+
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
+ printf("1: After releasing the mutex.\n");
+
+ rv = read(fd, mem, HUGE_BUFFER);
+ close(fd);
+ ATF_REQUIRE_EQ(rv, HUGE_BUFFER);
+
+ PTHREAD_REQUIRE(pthread_join(new, &joinval));
+
+ printf("1: Thread joined.\n");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, preempt1);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_resolv.sh b/contrib/netbsd-tests/lib/libpthread/t_resolv.sh
new file mode 100755
index 0000000..847eadc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_resolv.sh
@@ -0,0 +1,42 @@
+# $NetBSD: t_resolv.sh,v 1.1 2010/07/16 15:42:53 jmmv Exp $
+#
+# 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.
+#
+
+atf_test_case resolv
+resolv_head()
+{
+ atf_set "descr" "Checks parallel name resolution"
+}
+resolv_body()
+{
+ "$(atf_get_srcdir)"/h_resolv -d -n 5 -h 5 \
+ "$(atf_get_srcdir)"/d_mach || atf_fail "test failed"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case resolv
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_rwlock.c b/contrib/netbsd-tests/lib/libpthread/t_rwlock.c
new file mode 100644
index 0000000..b2a3d6f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_rwlock.c
@@ -0,0 +1,125 @@
+/* $NetBSD: t_rwlock.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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.
+ */
+
+/*-
+ * Copyright (c)2004 YAMAMOTO Takashi,
+ * 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 AUTHOR 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 AUTHOR 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_rwlock.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+pthread_rwlock_t lk;
+
+struct timespec to;
+
+/* ARGSUSED */
+static void *
+do_nothing(void *dummy)
+{
+ return NULL;
+}
+
+ATF_TC(rwlock1);
+ATF_TC_HEAD(rwlock1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks read/write locks");
+}
+ATF_TC_BODY(rwlock1, tc)
+{
+ int error;
+ pthread_t t;
+
+ PTHREAD_REQUIRE(pthread_create(&t, NULL, do_nothing, NULL));
+ PTHREAD_REQUIRE(pthread_rwlock_init(&lk, NULL));
+ PTHREAD_REQUIRE(pthread_rwlock_rdlock(&lk));
+ PTHREAD_REQUIRE(pthread_rwlock_rdlock(&lk));
+ PTHREAD_REQUIRE(pthread_rwlock_unlock(&lk));
+
+ ATF_REQUIRE_EQ(pthread_rwlock_trywrlock(&lk), EBUSY);
+
+ ATF_REQUIRE_EQ_MSG(clock_gettime(CLOCK_REALTIME, &to), 0,
+ "%s", strerror(errno));
+ to.tv_sec++;
+ error = pthread_rwlock_timedwrlock(&lk, &to);
+ ATF_REQUIRE_MSG(error == ETIMEDOUT || error == EDEADLK,
+ "%s", strerror(error));
+
+ PTHREAD_REQUIRE(pthread_rwlock_unlock(&lk));
+
+ ATF_REQUIRE_EQ_MSG(clock_gettime(CLOCK_REALTIME, &to), 0,
+ "%s", strerror(errno));
+ to.tv_sec++;
+ PTHREAD_REQUIRE(pthread_rwlock_timedwrlock(&lk, &to));
+
+ ATF_REQUIRE_EQ_MSG(clock_gettime(CLOCK_REALTIME, &to), 0,
+ "%s", strerror(errno));
+ to.tv_sec++;
+ error = pthread_rwlock_timedwrlock(&lk, &to);
+ ATF_REQUIRE_MSG(error == ETIMEDOUT || error == EDEADLK,
+ "%s", strerror(error));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, rwlock1);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_sem.c b/contrib/netbsd-tests/lib/libpthread/t_sem.c
new file mode 100644
index 0000000..5bb7ae7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_sem.c
@@ -0,0 +1,310 @@
+/* $NetBSD: t_sem.c,v 1.8 2014/11/04 00:20:19 justin Exp $ */
+
+/*
+ * Copyright (c) 2008, 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.
+ */
+
+/*-
+ * Copyright (c)2004 YAMAMOTO Takashi,
+ * 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 AUTHOR 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 AUTHOR 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 (C) 2000 Jason Evans <jasone@freebsd.org>.
+ * 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(s), this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified other than the possible
+ * addition of one or more copyright notices.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice(s), 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 COPYRIGHT HOLDER(S) ``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 HOLDER(S) 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008, 2010\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_sem.c,v 1.8 2014/11/04 00:20:19 justin Exp $");
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+#define NTHREADS 10
+
+#define _LIBC_R_
+
+#define SEM_REQUIRE(x) \
+ ATF_REQUIRE_EQ_MSG(x, 0, "%s", strerror(errno))
+
+static sem_t sem;
+
+#ifdef __FreeBSD__
+#include <sys/time.h>
+#endif
+
+ATF_TC(named);
+ATF_TC_HEAD(named, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks named semaphores");
+}
+ATF_TC_BODY(named, tc)
+{
+ sem_t *semp;
+
+ ATF_REQUIRE_MSG(-1 != sysconf(_SC_SEMAPHORES), "%s", strerror(errno));
+
+ printf("Test begin\n");
+
+ (void) sem_unlink("/foo");
+ semp = sem_open("/foo", O_CREAT | O_EXCL, 0644, 0);
+ ATF_REQUIRE_MSG(semp != SEM_FAILED, "%s", strerror(errno));
+ SEM_REQUIRE(sem_close(semp));
+ SEM_REQUIRE(sem_unlink("/foo"));
+
+ printf("Test end\n");
+}
+
+ATF_TC(unnamed);
+ATF_TC_HEAD(unnamed, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks unnamed semaphores");
+}
+
+static void *
+entry(void * a_arg)
+{
+ pthread_t self = pthread_self();
+ sem_t *semp = (sem_t *) a_arg;
+
+ printf("Thread %p waiting for semaphore...\n", self);
+ sem_wait(semp);
+ printf("Thread %p got semaphore\n", self);
+
+ return NULL;
+}
+
+ATF_TC_BODY(unnamed, tc)
+{
+ sem_t sem_a, sem_b;
+ pthread_t threads[NTHREADS];
+ unsigned i, j;
+ int val;
+
+ ATF_REQUIRE_MSG(-1 != sysconf(_SC_SEMAPHORES), "%s", strerror(errno));
+
+ printf("Test begin\n");
+
+ SEM_REQUIRE(sem_init(&sem_b, 0, 0));
+ SEM_REQUIRE(sem_getvalue(&sem_b, &val));
+ ATF_REQUIRE_EQ(0, val);
+
+ SEM_REQUIRE(sem_post(&sem_b));
+ SEM_REQUIRE(sem_getvalue(&sem_b, &val));
+ ATF_REQUIRE_EQ(1, val);
+
+ SEM_REQUIRE(sem_wait(&sem_b));
+ ATF_REQUIRE_EQ(sem_trywait(&sem_b), -1);
+ ATF_REQUIRE_EQ(errno, EAGAIN);
+ SEM_REQUIRE(sem_post(&sem_b));
+ SEM_REQUIRE(sem_trywait(&sem_b));
+ SEM_REQUIRE(sem_post(&sem_b));
+ SEM_REQUIRE(sem_wait(&sem_b));
+ SEM_REQUIRE(sem_post(&sem_b));
+
+ SEM_REQUIRE(sem_destroy(&sem_b));
+
+ SEM_REQUIRE(sem_init(&sem_a, 0, 0));
+
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < NTHREADS; i++) {
+ PTHREAD_REQUIRE(pthread_create(&threads[i], NULL,
+ entry, (void *) &sem_a));
+ }
+
+ for (i = 0; i < NTHREADS; i++) {
+ usleep(10000);
+ printf("main loop %u: posting...\n", j+1);
+ SEM_REQUIRE(sem_post(&sem_a));
+ }
+
+ for (i = 0; i < NTHREADS; i++) {
+ PTHREAD_REQUIRE(pthread_join(threads[i], NULL));
+ }
+ }
+
+ SEM_REQUIRE(sem_destroy(&sem_a));
+
+ printf("Test end\n");
+}
+
+static void
+sighandler(int signo)
+{
+ /* printf("signal %d\n", signo); */
+
+ ATF_REQUIRE_EQ_MSG(signo, SIGALRM, "unexpected signal");
+ SEM_REQUIRE(sem_post(&sem));
+}
+
+static void
+alarm_ms(const int ms)
+{
+ struct itimerval timer;
+ timer.it_interval.tv_sec = 0;
+ timer.it_interval.tv_usec = 0;
+ timer.it_value.tv_sec = 0;
+ timer.it_value.tv_usec = ms * 1000;
+ ATF_REQUIRE(setitimer(ITIMER_REAL, &timer, NULL) == 0);
+}
+
+static void *
+threadfunc(void *arg)
+{
+ int i, ret;
+
+ printf("Entering loop\n");
+ for (i = 0; i < 500; ) {
+ if ((i & 1) != 0) {
+ do {
+ ret = sem_wait(&sem);
+ } while (ret == -1 && errno == EINTR);
+ ATF_REQUIRE(ret == 0);
+ } else {
+ ret = sem_trywait(&sem);
+ if (ret == -1) {
+ ATF_REQUIRE(errno == EAGAIN);
+ continue;
+ }
+ }
+ printf("%s: %d\n", __func__, i);
+ alarm_ms(5);
+ i++;
+ }
+
+ return NULL;
+}
+
+static void
+before_start_test(const bool use_pthread)
+{
+ pthread_t t;
+
+ SEM_REQUIRE(sem_init(&sem, 0, 0));
+ ATF_REQUIRE(SIG_ERR != signal(SIGALRM, sighandler));
+
+ alarm_ms(5);
+
+ if (use_pthread) {
+ PTHREAD_REQUIRE(pthread_create(&t, NULL, threadfunc, NULL));
+ PTHREAD_REQUIRE(pthread_join(t, NULL));
+ } else {
+ threadfunc(NULL);
+ }
+}
+
+ATF_TC(before_start_no_threads);
+ATF_TC_HEAD(before_start_no_threads, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks using semaphores without any "
+ "thread running");
+ atf_tc_set_md_var(tc, "timeout", "40");
+}
+ATF_TC_BODY(before_start_no_threads, tc)
+{
+ before_start_test(false);
+}
+
+ATF_TC(before_start_one_thread);
+ATF_TC_HEAD(before_start_one_thread, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks using semaphores before "
+ "starting one thread");
+ atf_tc_set_md_var(tc, "timeout", "40");
+}
+ATF_TC_BODY(before_start_one_thread, tc)
+{
+ before_start_test(true);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, named);
+ ATF_TP_ADD_TC(tp, unnamed);
+ ATF_TP_ADD_TC(tp, before_start_no_threads);
+ ATF_TP_ADD_TC(tp, before_start_one_thread);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_sigalarm.c b/contrib/netbsd-tests/lib/libpthread/t_sigalarm.c
new file mode 100644
index 0000000..0a58c4e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_sigalarm.c
@@ -0,0 +1,107 @@
+/* $NetBSD: t_sigalarm.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_sigalarm.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+int alarm_set;
+
+#ifdef SA_SIGINFO
+static void
+alarm_handler(int signo, siginfo_t *si, void *ctx)
+{
+ ATF_REQUIRE_EQ_MSG(si->si_signo, signo, "Received unexpected signal");
+ alarm_set = 1;
+}
+#else
+static void
+alarm_handler(int signo)
+{
+ ATF_REQUIRE_EQ_MSG(SIGALRM, signo, "Received unexpected signal");
+ alarm_set = 1;
+}
+#endif
+
+static void *
+setup(void *dummy)
+{
+ struct sigaction sa;
+ sigset_t ss;
+#ifdef SA_SIGINFO
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = alarm_handler;
+#else
+ sa.sa_flags = 0;
+ sa.sa_handler = alarm_handler;
+#endif
+ sigfillset(&ss);
+ sigprocmask(SIG_SETMASK, &ss, NULL);
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGALRM, &sa, NULL);
+ alarm(1);
+
+ return NULL;
+}
+
+ATF_TC(sigalarm);
+ATF_TC_HEAD(sigalarm, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks sigsuspend in libpthread when pthread lib is initialized");
+}
+ATF_TC_BODY(sigalarm, tc)
+{
+ sigset_t set;
+ pthread_t self = pthread_self();
+
+ PTHREAD_REQUIRE(pthread_create(&self, NULL, setup, NULL));
+
+ sigemptyset(&set);
+ sigsuspend(&set);
+ alarm(0);
+
+ ATF_REQUIRE(alarm_set);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, sigalarm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_siglongjmp.c b/contrib/netbsd-tests/lib/libpthread/t_siglongjmp.c
new file mode 100644
index 0000000..298879c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_siglongjmp.c
@@ -0,0 +1,109 @@
+/* $NetBSD: t_siglongjmp.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_siglongjmp.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+/*
+ * Regression test for siglongjmp out of a signal handler back into
+ * its thread.
+ *
+ * Written by Christian Limpach <cl@NetBSD.org>, December 2003.
+ * Public domain.
+ */
+
+#include <sys/resource.h>
+
+#include <pthread.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+static sigjmp_buf env;
+
+static void *
+thread(void *arg)
+{
+ return NULL;
+}
+
+static void
+handler(int sig, siginfo_t *info, void *ctx)
+{
+ siglongjmp(env, 1);
+}
+
+ATF_TC(siglongjmp1);
+ATF_TC_HEAD(siglongjmp1, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks siglongjmp() out of a signal handler back into its thread");
+}
+ATF_TC_BODY(siglongjmp1, tc)
+{
+ pthread_t t;
+ sigset_t nset;
+ struct rlimit rlim;
+ struct sigaction act;
+
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ (void)setrlimit(RLIMIT_CORE, &rlim);
+
+ PTHREAD_REQUIRE(pthread_create(&t, NULL, thread, NULL));
+
+ sigemptyset(&nset);
+ sigaddset(&nset, SIGUSR1);
+ PTHREAD_REQUIRE(pthread_sigmask(SIG_SETMASK, &nset, NULL));
+
+ act.sa_sigaction = handler;
+ sigemptyset(&act.sa_mask);
+ sigaddset(&act.sa_mask, SIGUSR2);
+ act.sa_flags = 0;
+ sigaction(SIGSEGV, &act, NULL);
+
+ ATF_REQUIRE_EQ(sigsetjmp(env, 1), 0);
+
+ PTHREAD_REQUIRE(pthread_sigmask(0, NULL, &nset));
+
+ ATF_REQUIRE_EQ_MSG(sigismember(&nset, SIGSEGV), 0, "SIGSEGV set");
+ ATF_REQUIRE_EQ_MSG(sigismember(&nset, SIGUSR2), 0, "SIGUSR2 set");
+ ATF_REQUIRE_MSG(sigismember(&nset, SIGUSR1), "SIGUSR1 not set");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, siglongjmp1);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_sigmask.c b/contrib/netbsd-tests/lib/libpthread/t_sigmask.c
new file mode 100644
index 0000000..69e0577
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_sigmask.c
@@ -0,0 +1,261 @@
+/* $NetBSD: t_sigmask.c,v 1.3 2013/10/19 17:45:01 christos Exp $ */
+
+/*
+ * Copyright (c) 2008, 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 <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008, 2010\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_sigmask.c,v 1.3 2013/10/19 17:45:01 christos Exp $");
+
+/*
+ * Regression test for pthread_sigmask when SA upcalls aren't started yet.
+ *
+ * Written by Christian Limpach <cl@NetBSD.org>, December 2003.
+ * Public domain.
+ */
+
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <sys/resource.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+static volatile sig_atomic_t flag;
+static volatile sig_atomic_t flag2;
+
+static volatile pthread_t thr_usr1;
+static volatile pthread_t thr_usr2;
+
+static sig_atomic_t count = 0;
+
+ATF_TC(upcalls_not_started);
+ATF_TC_HEAD(upcalls_not_started, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks pthread_sigmask when SA upcalls "
+ "aren't started yet");
+}
+ATF_TC_BODY(upcalls_not_started, tc)
+{
+ sigset_t nset;
+ struct rlimit rlim;
+
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ (void) setrlimit(RLIMIT_CORE, &rlim);
+
+ sigemptyset(&nset);
+ sigaddset(&nset, SIGFPE);
+ pthread_sigmask(SIG_BLOCK, &nset, NULL);
+
+ kill(getpid(), SIGFPE);
+}
+
+static void
+upcalls_not_started_handler1(int sig, siginfo_t *info, void *ctx)
+{
+
+ kill(getpid(), SIGUSR2);
+ /*
+ * If the mask is properly set, SIGUSR2 will not be handled
+ * until this handler returns.
+ */
+ flag = 1;
+}
+
+static void
+upcalls_not_started_handler2(int sig, siginfo_t *info, void *ctx)
+{
+ if (flag == 1)
+ flag = 2;
+}
+
+ATF_TC(before_threads);
+ATF_TC_HEAD(before_threads, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that signal masks are respected "
+ "before threads are started");
+}
+ATF_TC_BODY(before_threads, tc)
+{
+ struct sigaction act;
+
+ act.sa_sigaction = upcalls_not_started_handler1;
+ sigemptyset(&act.sa_mask);
+ sigaddset(&act.sa_mask, SIGUSR2);
+ act.sa_flags = SA_SIGINFO;
+
+ ATF_REQUIRE_EQ(sigaction(SIGUSR1, &act, NULL), 0);
+
+ act.sa_sigaction = upcalls_not_started_handler2;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_SIGINFO;
+ (void)sigaction(SIGUSR2, &act, NULL);
+
+ kill(getpid(), SIGUSR1);
+
+ ATF_REQUIRE_EQ(flag, 2);
+ printf("Success: Both handlers ran in order\n");
+}
+
+static void
+respected_while_running_handler1(int sig, siginfo_t *info, void *ctx)
+{
+
+ kill(getpid(), SIGUSR2);
+ /*
+ * If the mask is properly set, SIGUSR2 will not be handled
+ * by the current thread until this handler returns.
+ */
+ flag = 1;
+ thr_usr1 = pthread_self();
+}
+
+static void
+respected_while_running_handler2(int sig, siginfo_t *info, void *ctx)
+{
+ if (flag == 1)
+ flag = 2;
+ flag2 = 1;
+ thr_usr2 = pthread_self();
+}
+
+static void *
+respected_while_running_threadroutine(void *arg)
+{
+
+ kill(getpid(), SIGUSR1);
+ sleep(1);
+
+ if (flag == 2)
+ printf("Success: Both handlers ran in order\n");
+ else if (flag == 1 && flag2 == 1 && thr_usr1 != thr_usr2)
+ printf("Success: Handlers were invoked by different threads\n");
+ else {
+ printf("Failure: flag=%d, flag2=%d, thr1=%p, thr2=%p\n",
+ (int)flag, (int)flag2, (void *)thr_usr1, (void *)thr_usr2);
+ atf_tc_fail("failure");
+ }
+
+ return NULL;
+}
+
+ATF_TC(respected_while_running);
+ATF_TC_HEAD(respected_while_running, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that signal masks are respected "
+ "while threads are running");
+}
+ATF_TC_BODY(respected_while_running, tc)
+{
+ struct sigaction act;
+ pthread_t thread;
+
+ act.sa_sigaction = respected_while_running_handler1;
+ sigemptyset(&act.sa_mask);
+ sigaddset(&act.sa_mask, SIGUSR2);
+ act.sa_flags = SA_SIGINFO;
+
+ ATF_REQUIRE_EQ(sigaction(SIGUSR1, &act, NULL), 0);
+
+ act.sa_sigaction = respected_while_running_handler2;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_SIGINFO;
+ (void)sigaction(SIGUSR2, &act, NULL);
+
+ PTHREAD_REQUIRE(pthread_create(&thread, NULL,
+ respected_while_running_threadroutine, NULL));
+ PTHREAD_REQUIRE(pthread_join(thread, NULL));
+}
+
+static void
+incorrect_mask_bug_handler(int sig)
+{
+ count++;
+}
+
+static void *
+incorrect_mask_bug_sleeper(void* arg)
+{
+ int i;
+ for (i = 0; i < 10; i++)
+ sleep(1);
+
+ atf_tc_fail("sleeper");
+}
+
+ATF_TC(incorrect_mask_bug);
+ATF_TC_HEAD(incorrect_mask_bug, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks for bug in libpthread where "
+ "incorrect signal mask was used");
+}
+ATF_TC_BODY(incorrect_mask_bug, tc)
+{
+ pthread_t id;
+ struct sigaction act;
+
+ act.sa_sigaction = NULL;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ act.sa_handler = incorrect_mask_bug_handler;
+
+ ATF_REQUIRE_EQ_MSG(sigaction(SIGALRM, &act, NULL), 0, "%s",
+ strerror(errno));
+
+ sigaddset(&act.sa_mask, SIGALRM);
+ PTHREAD_REQUIRE(pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL));
+
+ PTHREAD_REQUIRE(pthread_create(&id, NULL, incorrect_mask_bug_sleeper,
+ NULL));
+ sleep(1);
+
+ sigemptyset(&act.sa_mask);
+ PTHREAD_REQUIRE(pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL));
+
+ for (;;) {
+ alarm(1);
+ if (select(1, NULL, NULL, NULL, NULL) == -1 && errno == EINTR)
+ if (count == 2)
+ return;
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, upcalls_not_started);
+ ATF_TP_ADD_TC(tp, before_threads);
+ ATF_TP_ADD_TC(tp, respected_while_running);
+ ATF_TP_ADD_TC(tp, incorrect_mask_bug);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_sigsuspend.c b/contrib/netbsd-tests/lib/libpthread/t_sigsuspend.c
new file mode 100644
index 0000000..1179657
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_sigsuspend.c
@@ -0,0 +1,90 @@
+/* $NetBSD: t_sigsuspend.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_sigsuspend.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+/*
+ * Regression test for sigsuspend in libpthread when pthread lib isn't
+ * initialized.
+ *
+ * Written by Love FIXME strand <lha@NetBSD.org>, March 2003.
+ * Public domain.
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+int alarm_set;
+
+static void
+alarm_handler(int signo)
+{
+ alarm_set = 1;
+}
+
+ATF_TC(sigsuspend);
+ATF_TC_HEAD(sigsuspend, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks sigsuspend in libpthread when pthread lib isn't initialized");
+}
+ATF_TC_BODY(sigsuspend, tc)
+{
+ struct sigaction sa;
+ sigset_t set;
+
+ sa.sa_flags = 0;
+ sa.sa_handler = alarm_handler;
+ sigemptyset(&sa.sa_mask);
+
+ sigaction(SIGALRM, &sa, NULL);
+
+ alarm(1);
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGUSR1);
+
+ sigsuspend(&set);
+
+ alarm(0);
+
+ ATF_REQUIRE(alarm_set);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, sigsuspend);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_sleep.c b/contrib/netbsd-tests/lib/libpthread/t_sleep.c
new file mode 100644
index 0000000..93a30e3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_sleep.c
@@ -0,0 +1,104 @@
+/* $NetBSD: t_sleep.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $ */
+
+/*
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_sleep.c,v 1.1 2010/07/16 15:42:53 jmmv Exp $");
+
+#include <sys/time.h>
+
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+#define LONGTIME 2000000000
+
+static void *
+threadfunc(void *arg)
+{
+ sleep(LONGTIME);
+
+ return NULL;
+}
+
+static void
+handler(int sig)
+{
+ /*
+ * Nothing to do; invoking the handler is enough to interrupt
+ * the sleep.
+ */
+}
+
+ATF_TC(sleep1);
+ATF_TC_HEAD(sleep1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks sleeping past the time when "
+ "time_t wraps");
+}
+ATF_TC_BODY(sleep1, tc)
+{
+ pthread_t thread;
+ struct itimerval it;
+ struct sigaction act;
+ sigset_t mtsm;
+
+ printf("Testing sleeps unreasonably far into the future.\n");
+
+ act.sa_handler = handler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ sigaction(SIGALRM, &act, NULL);
+
+ PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL));
+
+ /* make sure the signal is delivered to the child thread */
+ sigemptyset(&mtsm);
+ sigaddset(&mtsm, SIGALRM);
+ PTHREAD_REQUIRE(pthread_sigmask(SIG_BLOCK, &mtsm, 0));
+
+ timerclear(&it.it_interval);
+ timerclear(&it.it_value);
+ it.it_value.tv_sec = 1;
+ setitimer(ITIMER_REAL, &it, NULL);
+
+ PTHREAD_REQUIRE(pthread_join(thread, NULL));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, sleep1);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c b/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c
new file mode 100644
index 0000000..8fd2314
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_swapcontext.c
@@ -0,0 +1,112 @@
+/* $NetBSD: t_swapcontext.c,v 1.2 2014/08/25 16:31:15 bouyer Exp $ */
+
+/*
+ * Copyright (c) 2012 Emmanuel Dreyfus. 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/cdefs.h>
+__RCSID("$NetBSD");
+
+#include <pthread.h>
+#include <ucontext.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <atf-c.h>
+
+#include "h_common.h"
+
+#define STACKSIZE 65536
+
+char stack[STACKSIZE];
+ucontext_t nctx;
+ucontext_t octx;
+void *oself;
+void *nself;
+int val1, val2;
+
+/* ARGSUSED0 */
+static void
+swapfunc(void *arg)
+{
+ /*
+ * If the test fails, we are very likely to crash
+ * without the opportunity to report
+ */
+ nself = (void *)pthread_self();
+ printf("after swapcontext self = %p\n", nself);
+
+ ATF_REQUIRE_EQ(oself, nself);
+ printf("Test succeeded\n");
+ /* Go back in main */
+ ATF_REQUIRE(swapcontext(&nctx, &octx));
+
+ /* NOTREACHED */
+ return;
+}
+
+/* ARGSUSED0 */
+static void *
+threadfunc(void *arg)
+{
+ nctx.uc_stack.ss_sp = stack;
+ nctx.uc_stack.ss_size = sizeof(stack);
+
+ makecontext(&nctx, (void *)*swapfunc, 0);
+
+ oself = (void *)pthread_self();
+ printf("before swapcontext self = %p\n", oself);
+ PTHREAD_REQUIRE(swapcontext(&octx, &nctx));
+
+ /* NOTREACHED */
+ return NULL;
+}
+
+
+ATF_TC(swapcontext1);
+ATF_TC_HEAD(swapcontext1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() "
+ "alters pthread_self()");
+}
+ATF_TC_BODY(swapcontext1, tc)
+{
+ pthread_t thread;
+
+ oself = (void *)&val1;
+ nself = (void *)&val2;
+
+ printf("Testing if swapcontext() alters pthread_self()\n");
+
+ PTHREAD_REQUIRE(getcontext(&nctx));
+ PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL));
+ PTHREAD_REQUIRE(pthread_join(thread, NULL));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, swapcontext1);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/librt/t_sched.c b/contrib/netbsd-tests/lib/librt/t_sched.c
new file mode 100644
index 0000000..8796043
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librt/t_sched.c
@@ -0,0 +1,256 @@
+/* $NetBSD: t_sched.c,v 1.5 2012/03/25 04:11:42 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_sched.c,v 1.5 2012/03/25 04:11:42 christos Exp $");
+
+#include <sched.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+static void sched_priority_set(int, int);
+
+ATF_TC(sched_getparam);
+ATF_TC_HEAD(sched_getparam, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of sched_getparam(3)");
+}
+
+ATF_TC_BODY(sched_getparam, tc)
+{
+ struct sched_param s1, s2;
+ pid_t p = getpid();
+
+ /*
+ * IEEE Std 1003.1-2008: if the supplied pid is zero,
+ * the parameters for the calling process are returned.
+ */
+ ATF_REQUIRE(sched_getparam(0, &s1) == 0);
+ ATF_REQUIRE(sched_getparam(p, &s2) == 0);
+
+ ATF_CHECK_EQ(s1.sched_priority, s2.sched_priority);
+
+ /*
+ * The behavior is undefined but should error
+ * out in case the supplied PID is negative.
+ */
+ ATF_REQUIRE(sched_getparam(-1, &s1) != 0);
+}
+
+ATF_TC(sched_priority);
+ATF_TC_HEAD(sched_priority, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sched(3) priority ranges");
+}
+
+ATF_TC_BODY(sched_priority, tc)
+{
+ static const int pol[3] = { SCHED_OTHER, SCHED_FIFO, SCHED_RR };
+ int pmax, pmin;
+ size_t i;
+
+ /*
+ * Test that bogus values error out.
+ */
+ if (INT_MAX > SCHED_RR)
+ ATF_REQUIRE(sched_get_priority_max(INT_MAX) != 0);
+
+ if (-INT_MAX < SCHED_OTHER)
+ ATF_REQUIRE(sched_get_priority_max(-INT_MAX) != 0);
+
+ /*
+ * Test that we have a valid range.
+ */
+ for (i = 0; i < __arraycount(pol); i++) {
+
+ pmax = sched_get_priority_max(pol[i]);
+ pmin = sched_get_priority_min(pol[i]);
+
+ ATF_REQUIRE(pmax != -1);
+ ATF_REQUIRE(pmin != -1);
+ ATF_REQUIRE(pmax > pmin);
+ }
+}
+
+static void
+sched_priority_set(int pri, int pol)
+{
+ struct sched_param sched;
+
+ sched.sched_priority = pri;
+
+ ATF_REQUIRE(pri >= 0);
+ ATF_REQUIRE(sched_setscheduler(0, pol, &sched) == 0);
+
+ /*
+ * Test that the policy was changed.
+ */
+ ATF_CHECK_EQ(sched_getscheduler(0), pol);
+
+ /*
+ * And that sched_getparam(3) returns the new priority.
+ */
+ sched.sched_priority = -1;
+
+ ATF_REQUIRE(sched_getparam(0, &sched) == 0);
+ ATF_CHECK_EQ(sched.sched_priority, pri);
+}
+
+ATF_TC(sched_setscheduler_1);
+ATF_TC_HEAD(sched_setscheduler_1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), max, RR");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(sched_setscheduler_1, tc)
+{
+ int pri;
+
+ pri = sched_get_priority_max(SCHED_RR);
+ sched_priority_set(pri, SCHED_RR);
+}
+
+ATF_TC(sched_setscheduler_2);
+ATF_TC_HEAD(sched_setscheduler_2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), min, RR");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(sched_setscheduler_2, tc)
+{
+ int pri;
+
+ pri = sched_get_priority_min(SCHED_RR);
+ sched_priority_set(pri, SCHED_RR);
+}
+
+ATF_TC(sched_setscheduler_3);
+ATF_TC_HEAD(sched_setscheduler_3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), max, FIFO");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(sched_setscheduler_3, tc)
+{
+ int pri;
+
+ pri = sched_get_priority_max(SCHED_FIFO);
+ sched_priority_set(pri, SCHED_FIFO);
+}
+
+ATF_TC(sched_setscheduler_4);
+ATF_TC_HEAD(sched_setscheduler_4, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "sched_setscheduler(3), min, FIFO");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(sched_setscheduler_4, tc)
+{
+ int pri;
+
+ pri = sched_get_priority_min(SCHED_FIFO);
+ sched_priority_set(pri, SCHED_FIFO);
+}
+
+ATF_TC(sched_rr_get_interval_1);
+ATF_TC_HEAD(sched_rr_get_interval_1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sched_rr_get_interval(3), #1"
+ " (PR lib/44768)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(sched_rr_get_interval_1, tc)
+{
+ struct timespec tv;
+ int pri;
+
+ pri = sched_get_priority_min(SCHED_RR);
+ sched_priority_set(pri, SCHED_RR);
+
+ /*
+ * This should fail with ESRCH for invalid PID.
+ */
+ ATF_REQUIRE(sched_rr_get_interval(-INT_MAX, &tv) != 0);
+}
+
+ATF_TC(sched_rr_get_interval_2);
+ATF_TC_HEAD(sched_rr_get_interval_2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sched_rr_get_interval(3), #2");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(sched_rr_get_interval_2, tc)
+{
+ struct timespec tv1, tv2;
+ int pri;
+
+ pri = sched_get_priority_min(SCHED_RR);
+ sched_priority_set(pri, SCHED_RR);
+
+ tv1.tv_sec = tv2.tv_sec = -1;
+ tv1.tv_nsec = tv2.tv_nsec = -1;
+
+ ATF_REQUIRE(sched_rr_get_interval(0, &tv1) == 0);
+ ATF_REQUIRE(sched_rr_get_interval(getpid(), &tv2) == 0);
+
+ ATF_REQUIRE(tv1.tv_sec != -1);
+ ATF_REQUIRE(tv2.tv_sec != -1);
+
+ ATF_REQUIRE(tv1.tv_nsec != -1);
+ ATF_REQUIRE(tv2.tv_nsec != -1);
+
+ ATF_REQUIRE(tv1.tv_sec == tv2.tv_sec);
+ ATF_REQUIRE(tv1.tv_nsec == tv2.tv_nsec);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sched_getparam);
+ ATF_TP_ADD_TC(tp, sched_priority);
+
+ ATF_TP_ADD_TC(tp, sched_setscheduler_1);
+ ATF_TP_ADD_TC(tp, sched_setscheduler_2);
+ ATF_TP_ADD_TC(tp, sched_setscheduler_3);
+ ATF_TP_ADD_TC(tp, sched_setscheduler_4);
+
+ ATF_TP_ADD_TC(tp, sched_rr_get_interval_1);
+ ATF_TP_ADD_TC(tp, sched_rr_get_interval_2);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/librt/t_sem.c b/contrib/netbsd-tests/lib/librt/t_sem.c
new file mode 100644
index 0000000..e76cd52
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librt/t_sem.c
@@ -0,0 +1,181 @@
+/* $NetBSD: t_sem.c,v 1.2 2010/11/08 13:05:49 njoly Exp $ */
+
+/*
+ * Copyright (c) 2008, 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.
+ */
+
+/*
+ * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>.
+ * 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(s), this list of conditions and the following disclaimer as
+ * the first lines of this file unmodified other than the possible
+ * addition of one or more copyright notices.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice(s), 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 COPYRIGHT HOLDER(S) ``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 HOLDER(S) 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008, 2010\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_sem.c,v 1.2 2010/11/08 13:05:49 njoly Exp $");
+
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#define NCHILDREN 10
+
+ATF_TC(basic);
+ATF_TC_HEAD(basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks basic functionality of POSIX "
+ "semaphores");
+}
+ATF_TC_BODY(basic, tc)
+{
+ int val;
+ sem_t *sem_b;
+
+ if (sysconf(_SC_SEMAPHORES) == -1)
+ atf_tc_skip("POSIX semaphores not supported");
+
+#ifdef __FreeBSD__
+ sem_unlink("/sem_b");
+#endif
+ sem_b = sem_open("/sem_b", O_CREAT | O_EXCL, 0644, 0);
+ ATF_REQUIRE(sem_b != SEM_FAILED);
+
+ ATF_REQUIRE_EQ(sem_getvalue(sem_b, &val), 0);
+ ATF_REQUIRE_EQ(val, 0);
+
+ ATF_REQUIRE_EQ(sem_post(sem_b), 0);
+ ATF_REQUIRE_EQ(sem_getvalue(sem_b, &val), 0);
+ ATF_REQUIRE_EQ(val, 1);
+
+ ATF_REQUIRE_EQ(sem_wait(sem_b), 0);
+ ATF_REQUIRE_EQ(sem_trywait(sem_b), -1);
+ ATF_REQUIRE_EQ(errno, EAGAIN);
+ ATF_REQUIRE_EQ(sem_post(sem_b), 0);
+ ATF_REQUIRE_EQ(sem_trywait(sem_b), 0);
+ ATF_REQUIRE_EQ(sem_post(sem_b), 0);
+ ATF_REQUIRE_EQ(sem_wait(sem_b), 0);
+ ATF_REQUIRE_EQ(sem_post(sem_b), 0);
+
+ ATF_REQUIRE_EQ(sem_close(sem_b), 0);
+ ATF_REQUIRE_EQ(sem_unlink("/sem_b"), 0);
+}
+
+ATF_TC(child);
+ATF_TC_HEAD(child, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks using semaphores to synchronize "
+ "parent with multiple child processes");
+}
+ATF_TC_BODY(child, tc)
+{
+ pid_t children[NCHILDREN];
+ unsigned i, j;
+ sem_t *sem_a;
+ int status;
+
+ pid_t pid;
+
+ if (sysconf(_SC_SEMAPHORES) == -1)
+ atf_tc_skip("POSIX semaphores not supported");
+
+#ifdef __FreeBSD__
+ sem_unlink("/sem_a");
+#endif
+ sem_a = sem_open("/sem_a", O_CREAT | O_EXCL, 0644, 0);
+ ATF_REQUIRE(sem_a != SEM_FAILED);
+
+ for (j = 1; j <= 2; j++) {
+ for (i = 0; i < NCHILDREN; i++) {
+ switch ((pid = fork())) {
+ case -1:
+ atf_tc_fail("fork() returned -1");
+ case 0:
+ printf("PID %d waiting for semaphore...\n",
+ getpid());
+ ATF_REQUIRE_MSG(sem_wait(sem_a) == 0,
+ "sem_wait failed; iteration %d", j);
+ printf("PID %d got semaphore\n", getpid());
+ _exit(0);
+ default:
+ children[i] = pid;
+ break;
+ }
+ }
+
+ for (i = 0; i < NCHILDREN; i++) {
+ sleep(1);
+ printf("main loop %d: posting...\n", j);
+ ATF_REQUIRE_EQ(sem_post(sem_a), 0);
+ }
+
+ for (i = 0; i < NCHILDREN; i++) {
+ ATF_REQUIRE_EQ(waitpid(children[i], &status, 0), children[i]);
+ ATF_REQUIRE(WIFEXITED(status));
+ ATF_REQUIRE_EQ(WEXITSTATUS(status), 0);
+ }
+ }
+
+ ATF_REQUIRE_EQ(sem_close(sem_a), 0);
+ ATF_REQUIRE_EQ(sem_unlink("/sem_a"), 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, basic);
+ ATF_TP_ADD_TC(tp, child);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/librumpclient/h_exec.c b/contrib/netbsd-tests/lib/librumpclient/h_exec.c
new file mode 100644
index 0000000..cf2526c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumpclient/h_exec.c
@@ -0,0 +1,132 @@
+/* $NetBSD: h_exec.c,v 1.6 2011/02/16 17:57:44 pooka Exp $ */
+
+/*
+ * Copyright (c) 2011 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/socket.h>
+
+#include <netinet/in.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rump/rumpclient.h>
+#include <rump/rump_syscalls.h>
+
+int
+main(int argc, char *argv[])
+{
+ struct sockaddr_in sin;
+ socklen_t slen;
+ int s1, s2;
+ char buf[12];
+ char *eargv[4];
+ char *ename;
+ extern char **environ;
+
+ if (rumpclient_init() == -1)
+ err(1, "init");
+
+ if (argc > 1) {
+ if (strcmp(argv[1], "_didexec") == 0) {
+ rumpclient_daemon(0, 0); /* detach-me-notnot */
+ s2 = atoi(argv[2]);
+ slen = sizeof(sin);
+ /* see below */
+ rump_sys_accept(s2, (struct sockaddr *)&sin, &slen);
+ }
+ }
+
+ /* open and listenize two TCP4 suckets */
+ if ((s1 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1)
+ err(1, "socket 1");
+ if ((s2 = rump_sys_socket(PF_INET, SOCK_STREAM, 0)) == -1)
+ err(1, "socket 2");
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(1234);
+
+ if (rump_sys_bind(s1, (struct sockaddr *)&sin, sizeof(sin)) == -1)
+ err(1, "bind1");
+ sin.sin_port = htons(2345);
+ if (rump_sys_bind(s2, (struct sockaddr *)&sin, sizeof(sin)) == -1)
+ err(1, "bind2");
+
+ if (rump_sys_listen(s1, 1) == -1)
+ err(1, "listen1");
+ if (rump_sys_listen(s2, 1) == -1)
+ err(1, "listen2");
+
+ if (argc == 1) {
+ rumpclient_daemon(0, 0);
+ slen = sizeof(sin);
+ /*
+ * "pause()", but conveniently gets rid of this helper
+ * since we were called with RUMPCLIENT_RETRYCONN_DIE set
+ */
+ rump_sys_accept(s2, (struct sockaddr *)&sin, &slen);
+ }
+
+ if (argc == 3 && strcmp(argv[2], "cloexec1") == 0) {
+ if (rump_sys_fcntl(s1, F_SETFD, FD_CLOEXEC) == -1) {
+ err(1, "cloexec failed");
+ }
+ }
+
+ sprintf(buf, "%d", s2);
+
+ if (argc == 3 && strcmp(argv[2], "vfork_please") == 0) {
+ switch (rumpclient_vfork()) {
+ case 0:
+ ename = __UNCONST("fourchette");
+ break;
+ case -1:
+ err(1, "vfork");
+ default:
+ ename = __UNCONST("h_ution");
+ break;
+ }
+ } else {
+ ename = __UNCONST("h_ution");
+ }
+
+ /* omstart! */
+ eargv[0] = ename;
+ eargv[1] = __UNCONST("_didexec");
+ eargv[2] = buf;
+ eargv[3] = NULL;
+ if (rumpclient_exec(argv[1], __UNCONST(eargv), environ) == -1)
+ err(1, "exec");
+}
diff --git a/contrib/netbsd-tests/lib/librumpclient/h_execthr.c b/contrib/netbsd-tests/lib/librumpclient/h_execthr.c
new file mode 100644
index 0000000..f653fe6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumpclient/h_execthr.c
@@ -0,0 +1,187 @@
+/* $NetBSD: h_execthr.c,v 1.3 2014/08/13 00:03:00 pooka Exp $ */
+
+/*
+ * Copyright (c) 2011 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/sysctl.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <rump/rumpclient.h>
+#include <rump/rump_syscalls.h>
+
+static int canreturn = 0;
+
+/*
+ * Use a fairly large number of threads so that we have
+ * a better chance catching races. XXX: this is rumpuser's
+ * MAXWORKER-1.
+ */
+#define NTHR 63
+
+#define P1_0 3
+#define P1_1 4
+#define P2_0 5
+#define P2_1 6
+
+static void *
+wrk(void *arg)
+{
+ int fd = (uintptr_t)arg;
+
+ rump_sys_read(fd, &fd, sizeof(fd));
+ if (!canreturn)
+ errx(1, "should not have returned");
+ if (fd != 37)
+ errx(1, "got invalid magic");
+
+ return NULL;
+}
+
+static int
+getproc(pid_t mypid, struct kinfo_proc2 *p)
+{
+ int name[6];
+ size_t len = sizeof(*p);
+
+ name[0] = CTL_KERN;
+ name[1] = KERN_PROC2;
+ name[2] = KERN_PROC_PID;
+ name[3] = mypid;
+ name[4] = len;
+ name[5] = 1;
+
+ return rump_sys___sysctl(name, __arraycount(name), p, &len, NULL, 0);
+}
+
+int
+main(int argc, char *argv[], char *envp[])
+{
+ struct kinfo_proc2 p;
+ char *execarg[3];
+ int p1[2], p2[2];
+ pid_t mypid;
+ pthread_t pt;
+ ssize_t n;
+ int i, execd;
+ char nexec[16];
+
+ if (argc > 1)
+ execd = atoi(argv[1]);
+ else
+ execd = 0;
+ sprintf(nexec, "%d", execd+1);
+
+ if (rumpclient_init() == -1) {
+ if (execd)
+ err(1, "init execd");
+ else
+ err(1, "init");
+ }
+ mypid = rump_sys_getpid();
+
+ if (execd) {
+ canreturn = 1;
+ if (pthread_create(&pt, NULL,
+ wrk, (void *)(uintptr_t)P2_0) != 0)
+ errx(1, "exec pthread_create");
+
+ i = 37;
+ rump_sys_write(P2_1, &i, sizeof(i));
+ pthread_join(pt, NULL);
+
+ n = rump_sys_read(P1_0, &i, sizeof(i));
+ if (n != -1 || errno != EBADF)
+ errx(1, "post-exec cloexec works");
+
+ getproc(mypid, &p);
+ if (p.p_nlwps != 2)
+ errx(1, "invalid nlwps: %lld", (long long)p.p_nlwps);
+
+ /* we passed? */
+ if (execd > 10)
+ exit(0);
+
+ rump_sys_close(P2_0);
+ rump_sys_close(P2_1);
+ }
+
+ if (rump_sys_pipe(p1) == -1)
+ err(1, "pipe1");
+ if (p1[0] != P1_0 || p1[1] != P1_1)
+ errx(1, "p1 assumptions failed %d %d", p1[0], p1[1]);
+ if (rump_sys_pipe(p2) == -1)
+ err(1, "pipe1");
+ if (p2[0] != P2_0 || p2[1] != P2_1)
+ errx(1, "p2 assumptions failed");
+ if (rump_sys_fcntl(p1[0], F_SETFD, FD_CLOEXEC) == -1)
+ err(1, "cloexec");
+ if (rump_sys_fcntl(p1[1], F_SETFD, FD_CLOEXEC) == -1)
+ err(1, "cloexec");
+
+ for (i = 0; i < NTHR; i++)
+ if (pthread_create(&pt, NULL,
+ wrk, (void *)(uintptr_t)p1[0]) != 0)
+ errx(1, "pthread_create 1 %d", i);
+
+ for (i = 0; i < NTHR; i++)
+ if (pthread_create(&pt, NULL,
+ wrk, (void *)(uintptr_t)p2[0]) != 0)
+ errx(1, "pthread_create 2 %d", i);
+
+ /* wait for all the threads to be enjoying themselves */
+ for (;;) {
+ getproc(mypid, &p);
+ if (p.p_nlwps == 2*NTHR + 2)
+ break;
+ usleep(10000);
+ }
+
+ /*
+ * load up one more (big) set. these won't start executing, though,
+ * but we're interested in if they create blockage
+ */
+ for (i = 0; i < 3*NTHR; i++)
+ if (pthread_create(&pt, NULL,
+ wrk, (void *)(uintptr_t)p1[0]) != 0)
+ errx(1, "pthread_create 1 %d", i);
+
+ /* then, we exec! */
+ execarg[0] = argv[0];
+ execarg[1] = nexec;
+ execarg[2] = NULL;
+ if (rumpclient_exec(argv[0], execarg, envp) == -1)
+ err(1, "exec");
+}
diff --git a/contrib/netbsd-tests/lib/librumpclient/t_exec.sh b/contrib/netbsd-tests/lib/librumpclient/t_exec.sh
new file mode 100755
index 0000000..661a3b9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumpclient/t_exec.sh
@@ -0,0 +1,154 @@
+# $NetBSD: t_exec.sh,v 1.8 2011/03/08 12:40:25 pooka Exp $
+#
+# Copyright (c) 2011 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.
+#
+
+rumpsrv='rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet'
+export RUMP_SERVER=unix://csock
+export RUMPHIJACK_RETRYCONNECT='die'
+
+atf_test_case noexec cleanup
+noexec_head()
+{
+ atf_set "descr" "check that we see what we expect without exec"
+}
+
+noexec_body()
+{
+
+ atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER}
+ atf_check -s exit:0 env $(atf_get_srcdir)/h_exec
+ atf_check -s exit:0 -o save:sstat.out rump.sockstat -n
+ atf_check -s exit:0 -o match:'^root.*h_exec.*tcp.*\*\.1234' \
+ sed -n 2p sstat.out
+ atf_check -s exit:0 -o match:'^root.*h_exec.*tcp.*\*\.2345' \
+ sed -n 3p sstat.out
+}
+
+noexec_cleanup()
+{
+ rump.halt
+}
+
+atf_test_case exec cleanup
+exec_head()
+{
+ atf_set "descr" "check that client names changes after exec"
+}
+
+exec_body()
+{
+
+ atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER}
+ atf_check -s exit:0 $(atf_get_srcdir)/h_exec $(atf_get_srcdir)/h_exec
+ atf_check -s exit:0 -o save:sstat.out rump.sockstat -n
+ atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.1234' \
+ sed -n 2p sstat.out
+ atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.2345' \
+ sed -n 3p sstat.out
+}
+
+exec_cleanup()
+{
+ rump.halt
+}
+
+atf_test_case cloexec cleanup
+cloexec_head()
+{
+ atf_set "descr" "check that FD_CLOEXEC works"
+}
+
+cloexec_body()
+{
+
+ atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER}
+ atf_check -s exit:0 \
+ $(atf_get_srcdir)/h_exec $(atf_get_srcdir)/h_exec cloexec1
+ atf_check -s exit:0 -o save:sstat.out rump.sockstat -n
+ atf_check -s exit:0 -o inline:'2\n' sed -n '$=' sstat.out
+ atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.2345' \
+ sed -n 2p sstat.out
+}
+
+cloexec_cleanup()
+{
+ rump.halt
+}
+
+atf_test_case vfork cleanup
+vfork_head()
+{
+ atf_set "descr" "test rumpclient_vfork()"
+}
+
+vfork_body()
+{
+
+ atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER}
+ atf_check -s exit:0 \
+ $(atf_get_srcdir)/h_exec $(atf_get_srcdir)/h_exec vfork_please
+ atf_check -s exit:0 -o save:sstat.out rump.sockstat -n
+ atf_check -s exit:0 -o inline:'5\n' sed -n '$=' sstat.out
+ atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.1234' \
+ cat sstat.out
+ atf_check -s exit:0 -o match:'^root.*h_ution.*tcp.*\*\.2345' \
+ cat sstat.out
+ atf_check -s exit:0 -o match:'^root.*fourchette.*tcp.*\*\.1234' \
+ cat sstat.out
+ atf_check -s exit:0 -o match:'^root.*fourchette.*tcp.*\*\.2345' \
+ cat sstat.out
+}
+
+vfork_cleanup()
+{
+ rump.halt
+}
+
+atf_test_case threxec cleanup
+threxec_head()
+{
+ atf_set "descr" "check that threads are killed before exec continues"
+}
+
+threxec_body()
+{
+ atf_check -s exit:0 rump_server ${RUMP_SERVER}
+ atf_check -s exit:0 $(atf_get_srcdir)/h_execthr
+}
+
+threxec_cleanup()
+{
+ rump.halt
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case noexec
+ atf_add_test_case exec
+ atf_add_test_case cloexec
+ atf_add_test_case vfork
+ atf_add_test_case threxec
+}
diff --git a/contrib/netbsd-tests/lib/librumpclient/t_fd.c b/contrib/netbsd-tests/lib/librumpclient/t_fd.c
new file mode 100644
index 0000000..aa0d1cc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumpclient/t_fd.c
@@ -0,0 +1,146 @@
+/* $NetBSD: t_fd.c,v 1.4 2011/08/25 18:46:01 hannken Exp $ */
+
+/*
+ * Copyright (c) 2011 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/stat.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <rump/rumpclient.h>
+#include <rump/rump_syscalls.h>
+
+#include "../../h_macros.h"
+
+ATF_TC_WITH_CLEANUP(bigenough);
+ATF_TC_HEAD(bigenough, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check that rumpclient uses "
+ "fd > 2");
+}
+ATF_TC_WITH_CLEANUP(sigio);
+ATF_TC_HEAD(sigio, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check that rump client receives "
+ "SIGIO");
+}
+
+#define RUMPSERV "unix://sucket"
+
+ATF_TC_CLEANUP(bigenough, tc){system("env RUMP_SERVER=" RUMPSERV " rump.halt");}
+ATF_TC_CLEANUP(sigio, tc) { system("env RUMP_SERVER=" RUMPSERV " rump.halt"); }
+
+ATF_TC_BODY(bigenough, tc)
+{
+ struct stat sb;
+
+ RZ(system("rump_server " RUMPSERV));
+ RL(setenv("RUMP_SERVER", RUMPSERV, 1));
+
+ RL(dup2(0, 10));
+ RL(dup2(1, 11));
+ RL(dup2(2, 12));
+
+ RL(close(0));
+ RL(close(1));
+ RL(close(2));
+
+ RL(rumpclient_init());
+ RL(rump_sys_getpid());
+
+ ATF_REQUIRE_ERRNO(EBADF, fstat(0, &sb) == -1);
+ ATF_REQUIRE_ERRNO(EBADF, fstat(1, &sb) == -1);
+ ATF_REQUIRE_ERRNO(EBADF, fstat(2, &sb) == -1);
+
+ RL(rump_sys_getpid());
+
+ /* restore these. does it help? */
+ dup2(10, 0);
+ dup2(11, 1);
+ dup2(12, 2);
+}
+
+static volatile sig_atomic_t sigcnt;
+static void
+gotsig(int sig)
+{
+
+ sigcnt++;
+}
+
+ATF_TC_BODY(sigio, tc)
+{
+ struct sockaddr_in sin;
+ int ls;
+ int cs;
+ int fl;
+ int sc;
+
+ signal(SIGIO, gotsig);
+ RZ(system("rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet "
+ RUMPSERV));
+ RL(setenv("RUMP_SERVER", RUMPSERV, 1));
+
+ RL(rumpclient_init());
+ RL(ls = rump_sys_socket(PF_INET, SOCK_STREAM, 0));
+
+ RL(rump_sys_fcntl(ls, F_SETOWN, rump_sys_getpid()));
+ RL(fl = rump_sys_fcntl(ls, F_GETFL));
+ RL(rump_sys_fcntl(ls, F_SETFL, fl | O_ASYNC));
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(12345);
+ RL(rump_sys_bind(ls, (struct sockaddr *)&sin, sizeof(sin)));
+ RL(rump_sys_listen(ls, 5));
+
+ RL(cs = rump_sys_socket(PF_INET, SOCK_STREAM, 0));
+ sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ ATF_REQUIRE_EQ(sigcnt, 0);
+ RL(rump_sys_connect(cs, (struct sockaddr *)&sin, sizeof(sin)));
+ sc = sigcnt;
+ printf("sigcnt after connect: %d\n", sc);
+ ATF_REQUIRE(sc >= 1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, bigenough);
+ ATF_TP_ADD_TC(tp, sigio);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/librumphijack/h_client.c b/contrib/netbsd-tests/lib/librumphijack/h_client.c
new file mode 100644
index 0000000..20add73
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/h_client.c
@@ -0,0 +1,138 @@
+/* $NetBSD: h_client.c,v 1.8 2012/04/20 05:15:11 jruoho Exp $ */
+
+/*
+ * Copyright (c) 2011 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/poll.h>
+#include <sys/select.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int
+main(int argc, char *argv[])
+{
+
+ if (argc != 2) {
+ errx(1, "need testname as param");
+ }
+
+ if (strcmp(argv[1], "select_timeout") == 0) {
+ fd_set rfds;
+ struct timeval tv;
+ int pipefd[2];
+ int rv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 1;
+
+ if (pipe(pipefd) == -1)
+ err(EXIT_FAILURE, "pipe");
+ FD_ZERO(&rfds);
+ FD_SET(pipefd[0], &rfds);
+
+ rv = select(pipefd[0]+1, &rfds, NULL, NULL, &tv);
+ if (rv == -1)
+ err(EXIT_FAILURE, "select");
+ if (rv != 0)
+ errx(EXIT_FAILURE, "select succesful");
+
+ if (FD_ISSET(pipefd[0], &rfds))
+ errx(EXIT_FAILURE, "stdin fileno is still set");
+ return EXIT_SUCCESS;
+ } else if (strcmp(argv[1], "select_allunset") == 0) {
+ fd_set fds;
+ struct timeval tv;
+ int rv;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 1;
+
+ FD_ZERO(&fds);
+
+ rv = select(100, &fds, &fds, &fds, &tv);
+ if (rv == -1)
+ err(EXIT_FAILURE, "select");
+ if (rv != 0)
+ errx(EXIT_FAILURE, "select succesful");
+
+ rv = select(0, NULL, NULL, NULL, &tv);
+ if (rv == -1)
+ err(EXIT_FAILURE, "select2");
+ if (rv != 0)
+ errx(EXIT_FAILURE, "select2 succesful");
+
+ return EXIT_SUCCESS;
+ } else if (strcmp(argv[1], "invafd") == 0) {
+ struct pollfd pfd[2];
+ int fd, rv;
+
+ fd = open("/rump/dev/null", O_RDWR);
+ if (fd == -1)
+ err(EXIT_FAILURE, "open");
+ close(fd);
+
+ pfd[0].fd = STDIN_FILENO;
+ pfd[0].events = POLLIN;
+ pfd[1].fd = fd;
+ pfd[1].events = POLLIN;
+
+ if ((rv = poll(pfd, 2, INFTIM)) != 1)
+ errx(EXIT_FAILURE, "poll unexpected rv %d (%d)",
+ rv, errno);
+ if (pfd[1].revents != POLLNVAL || pfd[0].revents != 0)
+ errx(EXIT_FAILURE, "poll unexpected revents");
+
+ return EXIT_SUCCESS;
+ } else if (strcmp(argv[1], "fdoff8") == 0) {
+
+ (void)closefrom(0);
+
+ int fd;
+
+ do {
+ if ((fd = open("/dev/null", O_RDWR)) == -1)
+ err(EXIT_FAILURE, "open1");
+ } while (fd < 7);
+ fd = open("/dev/null", O_RDWR);
+ if (fd != -1 || errno != ENFILE)
+ errx(EXIT_FAILURE, "unexpected fd8 %d %d", fd, errno);
+ if (fcntl(0, F_MAXFD) != 7)
+ errx(EXIT_FAILURE, "fd leak?");
+ if ((fd = open("/rump/dev/null", O_RDWR)) != 8)
+ errx(EXIT_FAILURE, "rump open %d %d", fd, errno);
+ return EXIT_SUCCESS;
+ } else {
+ return ENOTSUP;
+ }
+}
diff --git a/contrib/netbsd-tests/lib/librumphijack/h_cwd.c b/contrib/netbsd-tests/lib/librumphijack/h_cwd.c
new file mode 100644
index 0000000..dfc509d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/h_cwd.c
@@ -0,0 +1,168 @@
+/* $NetBSD: h_cwd.c,v 1.3 2012/04/17 09:23:21 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 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/stat.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char *prefix;
+static size_t prefixlen;
+static char buf[1024];
+static char pwd[1024];
+
+static const char *
+makepath(const char *tail)
+{
+
+ strcpy(buf, prefix);
+ if (prefix[prefixlen-1] != '/')
+ strcat(buf, "/");
+ strcat(buf, tail);
+
+ return buf;
+}
+
+static void
+dochdir(const char *path, const char *errmsg)
+{
+
+ if (chdir(path) == -1)
+ err(EXIT_FAILURE, "%s", errmsg);
+}
+
+static void
+dofchdir(const char *path, const char *errmsg)
+{
+ int fd;
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ err(EXIT_FAILURE, "open %s", errmsg);
+ if (fchdir(fd) == -1)
+ err(EXIT_FAILURE, "fchdir %s", errmsg);
+ close(fd);
+}
+static void (*thechdir)(const char *, const char *);
+
+static void
+simple(void)
+{
+
+ thechdir(prefix, "chdir1");
+ if (getcwd(pwd, sizeof(pwd)) == NULL)
+ err(EXIT_FAILURE, "getcwd1");
+ if (strcmp(pwd, prefix) != 0)
+ errx(EXIT_FAILURE, "strcmp1");
+
+ if (mkdir("dir", 0777) == -1)
+ err(EXIT_FAILURE, "mkdir2");
+ thechdir("dir", "chdir2");
+ if (getcwd(pwd, sizeof(pwd)) == NULL)
+ err(EXIT_FAILURE, "getcwd2");
+ if (strcmp(pwd, makepath("dir")) != 0)
+ errx(EXIT_FAILURE, "strcmp2");
+
+ if (mkdir("dir", 0777) == -1)
+ err(EXIT_FAILURE, "mkdir3");
+ thechdir("dir", "chdir3");
+ if (getcwd(pwd, sizeof(pwd)) == NULL)
+ err(EXIT_FAILURE, "getcwd3");
+ if (strcmp(pwd, makepath("dir/dir")) != 0)
+ errx(EXIT_FAILURE, "strcmp3");
+
+ thechdir("..", "chdir4");
+ if (getcwd(pwd, sizeof(pwd)) == NULL)
+ err(EXIT_FAILURE, "getcwd4");
+ if (strcmp(pwd, makepath("dir")) != 0)
+ errx(EXIT_FAILURE, "strcmp4");
+
+
+ thechdir("../../../../../../..", "chdir5");
+ if (getcwd(pwd, sizeof(pwd)) == NULL)
+ err(EXIT_FAILURE, "getcwd5");
+ if (strcmp(pwd, prefix) != 0)
+ errx(EXIT_FAILURE, "strcmp5");
+
+ thechdir("/", "chdir6");
+ if (getcwd(pwd, sizeof(pwd)) == NULL)
+ err(EXIT_FAILURE, "getcwd6");
+ if (strcmp(pwd, "/") != 0)
+ errx(EXIT_FAILURE, "strcmp6");
+}
+
+static void
+symlinktest(void)
+{
+
+ thechdir(prefix, "chdir1");
+ if (mkdir("adir", 0777) == -1)
+ err(EXIT_FAILURE, "mkdir1");
+ if (mkdir("anotherdir", 0777) == -1)
+ err(EXIT_FAILURE, "mkdir2");
+
+ if (symlink("/adir", "anotherdir/lincthesink") == -1)
+ err(EXIT_FAILURE, "symlink");
+
+ thechdir("anotherdir/lincthesink", "chdir2");
+ if (getcwd(pwd, sizeof(pwd)) == NULL)
+ err(EXIT_FAILURE, "getcwd");
+ if (strcmp(pwd, makepath("adir")) != 0)
+ errx(EXIT_FAILURE, "strcmp");
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ if (argc != 4)
+ errx(1, "usage");
+
+ prefix = argv[1];
+ prefixlen = strlen(argv[1]);
+
+ if (strcmp(argv[3], "chdir") == 0)
+ thechdir = dochdir;
+ else if (strcmp(argv[3], "fchdir") == 0)
+ thechdir = dofchdir;
+ else
+ errx(EXIT_FAILURE, "invalid chdir type");
+
+ if (strcmp(argv[2], "simple") == 0)
+ simple();
+ if (strcmp(argv[2], "symlink") == 0)
+ symlinktest();
+
+ return EXIT_SUCCESS;
+}
diff --git a/contrib/netbsd-tests/lib/librumphijack/h_netget.c b/contrib/netbsd-tests/lib/librumphijack/h_netget.c
new file mode 100644
index 0000000..4d8b408
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/h_netget.c
@@ -0,0 +1,101 @@
+/* $NetBSD: h_netget.c,v 1.2 2012/04/17 09:23:21 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 Antti Kantee. 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 AUTHOR ``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 AUTHOR 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.
+ */
+
+/*
+ * simple utility to fetch a webpage. we wouldn't need this
+ * if we had something like netcat in base
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: h_netget.c,v 1.2 2012/04/17 09:23:21 jruoho Exp $");
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <arpa/inet.h>
+
+#include <netinet/in.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define GETSTR "GET / HTTP/1.0\n\n"
+
+int
+main(int argc, char *argv[])
+{
+ char buf[8192];
+ struct sockaddr_in sin;
+ ssize_t n;
+ int s, fd;
+
+ setprogname(argv[0]);
+ if (argc != 4) {
+ fprintf(stderr, "usage: %s address port savefile\n",
+ getprogname());
+ return EXIT_FAILURE;
+ }
+
+ s = socket(PF_INET, SOCK_STREAM, 0);
+ if (s == -1)
+ err(EXIT_FAILURE, "socket");
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(atoi(argv[2]));
+ sin.sin_addr.s_addr = inet_addr(argv[1]);
+
+ fd = open(argv[3], O_CREAT | O_RDWR, 0644);
+ if (fd == -1)
+ err(EXIT_FAILURE, "open");
+ if (ftruncate(fd, 0) == -1)
+ err(EXIT_FAILURE, "ftruncate savefile");
+
+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
+ err(EXIT_FAILURE, "connect");
+
+ if (write(s, GETSTR, strlen(GETSTR)) != strlen(GETSTR))
+ err(EXIT_FAILURE, "socket write");
+
+ for (;;) {
+ n = read(s, buf, sizeof(buf));
+ if (n == 0)
+ break;
+ if (n == -1)
+ err(EXIT_FAILURE, "socket read");
+
+ if (write(fd, buf, n) != n)
+ err(EXIT_FAILURE, "write file");
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/contrib/netbsd-tests/lib/librumphijack/index.html b/contrib/netbsd-tests/lib/librumphijack/index.html
new file mode 100644
index 0000000..1d8679c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/index.html
@@ -0,0 +1,5 @@
+<html><head>
+<title>test page</title>
+</head><body>
+i am a test, how do you do?
+</body></html>
diff --git a/contrib/netbsd-tests/lib/librumphijack/netstat.expout b/contrib/netbsd-tests/lib/librumphijack/netstat.expout
new file mode 100644
index 0000000..1a9a2a1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/netstat.expout
@@ -0,0 +1,6 @@
+Active Internet connections (including servers)
+Proto Recv-Q Send-Q Local Address Foreign Address State
+tcp 0 0 *.http *.* LISTEN
+Active Internet6 connections (including servers)
+Proto Recv-Q Send-Q Local Address Foreign Address (state)
+tcp6 0 0 *.http *.* LISTEN
diff --git a/contrib/netbsd-tests/lib/librumphijack/ssh_config.in b/contrib/netbsd-tests/lib/librumphijack/ssh_config.in
new file mode 100644
index 0000000..73b83c8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/ssh_config.in
@@ -0,0 +1,14 @@
+# $NetBSD: ssh_config.in,v 1.1 2011/02/14 15:14:00 pooka Exp $
+
+# Basic settings.
+Port 22
+Protocol 2
+
+# The temporary key used for login.
+IdentityFile @WORKDIR@/ssh_user_key
+
+# Prevent the client from complaining about unknown host keys.
+GlobalKnownHostsFile @WORKDIR@/known_hosts
+
+# Do not attempt password authentication in case keys fail.
+IdentitiesOnly yes
diff --git a/contrib/netbsd-tests/lib/librumphijack/ssh_host_key b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key
new file mode 100644
index 0000000..ebdbc8b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICWwIBAAKBgQDJnMpSG1lGmApk8F7ZH7TGtjjP/WUs+vqHyFsyS2lilJzereen
+a/ME6S0d0HTOeCdKldjbtDpfNXbh+XnJMlJMEgEs4Mg1jluuEV0GOJoMt7cGzku2
+gAYGx++2+wqYw6Y+M8Tb1M4AO+PcxD/3BkdUyIKO63v6STl2VQn1BzsTQwIBIwKB
+gAuFTWPHDGpvFols0jhK9GMgWwSSIwnidLdNRwowMehgQ3pwVmFWoCwqlN0h2sn4
+PMJu9nL0WxtiJAzprzARgQuPI25t9LiKTF7scC/cNUiHPplUjvoDXA9ccY1eIf4R
+e6wwZz1jfCWen0eRsvMyoYvFmEH8hILAk1bY9heymOGLAkEA/WhC49n+gtloVMow
+iKQOO6+u3ouxTOTQ3sV2wCaLaO2pEbHP2//5SlUJLp6QrjC7bg9Kr+f56+zT2he9
+f6GCwwJBAMus3XizmZdJyJLnkCJRiT0/3Kf57fhWKRdnFkuRLyjET9MEWavRdJmr
+bx/lxmILi1iKwXiFEDM6MqYfmNImJYECQQCtw9YYlXtSaTGZOi/oqwJyEhGCqO6b
+II85q/moVPHhjQY4BOZNttbT4on0FPV+wlSjPa+OkHDcSp/mAaaDZ2+bAkEAujel
+6rLVkaKLfv+ZuPoXE22WivMityo0Mqdk12ArHfVQS+a4YpOdzlOYzLTSosi56o19
+sAShGOTAl+Jf1hQ/iwJAKpPviX5w292H/m5T0m4l0NRdQ3pRujOLMSVmY+/HFZTW
+GJMYLr1eBKNfLsKzJgB88GzuF2O/O8hNi3XSiOP+9w==
+-----END RSA PRIVATE KEY-----
diff --git a/contrib/netbsd-tests/lib/librumphijack/ssh_host_key.pub b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key.pub
new file mode 100644
index 0000000..8d08795
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/ssh_host_key.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAyZzKUhtZRpgKZPBe2R+0xrY4z/1lLPr6h8hbMktpYpSc3q3np2vzBOktHdB0zngnSpXY27Q6XzV24fl5yTJSTBIBLODINY5brhFdBjiaDLe3Bs5LtoAGBsfvtvsKmMOmPjPE29TOADvj3MQ/9wZHVMiCjut7+kk5dlUJ9Qc7E0M= test@test.example.net
diff --git a/contrib/netbsd-tests/lib/librumphijack/sshd_config.in b/contrib/netbsd-tests/lib/librumphijack/sshd_config.in
new file mode 100644
index 0000000..9ffc47f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/sshd_config.in
@@ -0,0 +1,39 @@
+# $NetBSD: sshd_config.in,v 1.1 2011/02/14 15:14:00 pooka Exp $
+
+# Basic settings.
+Port 22
+Protocol 2
+
+# Provide information to the user in case something goes wrong.
+LogLevel DEBUG1
+
+# The host key. It lives in the work directory because we need to set
+# very strict permissions on it and cannot modify the copy on the source
+# directory.
+HostKey @WORKDIR@/ssh_host_key
+
+# The authorized keys file we set up during the test to allow the client
+# to safely log in. We need to disable strict modes because ATF_WORKDIR
+# usually lives in /tmp, which has 1777 permissions and are not liked by
+# sshd.
+AuthorizedKeysFile @WORKDIR@/authorized_keys
+StrictModes no
+
+# Some settings to allow user runs of sshd.
+PidFile @WORKDIR@/sshd.pid
+UsePam no
+UsePrivilegeSeparation no
+
+# The root user should also be able to run the tests.
+PermitRootLogin yes
+
+# Be restrictive about access to the temporary server. Only allow key-based
+# authentication.
+ChallengeResponseAuthentication no
+GSSAPIAuthentication no
+HostbasedAuthentication no
+KerberosAuthentication no
+MaxAuthTries 1
+MaxStartups 1
+PasswordAuthentication no
+PubkeyAuthentication yes
diff --git a/contrib/netbsd-tests/lib/librumphijack/t_asyncio.sh b/contrib/netbsd-tests/lib/librumphijack/t_asyncio.sh
new file mode 100755
index 0000000..d5d703c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/t_asyncio.sh
@@ -0,0 +1,94 @@
+# $NetBSD: t_asyncio.sh,v 1.4 2014/08/27 13:32:16 gson Exp $
+#
+# Copyright (c) 2011 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.
+#
+
+rumpsrv='rump_server'
+export RUMP_SERVER=unix://csock
+
+atf_test_case select_timeout cleanup
+select_timeout_head()
+{
+ atf_set "descr" "select() with timeout returns no fds set"
+}
+
+select_timeout_body()
+{
+
+ atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER}
+ atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
+ $(atf_get_srcdir)/h_client select_timeout
+}
+
+select_timeout_cleanup()
+{
+ rump.halt
+}
+
+atf_test_case select_allunset cleanup
+select_allunset_head()
+{
+ atf_set "descr" "select() with no set fds in fd_set should not crash"
+}
+
+select_allunset_body()
+{
+
+ atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER}
+ atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
+ $(atf_get_srcdir)/h_client select_allunset
+}
+
+select_allunset_cleanup()
+{
+ rump.halt
+}
+
+atf_test_case invafd cleanup
+invafd_head()
+{
+ atf_set "descr" "poll on invalid rump fd"
+ atf_set "timeout" "10"
+}
+
+invafd_body()
+{
+
+ atf_check -s exit:0 rump_server -lrumpvfs ${RUMP_SERVER}
+ atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
+ $(atf_get_srcdir)/h_client invafd
+}
+
+invafd_cleanup()
+{
+ rump.halt
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case select_timeout
+ atf_add_test_case select_allunset
+ atf_add_test_case invafd
+}
diff --git a/contrib/netbsd-tests/lib/librumphijack/t_config.sh b/contrib/netbsd-tests/lib/librumphijack/t_config.sh
new file mode 100755
index 0000000..014bb0f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/t_config.sh
@@ -0,0 +1,54 @@
+# $NetBSD: t_config.sh,v 1.1 2011/03/14 15:56:40 pooka Exp $
+#
+# Copyright (c) 2011 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.
+#
+
+rumpsrv='rump_server -lrumpvfs'
+export RUMP_SERVER=unix://csock
+
+atf_test_case fdoff cleanup
+fdoff_head()
+{
+ atf_set "descr" "RUMPHIJACK fdoff=8"
+}
+
+fdoff_body()
+{
+
+ atf_check -s exit:0 rump_server -lrumpvfs ${RUMP_SERVER}
+ export RUMPHIJACK=path=/rump,fdoff=8
+ atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
+ $(atf_get_srcdir)/h_client fdoff8
+}
+
+fdoff_cleanup()
+{
+ rump.halt
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case fdoff
+}
diff --git a/contrib/netbsd-tests/lib/librumphijack/t_cwd.sh b/contrib/netbsd-tests/lib/librumphijack/t_cwd.sh
new file mode 100755
index 0000000..3f2a50b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/t_cwd.sh
@@ -0,0 +1,72 @@
+# $NetBSD: t_cwd.sh,v 1.2 2011/02/19 19:57:28 pooka Exp $
+#
+# Copyright (c) 2011 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.
+#
+
+rumpsrv='rump_server -lrumpvfs'
+export RUMP_SERVER=unix://csock
+
+test_case()
+{
+ local name="${1}"; shift
+
+ atf_test_case "${name}" cleanup
+ eval "${name}_head() { }"
+ eval "${name}_body() { \
+ export RUMPHIJACK="path=${1}" ; \
+ atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER} ; \
+ testbody " "${@}" "; \
+ }"
+ eval "${name}_cleanup() { \
+ rump.halt
+ }"
+}
+
+test_case basic_chdir /rump simple chdir
+test_case basic_fchdir /rump simple fchdir
+test_case slash_chdir // simple chdir
+test_case slash_fchdir // simple fchdir
+test_case symlink_chdir /rump symlink chdir
+test_case symlink_fchdir /rump symlink fchdir
+test_case symlink_slash_chdir // symlink chdir
+test_case symlink_slash_fchdir // symlink fchdir
+
+testbody()
+{
+ atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
+ $(atf_get_srcdir)/h_cwd $*
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case basic_chdir
+ atf_add_test_case basic_fchdir
+ atf_add_test_case slash_chdir
+ atf_add_test_case slash_fchdir
+ atf_add_test_case symlink_chdir
+ atf_add_test_case symlink_fchdir
+ atf_add_test_case symlink_slash_chdir
+ atf_add_test_case symlink_slash_fchdir
+}
diff --git a/contrib/netbsd-tests/lib/librumphijack/t_sh.sh b/contrib/netbsd-tests/lib/librumphijack/t_sh.sh
new file mode 100755
index 0000000..c01c729
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/t_sh.sh
@@ -0,0 +1,91 @@
+# $NetBSD: t_sh.sh,v 1.1 2011/03/03 11:54:12 pooka Exp $
+#
+# Copyright (c) 2011 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.
+#
+
+#
+# Test various /bin/sh descriptor games.
+#
+# Note that there is an extra level of trickery here, since
+# we need to run an extra level of shell to "catch" LD_PRELOAD.
+#
+
+rumpsrv='rump_server -lrumpvfs'
+export RUMP_SERVER=unix://csock
+exout="this is the output you are looking for"
+
+atf_test_case runscript cleanup
+runscript_head()
+{
+ atf_set "descr" "can run /bin/sh scripts from rumpfs"
+}
+
+runscript_body()
+{
+ atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER}
+
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+ echo "echo $exout" > thescript
+ atf_check -s exit:0 mv thescript /rump
+ atf_check -s exit:0 -o inline:"${exout}\n" -x sh /rump/thescript
+}
+
+runscript_cleanup()
+{
+ rump.halt
+}
+
+atf_test_case redirect cleanup
+redirect_head()
+{
+ atf_set "descr" "input/output redirection works with rumphijack"
+}
+
+redirect_body()
+{
+ atf_check -s exit:0 ${rumpsrv} ${RUMP_SERVER}
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+
+ echo "echo $exout > /rump/thefile" > thescript
+ atf_check -s exit:0 -x sh thescript
+
+ # read it without input redirection
+ atf_check -s exit:0 -o inline:"${exout}\n" cat /rump/thefile
+
+ # read it with input redirection (note, need an exec'd shell again)
+ echo "cat < /rump/thefile" > thescript
+ atf_check -s exit:0 -o inline:"${exout}\n" -x sh thescript
+}
+
+redirect_cleanup()
+{
+ rump.halt
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case runscript
+ atf_add_test_case redirect
+}
diff --git a/contrib/netbsd-tests/lib/librumphijack/t_tcpip.sh b/contrib/netbsd-tests/lib/librumphijack/t_tcpip.sh
new file mode 100755
index 0000000..d6a16fa
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/t_tcpip.sh
@@ -0,0 +1,268 @@
+# $NetBSD: t_tcpip.sh,v 1.13 2014/01/03 13:18:00 pooka Exp $
+#
+# Copyright (c) 2011 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.
+#
+
+rumpnetsrv='rump_server -lrumpnet -lrumpnet_net -lrumpnet_netinet'
+export RUMP_SERVER=unix://csock
+
+atf_test_case http cleanup
+http_head()
+{
+ atf_set "descr" "Start hijacked httpd and get webpage from it"
+}
+
+http_body()
+{
+
+ atf_check -s exit:0 ${rumpnetsrv} -lrumpnet_netinet6 ${RUMP_SERVER}
+
+ # start bozo in daemon mode
+ atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
+ /usr/libexec/httpd -P ./httpd.pid -b -s $(atf_get_srcdir)
+
+ atf_check -s exit:0 -o file:"$(atf_get_srcdir)/netstat.expout" \
+ rump.netstat -a
+
+ # get the webpage
+ atf_check -s exit:0 env LD_PRELOAD=/usr/lib/librumphijack.so \
+ $(atf_get_srcdir)/h_netget 127.0.0.1 80 webfile
+
+ # check that we got what we wanted
+ atf_check -o match:'HTTP/1.0 200 OK' cat webfile
+ atf_check -o match:'Content-Length: 95' cat webfile
+ atf_check -o file:"$(atf_get_srcdir)/index.html" \
+ sed -n '1,/^$/!p' webfile
+}
+
+http_cleanup()
+{
+ if [ -f httpd.pid ]; then
+ kill -9 "$(cat httpd.pid)"
+ rm -f httpd.pid
+ fi
+
+ rump.halt
+}
+
+#
+# Starts a SSH server and sets up the client to access it.
+# Authentication is allowed and done using an RSA key exclusively, which
+# is generated on the fly as part of the test case.
+# XXX: Ideally, all the tests in this test program should be able to share
+# the generated key, because creating it can be a very slow process on some
+# machines.
+#
+# XXX2: copypasted from jmmv's sshd thingamob in the psshfs test.
+# ideally code (and keys, like jmmv notes above) could be shared
+#
+start_sshd() {
+ echo "Setting up SSH server configuration"
+ sed -e "s,@SRCDIR@,$(atf_get_srcdir),g" -e "s,@WORKDIR@,$(pwd),g" \
+ $(atf_get_srcdir)/sshd_config.in >sshd_config || \
+ atf_fail "Failed to create sshd_config"
+ atf_check -s ignore -o empty -e ignore \
+ cp $(atf_get_srcdir)/ssh_host_key .
+ atf_check -s ignore -o empty -e ignore \
+ cp $(atf_get_srcdir)/ssh_host_key.pub .
+ atf_check -s eq:0 -o empty -e empty chmod 400 ssh_host_key
+ atf_check -s eq:0 -o empty -e empty chmod 444 ssh_host_key.pub
+
+ env LD_PRELOAD=/usr/lib/librumphijack.so \
+ /usr/sbin/sshd -e -f ./sshd_config
+ while [ ! -f sshd.pid ]; do
+ sleep 0.01
+ done
+ echo "SSH server started (pid $(cat sshd.pid))"
+
+ echo "Setting up SSH client configuration"
+ atf_check -s eq:0 -o empty -e empty \
+ ssh-keygen -f ssh_user_key -t rsa -b 1024 -N "" -q
+ atf_check -s eq:0 -o empty -e empty \
+ cp ssh_user_key.pub authorized_keys
+ echo "127.0.0.1,localhost,::1 " \
+ "$(cat $(atf_get_srcdir)/ssh_host_key.pub)" >known_hosts || \
+ atf_fail "Failed to create known_hosts"
+ atf_check -s eq:0 -o empty -e empty chmod 600 authorized_keys
+ sed -e "s,@SRCDIR@,$(atf_get_srcdir),g" -e "s,@WORKDIR@,$(pwd),g" \
+ $(atf_get_srcdir)/ssh_config.in >ssh_config || \
+ atf_fail "Failed to create ssh_config"
+
+ echo "sshd running"
+}
+
+atf_test_case ssh cleanup
+ssh_head()
+{
+ atf_set "descr" "Test that hijacked ssh/sshd works"
+}
+
+ssh_body()
+{
+
+ atf_check -s exit:0 ${rumpnetsrv} ${RUMP_SERVER}
+ # make sure clients die after we nuke the server
+ export RUMPHIJACK_RETRYCONNECT='die'
+
+ start_sshd
+
+ # create some sort of directory for us to "ls"
+ mkdir testdir
+ cd testdir
+ jot 11 | xargs touch
+ jot 11 12 | xargs mkdir
+ cd ..
+
+ atf_check -s exit:0 -o save:ssh.out \
+ env LD_PRELOAD=/usr/lib/librumphijack.so \
+ ssh -T -F ssh_config 127.0.0.1 env BLOCKSIZE=512 \
+ ls -li $(pwd)/testdir
+ atf_check -s exit:0 -o file:ssh.out env BLOCKSIZE=512 \
+ ls -li $(pwd)/testdir
+}
+
+ssh_cleanup()
+{
+ rump.halt
+ # sshd dies due to RUMPHIJACK_RETRYCONNECT=1d6
+}
+
+test_nfs()
+{
+
+ magicstr='wind in my hair'
+ # create ffs file system we'll be serving from
+ atf_check -s exit:0 -o ignore newfs -F -s 10000 ffs.img
+
+ # start nfs kernel server. this is a mouthful
+ export RUMP_SERVER=unix://serversock
+ atf_check -s exit:0 rump_server $* ${RUMP_SERVER}
+
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 10.1.1.1
+
+ export RUMPHIJACK_RETRYCONNECT=die
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+
+ atf_check -s exit:0 mkdir -p /rump/var/run
+ atf_check -s exit:0 mkdir -p /rump/var/db
+ atf_check -s exit:0 touch /rump/var/db/mountdtab
+ atf_check -s exit:0 mkdir /rump/etc
+ atf_check -s exit:0 mkdir /rump/export
+
+ atf_check -s exit:0 -x \
+ 'echo "/export -noresvport -noresvmnt 10.1.1.100" | \
+ dd of=/rump/etc/exports 2> /dev/null'
+
+ atf_check -s exit:0 -e ignore mount_ffs /dk /rump/export
+ atf_check -s exit:0 -x "echo ${magicstr} > /rump/export/im_alive"
+
+ # start rpcbind. we want /var/run/rpcbind.sock
+ export RUMPHIJACK='blanket=/var/run,socket=all'
+ atf_check -s exit:0 rpcbind
+
+ # ok, then we want mountd in the similar fashion
+ export RUMPHIJACK='blanket=/var/run:/var/db:/export,socket=all,path=/rump,vfs=all'
+ atf_check -s exit:0 mountd /rump/etc/exports
+
+ # finally, le nfschuck
+ export RUMPHIJACK='blanket=/var/run,socket=all,vfs=all'
+ atf_check -s exit:0 nfsd
+
+ #
+ # now, time for the client server and associated madness.
+ #
+
+ export RUMP_SERVER=unix://clientsock
+ unset RUMPHIJACK
+ unset LD_PRELOAD
+
+ # at least the kernel server is easier
+ atf_check -s exit:0 rump_server -lrumpvfs -lrumpnet \
+ -lrumpnet_net -lrumpnet_netinet -lrumpnet_shmif -lrumpfs_nfs\
+ ${RUMP_SERVER}
+
+ atf_check -s exit:0 rump.ifconfig shmif0 create
+ atf_check -s exit:0 rump.ifconfig shmif0 linkstr shmbus
+ atf_check -s exit:0 rump.ifconfig shmif0 inet 10.1.1.100
+
+ export LD_PRELOAD=/usr/lib/librumphijack.so
+
+ atf_check -s exit:0 mkdir /rump/mnt
+ atf_check -s exit:0 mount_nfs 10.1.1.1:/export /rump/mnt
+
+ atf_check -s exit:0 -o inline:"${magicstr}\n" cat /rump/mnt/im_alive
+ atf_check -s exit:0 -o match:'.*im_alive$' ls -l /rump/mnt/im_alive
+}
+
+
+atf_test_case nfs cleanup
+nfs_head()
+{
+ atf_set "descr" "Test hijacked nfsd and mount_nfs"
+}
+
+nfs_body()
+{
+ test_nfs -lrumpvfs -lrumpdev -lrumpnet -lrumpnet_net \
+ -lrumpnet_netinet -lrumpnet_local -lrumpnet_shmif \
+ -lrumpdev_disk -lrumpfs_ffs -lrumpfs_nfs -lrumpfs_nfsserver \
+ -d key=/dk,hostpath=ffs.img,size=host
+}
+
+nfs_cleanup()
+{
+ RUMP_SERVER=unix://serversock rump.halt 2> /dev/null
+ RUMP_SERVER=unix://clientsock rump.halt 2> /dev/null
+ :
+}
+
+atf_test_case nfs_autoload cleanup
+nfs_autoload_head()
+{
+ atf_set "descr" "Test hijacked nfsd with autoload from /stand"
+}
+
+nfs_autoload_body()
+{
+ [ `uname -m` = "i386" ] || atf_skip "test currently valid only on i386"
+ test_nfs -lrumpvfs -lrumpdev -lrumpnet -lrumpnet_net \
+ -lrumpnet_netinet -lrumpnet_local -lrumpnet_shmif \
+ -lrumpdev_disk -d key=/dk,hostpath=ffs.img,size=host
+}
+
+nfs_autoload_cleanup()
+{
+ nfs_cleanup
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case http
+ atf_add_test_case ssh
+ atf_add_test_case nfs
+ atf_add_test_case nfs_autoload
+}
diff --git a/contrib/netbsd-tests/lib/librumphijack/t_vfs.sh b/contrib/netbsd-tests/lib/librumphijack/t_vfs.sh
new file mode 100755
index 0000000..c803e2a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librumphijack/t_vfs.sh
@@ -0,0 +1,223 @@
+# $NetBSD: t_vfs.sh,v 1.6 2012/08/04 03:56:47 riastradh Exp $
+#
+# Copyright (c) 2011 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.
+#
+
+img=ffs.img
+rumpsrv_ffs=\
+"rump_server -lrumpvfs -lrumpfs_ffs -lrumpdev_disk -d key=/img,hostpath=${img},size=host"
+export RUMP_SERVER=unix://csock
+
+domount()
+{
+
+ mntdir=$1
+ [ $# -eq 0 ] && mntdir=/rump/mnt
+ atf_check -s exit:0 -e ignore mount_ffs /img ${mntdir}
+}
+
+dounmount()
+{
+
+ atf_check -s exit:0 umount -R ${mntdir}
+}
+
+remount()
+{
+
+ dounmount
+ domount /rump/mnt2
+}
+
+simpletest()
+{
+ local name="${1}"; shift
+
+ atf_test_case "${name}" cleanup
+ eval "${name}_head() { }"
+ eval "${name}_body() { \
+ atf_check -s exit:0 rump_server -lrumpvfs ${RUMP_SERVER} ; \
+ export LD_PRELOAD=/usr/lib/librumphijack.so ; \
+ ${name} " "${@}" "; \
+ }"
+ eval "${name}_cleanup() { \
+ rump.halt
+ }"
+}
+
+test_case()
+{
+ local name="${1}"; shift
+
+ atf_test_case "${name}" cleanup
+ eval "${name}_head() { }"
+ eval "${name}_body() { \
+ atf_check -s exit:0 -o ignore newfs -F -s 20000 ${img} ; \
+ atf_check -s exit:0 ${rumpsrv_ffs} ${RUMP_SERVER} ; \
+ export LD_PRELOAD=/usr/lib/librumphijack.so ; \
+ mkdir /rump/mnt /rump/mnt2 ; \
+ domount ; \
+ ${name} " "${@}" "; \
+ dounmount ${mntdir}
+ }"
+ eval "${name}_cleanup() { \
+ rump.halt
+ }"
+}
+
+test_case paxcopy
+test_case cpcopy
+test_case mv_nox
+test_case ln_nox
+
+#
+# use rumphijack to cp/pax stuff onto an image, unmount it, remount it
+# at a different location, and check that we have an identical copy
+# (we make a local copy to avoid the minor possibility that someone
+# modifies the source dir data while the test is running)
+#
+paxcopy()
+{
+ parent=$(dirname $(atf_get_srcdir))
+ thedir=$(basename $(atf_get_srcdir))
+ atf_check -s exit:0 pax -rw -s,${parent},, $(atf_get_srcdir) .
+ atf_check -s exit:0 pax -rw ${thedir} /rump/mnt
+ remount
+ atf_check -s exit:0 diff -ru ${thedir} /rump/mnt2/${thedir}
+}
+
+cpcopy()
+{
+ thedir=$(basename $(atf_get_srcdir))
+ atf_check -s exit:0 cp -Rp $(atf_get_srcdir) .
+ atf_check -s exit:0 cp -Rp ${thedir} /rump/mnt
+ remount
+ atf_check -s exit:0 diff -ru ${thedir} /rump/mnt2/${thedir}
+}
+
+#
+# non-crosskernel mv (non-simple test since this uses rename(2)
+# which is not supported by rumpfs)
+#
+
+mv_nox()
+{
+ # stat default format sans changetime and filename
+ statstr='%d %i %Sp %l %Su %Sg %r %z \"%Sa\" \"%Sm\" \"%SB\" %k %b %#Xf'
+
+ atf_check -s exit:0 touch /rump/mnt/filename
+ atf_check -s exit:0 -o save:stat.out \
+ stat -f "${statstr}" /rump/mnt/filename
+ atf_check -s exit:0 mkdir /rump/mnt/dir
+ atf_check -s exit:0 mv /rump/mnt/filename /rump/mnt/dir/same
+ atf_check -s exit:0 -o file:stat.out \
+ stat -f "${statstr}" /rump/mnt/dir/same
+}
+
+ln_nox()
+{
+ # Omit st_nlink too, since it will increase.
+ statstr='%d %i %Sp %Su %Sg %r %z \"%Sa\" \"%Sm\" \"%SB\" %k %b %#Xf'
+
+ atf_check -s exit:0 touch /rump/mnt/filename
+ atf_check -s exit:0 -o save:stat.out \
+ stat -f "${statstr}" /rump/mnt/filename
+ atf_check -s exit:0 mkdir /rump/mnt/dir
+ atf_check -s exit:0 ln /rump/mnt/filename /rump/mnt/dir/same
+ atf_check -s exit:0 -o file:stat.out \
+ stat -f "${statstr}" /rump/mnt/filename
+ atf_check -s exit:0 -o file:stat.out \
+ stat -f "${statstr}" /rump/mnt/dir/same
+}
+
+simpletest mv_x
+simpletest ln_x
+simpletest runonprefix
+simpletest blanket
+simpletest doubleblanket
+
+#
+# do a cross-kernel mv
+#
+mv_x()
+{
+ thedir=$(basename $(atf_get_srcdir))
+ atf_check -s exit:0 cp -Rp $(atf_get_srcdir) .
+ atf_check -s exit:0 cp -Rp ${thedir} ${thedir}.2
+ atf_check -s exit:0 mv ${thedir} /rump
+ atf_check -s exit:0 diff -ru ${thedir}.2 /rump/${thedir}
+}
+
+#
+# Fail to make a cross-kernel hard link.
+#
+ln_x()
+{
+ atf_check -s exit:0 touch ./loser
+ atf_check -s not-exit:0 -e ignore ln ./loser /rump/.
+}
+
+runonprefix()
+{
+ atf_check -s exit:0 -o ignore stat /rump/dev
+ atf_check -s exit:1 -e ignore stat /rumpdev
+}
+
+blanket()
+{
+ export RUMPHIJACK='blanket=/dev,path=/rump'
+ atf_check -s exit:0 -o save:stat.out \
+ stat -f "${statstr}" /rump/dev/null
+ atf_check -s exit:0 -o file:stat.out \
+ stat -f "${statstr}" /dev/null
+}
+
+doubleblanket()
+{
+ atf_check -s exit:0 mkdir /rump/dir
+ atf_check -s exit:0 ln -s dir /rump/dirtoo
+
+ export RUMPHIJACK='blanket=/dirtoo:/dir'
+ atf_check -s exit:0 touch /dir/file
+
+ atf_check -s exit:0 -o save:stat.out \
+ stat -f "${statstr}" /dir/file
+ atf_check -s exit:0 -o file:stat.out \
+ stat -f "${statstr}" /dirtoo/file
+}
+
+atf_init_test_cases()
+{
+
+ atf_add_test_case paxcopy
+ atf_add_test_case cpcopy
+ atf_add_test_case mv_x
+ atf_add_test_case ln_x
+ atf_add_test_case mv_nox
+ atf_add_test_case ln_nox
+ atf_add_test_case runonprefix
+ atf_add_test_case blanket
+ atf_add_test_case doubleblanket
+}
diff --git a/contrib/netbsd-tests/lib/libskey/t_algorithms.c b/contrib/netbsd-tests/lib/libskey/t_algorithms.c
new file mode 100644
index 0000000..2eec278
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libskey/t_algorithms.c
@@ -0,0 +1,121 @@
+/* $NetBSD: t_algorithms.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $ */
+
+/*
+ * Copyright (c) 2000, 2008, 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 <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008, 2010\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_algorithms.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $");
+
+#include <stdio.h>
+#include <strings.h>
+#include <skey.h>
+
+#include <atf-c.h>
+
+#define H_REQUIRE(x, y) \
+ ATF_REQUIRE_MSG(strcasecmp((x), (y)) == 0, "\"%s\" != \"%s\"", (x), (y))
+
+static void
+h_check(const char *pass, const char *seed,
+ const char *algo, const char *zero,
+ const char *one, const char *nine)
+{
+ char prn[64];
+ char data[16];
+ int i;
+
+ skey_set_algorithm(algo);
+
+ keycrunch(data, seed, pass);
+ btoa8(prn, data);
+ H_REQUIRE(prn, zero);
+
+ f(data);
+ btoa8(prn, data);
+ H_REQUIRE(prn, one);
+
+ for(i = 1; i < 99; ++i)
+ f(data);
+ btoa8(prn, data);
+ H_REQUIRE(prn, nine);
+}
+
+ATF_TC(md4);
+ATF_TC_HEAD(md4, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks MD4 algorithm");
+}
+ATF_TC_BODY(md4, tc)
+{
+ h_check("This is a test.", "TeSt", "md4", "D1854218EBBB0B51",
+ "63473EF01CD0B444", "C5E612776E6C237A");
+ h_check("AbCdEfGhIjK", "alpha1", "md4", "50076F47EB1ADE4E",
+ "65D20D1949B5F7AB", "D150C82CCE6F62D1");
+ h_check("OTP's are good", "correct", "md4", "849C79D4F6F55388",
+ "8C0992FB250847B1", "3F3BF4B4145FD74B");
+}
+
+ATF_TC(md5);
+ATF_TC_HEAD(md5, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks MD5 algorithm");
+}
+ATF_TC_BODY(md5, tc)
+{
+ h_check("This is a test.", "TeSt", "md5", "9E876134D90499DD",
+ "7965E05436F5029F", "50FE1962C4965880");
+ h_check("AbCdEfGhIjK", "alpha1", "md5", "87066DD9644BF206",
+ "7CD34C1040ADD14B", "5AA37A81F212146C");
+ h_check("OTP's are good", "correct", "md5", "F205753943DE4CF9",
+ "DDCDAC956F234937", "B203E28FA525BE47");
+}
+
+ATF_TC(sha1);
+ATF_TC_HEAD(sha1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks SHA1 algorithm");
+}
+ATF_TC_BODY(sha1, tc)
+{
+ h_check("This is a test.", "TeSt", "sha1","BB9E6AE1979D8FF4",
+ "63D936639734385B", "87FEC7768B73CCF9");
+ h_check("AbCdEfGhIjK", "alpha1", "sha1","AD85F658EBE383C9",
+ "D07CE229B5CF119B", "27BC71035AAF3DC6");
+ h_check("OTP's are good", "correct", "sha1","D51F3E99BF8E6F0B",
+ "82AEB52D943774E4", "4F296A74FE1567EC");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, md4);
+ ATF_TP_ADD_TC(tp, md5);
+ ATF_TP_ADD_TC(tp, sha1);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libsljit/t_sljit.sh b/contrib/netbsd-tests/lib/libsljit/t_sljit.sh
new file mode 100755
index 0000000..50fb860
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libsljit/t_sljit.sh
@@ -0,0 +1,45 @@
+# $NetBSD: t_sljit.sh,v 1.1 2012/11/05 00:34:28 alnsn Exp $
+#
+# Copyright (c) 2012 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Alexander Nasonov.
+#
+# 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 sljit
+sljit_head() {
+
+ atf_set "descr" "Run sljit unit tests."
+}
+
+sljit_body() {
+
+ $(atf_get_srcdir)/h_sljit 2>&1 || atf_fail "check report"
+}
+
+atf_init_test_cases() {
+
+ atf_add_test_case sljit
+}
diff --git a/contrib/netbsd-tests/lib/libutil/t_efun.c b/contrib/netbsd-tests/lib/libutil/t_efun.c
new file mode 100644
index 0000000..f5187f2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libutil/t_efun.c
@@ -0,0 +1,135 @@
+/* $NetBSD: t_efun.c,v 1.3 2012/11/04 23:37:02 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * 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/cdefs.h>
+__RCSID("$NetBSD: t_efun.c,v 1.3 2012/11/04 23:37:02 christos Exp $");
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <util.h>
+
+static bool fail;
+static void handler(int, const char *, ...);
+
+static void
+handler(int ef, const char *fmt, ...)
+{
+ fail = false;
+}
+
+ATF_TC(ecalloc);
+ATF_TC_HEAD(ecalloc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of ecalloc(3)");
+}
+
+ATF_TC_BODY(ecalloc, tc)
+{
+ char *x;
+
+ fail = true;
+ x = ecalloc(-1, 1);
+
+ ATF_REQUIRE(x == NULL);
+ ATF_REQUIRE(fail != true);
+
+ fail = true;
+ x = ecalloc(SIZE_MAX, 2);
+
+ ATF_REQUIRE(x == NULL);
+ ATF_REQUIRE(fail != true);
+}
+
+ATF_TC(efopen);
+ATF_TC_HEAD(efopen, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of efopen(3)");
+}
+
+ATF_TC_BODY(efopen, tc)
+{
+ FILE *f;
+
+ fail = true;
+ f = efopen("XXX", "XXX");
+
+ ATF_REQUIRE(f == NULL);
+ ATF_REQUIRE(fail != true);
+}
+
+ATF_TC(emalloc);
+ATF_TC_HEAD(emalloc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of emalloc(3)");
+}
+
+ATF_TC_BODY(emalloc, tc)
+{
+ char *x;
+
+ fail = true;
+ x = emalloc(-1);
+
+ ATF_REQUIRE(x == NULL);
+ ATF_REQUIRE(fail != true);
+}
+
+ATF_TC(erealloc);
+ATF_TC_HEAD(erealloc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of erealloc(3)");
+}
+
+ATF_TC_BODY(erealloc, tc)
+{
+ char *x;
+
+ fail = true;
+ x = erealloc(NULL, -1);
+
+ ATF_REQUIRE(x == NULL);
+ ATF_REQUIRE(fail != true);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_REQUIRE(esetfunc(handler) != NULL);
+
+ ATF_TP_ADD_TC(tp, ecalloc);
+ ATF_TP_ADD_TC(tp, efopen);
+ ATF_TP_ADD_TC(tp, emalloc);
+ ATF_TP_ADD_TC(tp, erealloc);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libutil/t_parsedate.c b/contrib/netbsd-tests/lib/libutil/t_parsedate.c
new file mode 100644
index 0000000..ec035a6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libutil/t_parsedate.c
@@ -0,0 +1,142 @@
+/* $NetBSD: t_parsedate.c,v 1.7 2013/01/19 15:21:43 apb Exp $ */
+/*-
+ * 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 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 HOLDERS 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/cdefs.h>
+__RCSID("$NetBSD: t_parsedate.c,v 1.7 2013/01/19 15:21:43 apb Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
+#include <util.h>
+
+ATF_TC(dates);
+
+ATF_TC_HEAD(dates, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test unambiguous dates"
+ " (PR lib/44255)");
+}
+
+ATF_TC_BODY(dates, tc)
+{
+
+ ATF_CHECK(parsedate("69-09-10", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("2006-11-17", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("10/1/2000", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("20 Jun 1994", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("23jun2001", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("1-sep-06", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("1/11", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("1500-01-02", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("9999-12-21", NULL, NULL) != -1);
+}
+
+ATF_TC(times);
+
+ATF_TC_HEAD(times, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test times"
+ " (PR lib/44255)");
+}
+
+ATF_TC_BODY(times, tc)
+{
+
+ ATF_CHECK(parsedate("10:01", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("10:12pm", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("12:11:01.000012", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("12:21-0500", NULL, NULL) != -1);
+}
+
+ATF_TC(relative);
+
+ATF_TC_HEAD(relative, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test relative items"
+ " (PR lib/44255)");
+}
+
+ATF_TC_BODY(relative, tc)
+{
+
+ ATF_CHECK(parsedate("-1 month", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("last friday", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("one week ago", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("this thursday", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("next sunday", NULL, NULL) != -1);
+ ATF_CHECK(parsedate("+2 years", NULL, NULL) != -1);
+}
+
+ATF_TC(atsecs);
+
+ATF_TC_HEAD(atsecs, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test seconds past the epoch");
+}
+
+ATF_TC_BODY(atsecs, tc)
+{
+ int tzoff;
+
+ /* "@0" -> (time_t)0, regardless of timezone */
+ ATF_CHECK(parsedate("@0", NULL, NULL) == (time_t)0);
+ putenv(__UNCONST("TZ=Europe/Berlin"));
+ tzset();
+ ATF_CHECK(parsedate("@0", NULL, NULL) == (time_t)0);
+ putenv(__UNCONST("TZ=America/New_York"));
+ tzset();
+ ATF_CHECK(parsedate("@0", NULL, NULL) == (time_t)0);
+ tzoff = 0;
+ ATF_CHECK(parsedate("@0", NULL, &tzoff) == (time_t)0);
+ tzoff = 3600;
+ ATF_CHECK(parsedate("@0", NULL, &tzoff) == (time_t)0);
+ tzoff = -3600;
+ ATF_CHECK(parsedate("@0", NULL, &tzoff) == (time_t)0);
+
+ /* -1 or other negative numbers are not errors */
+ errno = 0;
+ ATF_CHECK(parsedate("@-1", NULL, &tzoff) == (time_t)-1 && errno == 0);
+ ATF_CHECK(parsedate("@-2", NULL, &tzoff) == (time_t)-2 && errno == 0);
+
+ /* junk is an error */
+ errno = 0;
+ ATF_CHECK(parsedate("@junk", NULL, NULL) == (time_t)-1 && errno != 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, dates);
+ ATF_TP_ADD_TC(tp, times);
+ ATF_TP_ADD_TC(tp, relative);
+ ATF_TP_ADD_TC(tp, atsecs);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libutil/t_pidfile.c b/contrib/netbsd-tests/lib/libutil/t_pidfile.c
new file mode 100644
index 0000000..a2aff83
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libutil/t_pidfile.c
@@ -0,0 +1,363 @@
+/* $NetBSD: t_pidfile.c,v 1.3 2011/03/29 13:55:37 jmmv Exp $ */
+
+/*
+ * Copyright (c) 2011 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.
+ */
+
+/*
+ * This file implements tests for the pidfile(3) functions.
+ *
+ * The tests here are tricky because we need to validate that the atexit(3)
+ * handler registered by pidfile(3) correctly deletes the generated pidfile.
+ * To do so:
+ * 1) We spawn a subprocess in every test case,
+ * 2) Run our test code in such subprocesses. We cannot call any of the ATF
+ * primitives from inside these.
+ * 3) Wait for the subprocess to terminate and ensure it exited successfully.
+ * 4) Check that the pidfile(s) created in the subprocess are gone.
+ *
+ * Additionally, pidfile(3) hardcodes a path to a directory writable only by
+ * root (/var/run). This makes us require root privileges to execute these
+ * tests.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_pidfile.c,v 1.3 2011/03/29 13:55:37 jmmv Exp $");
+
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <assert.h>
+#include <err.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <paths.h>
+#include <unistd.h>
+#include <util.h>
+
+#include <atf-c.h>
+
+/* Used by routines that can be called both from the parent and the child
+ * code to implement proper error reporting. */
+static bool in_child = false;
+
+/* Callable from the test case child code. */
+static void
+check_pidfile(const char *path)
+{
+ FILE *file;
+ int pid;
+
+ printf("Validating contents of pidfile '%s'\n", path);
+
+ if ((file = fopen(path, "r")) == NULL)
+ errx(EXIT_FAILURE, "Cannot open expected pidfile '%s'", path);
+
+ if (fscanf(file, "%d", &pid) == -1)
+ errx(EXIT_FAILURE, "Failed to read pid from pidfile '%s'",
+ path);
+
+ printf("Read pid %d, current pid %d\n", pid, getpid());
+ if (pid != getpid())
+ errx(EXIT_FAILURE, "Pid in pidfile (%d) does not match "
+ "current pid (%d)", pid, getpid());
+}
+
+/* Callable from the test case parent/child code. */
+static void
+ensure_deleted(const char *path)
+{
+ printf("Ensuring pidfile %s does not exist any more\n", path);
+ if (access(path, R_OK) != -1) {
+ unlink(path);
+ if (in_child)
+ errx(EXIT_FAILURE, "The pidfile %s was not deleted",
+ path);
+ else
+ atf_tc_fail("The pidfile %s was not deleted", path);
+ }
+}
+
+/* Callable from the test case parent code. */
+static void
+run_child(void (*child)(const char *), const char *cookie)
+{
+ pid_t pid;
+
+ pid = fork();
+ ATF_REQUIRE(pid != -1);
+ if (pid == 0) {
+ in_child = true;
+ child(cookie);
+ assert(false);
+ /* UNREACHABLE */
+ } else {
+ int status;
+
+ ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS)
+ atf_tc_fail("See stderr for details");
+ }
+}
+
+/* Callable from the test case parent/child code. */
+static char *
+generate_varrun_pidfile(const char *basename)
+{
+ char *path;
+
+ if (asprintf(&path, "%s%s.pid", _PATH_VARRUN,
+ basename == NULL ? getprogname() : basename) == -1) {
+ if (in_child)
+ errx(EXIT_FAILURE, "Cannot allocate memory for path");
+ else
+ atf_tc_fail("Cannot allocate memory for path");
+ }
+
+ return path;
+}
+
+static void
+helper_default_path(const char *path)
+{
+
+ if (pidfile(NULL) == -1)
+ errx(EXIT_FAILURE, "Failed to create pidfile with default "
+ "basename");
+
+ check_pidfile(path);
+ exit(EXIT_SUCCESS);
+}
+
+ATF_TC(default_path);
+ATF_TC_HEAD(default_path, tc)
+{
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(default_path, tc)
+{
+ char *path;
+
+ path = generate_varrun_pidfile(NULL);
+ run_child(helper_default_path, path);
+ ensure_deleted(path);
+ free(path);
+}
+
+static void
+helper_custom_basename(const char *path)
+{
+
+ if (pidfile("custom-basename") == -1)
+ errx(EXIT_FAILURE, "Failed to create pidfile with custom "
+ "basename");
+
+ check_pidfile(path);
+ exit(EXIT_SUCCESS);
+}
+
+ATF_TC(custom_basename);
+ATF_TC_HEAD(custom_basename, tc)
+{
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(custom_basename, tc)
+{
+ char *path;
+
+ path = generate_varrun_pidfile("custom-basename");
+ run_child(helper_custom_basename, path);
+ ensure_deleted(path);
+ free(path);
+}
+
+static void
+helper_custom_path(const char *path)
+{
+
+ if (pidfile(path) == -1)
+ errx(EXIT_FAILURE, "Failed to create pidfile '%s'", path);
+ check_pidfile(path);
+ exit(EXIT_SUCCESS);
+}
+
+ATF_TC_WITHOUT_HEAD(custom_path);
+ATF_TC_BODY(custom_path, tc)
+{
+
+ ATF_REQUIRE(mkdir("var", 0777) != -1);
+ ATF_REQUIRE(mkdir("var/run", 0777) != -1);
+
+ run_child(helper_custom_path, "./var/run/my-pidfile.pid");
+
+ ensure_deleted("./var/run/my-pidfile.pid");
+}
+
+static void
+helper_change_basenames(const char *unused_cookie)
+{
+ char *default_path;
+ char *custom_path;
+
+ default_path = generate_varrun_pidfile(NULL);
+ if (pidfile(NULL) == -1)
+ errx(EXIT_FAILURE, "Failed to create pidfile with default "
+ "basename");
+ check_pidfile(default_path);
+ if (pidfile(NULL) == -1)
+ errx(EXIT_FAILURE, "Failed to recreate pidfile with default "
+ "basename");
+ check_pidfile(default_path);
+
+ custom_path = generate_varrun_pidfile("custom-basename");
+ if (pidfile("custom-basename") == -1)
+ errx(EXIT_FAILURE, "Failed to create pidfile with custom "
+ "basename");
+ ensure_deleted(default_path);
+ check_pidfile(custom_path);
+ if (pidfile("custom-basename") == -1)
+ errx(EXIT_FAILURE, "Failed to recreate pidfile with custom "
+ "basename");
+ check_pidfile(custom_path);
+
+ free(custom_path);
+ free(default_path);
+ exit(EXIT_SUCCESS);
+}
+
+ATF_TC(change_basenames);
+ATF_TC_HEAD(change_basenames, tc)
+{
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(change_basenames, tc)
+{
+ char *default_path;
+ char *custom_path;
+
+ run_child(helper_change_basenames, NULL);
+
+ default_path = generate_varrun_pidfile(NULL);
+ custom_path = generate_varrun_pidfile("custom-basename");
+
+ ensure_deleted(default_path);
+ ensure_deleted(custom_path);
+
+ free(custom_path);
+ free(default_path);
+}
+
+static void
+helper_change_paths(const char *unused_cookie)
+{
+
+ if (pidfile("./var/run/first.pid") == -1)
+ errx(EXIT_FAILURE, "Failed to create pidfile "
+ "'./var/run/first.pid'");
+ check_pidfile("./var/run/first.pid");
+
+ if (pidfile("./second.pid") == -1)
+ errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'");
+ ensure_deleted("./var/run/first.pid");
+ check_pidfile("./second.pid");
+
+ exit(EXIT_SUCCESS);
+}
+
+ATF_TC_WITHOUT_HEAD(change_paths);
+ATF_TC_BODY(change_paths, tc)
+{
+
+ ATF_REQUIRE(mkdir("var", 0777) != -1);
+ ATF_REQUIRE(mkdir("var/run", 0777) != -1);
+
+ run_child(helper_change_paths, NULL);
+
+ ensure_deleted("./var/run/my-pidfile.pid");
+ ensure_deleted("second.pid");
+}
+
+static void
+helper_mix(const char *unused_cookie)
+{
+ char *default_path;
+ char *custom_path;
+
+ default_path = generate_varrun_pidfile(NULL);
+ custom_path = generate_varrun_pidfile("custom-basename");
+
+ if (pidfile(NULL) == -1)
+ errx(EXIT_FAILURE, "Failed to create default pidfile");
+ check_pidfile(default_path);
+
+ if (pidfile("./second.pid") == -1)
+ errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'");
+ ensure_deleted(default_path);
+ check_pidfile("./second.pid");
+
+ if (pidfile("custom-basename") == -1)
+ errx(EXIT_FAILURE, "Failed to create pidfile 'second.pid'");
+ ensure_deleted(default_path);
+ ensure_deleted("./second.pid");
+ ensure_deleted("./custom-basename");
+ check_pidfile(custom_path);
+
+ free(custom_path);
+ free(default_path);
+ exit(EXIT_SUCCESS);
+}
+
+ATF_TC(change_mix);
+ATF_TC_HEAD(change_mix, tc)
+{
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(change_mix, tc)
+{
+ char *default_path;
+
+ run_child(helper_mix, NULL);
+
+ default_path = generate_varrun_pidfile(NULL);
+ ensure_deleted(default_path);
+ ensure_deleted("second.pid");
+ free(default_path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, default_path);
+ ATF_TP_ADD_TC(tp, custom_basename);
+ ATF_TP_ADD_TC(tp, custom_path);
+ ATF_TP_ADD_TC(tp, change_basenames);
+ ATF_TP_ADD_TC(tp, change_paths);
+ ATF_TP_ADD_TC(tp, change_mix);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libutil/t_snprintb.c b/contrib/netbsd-tests/lib/libutil/t_snprintb.c
new file mode 100644
index 0000000..8863e8b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libutil/t_snprintb.c
@@ -0,0 +1,117 @@
+/* $NetBSD: t_snprintb.c,v 1.4 2014/06/06 06:59:21 shm Exp $ */
+
+/*
+ * Copyright (c) 2002, 2004, 2008, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Christos Zoulas.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008, 2010\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_snprintb.c,v 1.4 2014/06/06 06:59:21 shm Exp $");
+
+#include <string.h>
+#include <util.h>
+
+#include <atf-c.h>
+
+static void
+h_snprintb(const char *fmt, uint64_t val, const char *res)
+{
+ char buf[1024];
+ int len, slen;
+
+ len = snprintb(buf, sizeof(buf), fmt, val);
+ slen = (int) strlen(res);
+
+ ATF_REQUIRE_STREQ(res, buf);
+ ATF_REQUIRE_EQ(len, slen);
+}
+
+ATF_TC(snprintb);
+ATF_TC_HEAD(snprintb, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks snprintb(3)");
+}
+ATF_TC_BODY(snprintb, tc)
+{
+ h_snprintb("\10\2BITTWO\1BITONE", 3, "03<BITTWO,BITONE>");
+ h_snprintb("\177\20b\0A\0\0", 0, "0x0");
+
+ h_snprintb("\177\20b\05NOTBOOT\0b\06FPP\0b\013SDVMA\0b\015VIDEO\0"
+ "b\020LORES\0b\021FPA\0b\022DIAG\0b\016CACHE\0"
+ "b\017IOCACHE\0b\022LOOPBACK\0b\04DBGCACHE\0",
+ 0xe860, "0xe860<NOTBOOT,FPP,SDVMA,VIDEO,CACHE,IOCACHE>");
+}
+
+static void
+h_snprintb_m(const char *fmt, uint64_t val, int line_max, const char *res,
+ int res_len)
+{
+ char buf[1024];
+ int len;
+
+ len = snprintb_m(buf, sizeof(buf), fmt, val, line_max);
+
+ ATF_REQUIRE_EQ(len, res_len);
+ ATF_REQUIRE_EQ(0, memcmp(res, buf, res_len + 1));
+}
+
+ATF_TC(snprintb_m);
+ATF_TC_HEAD(snprintb_m, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks snprintb_m(3)");
+}
+ATF_TC_BODY(snprintb_m, tc)
+{
+ h_snprintb_m("\177\020b\0LSB\0b\1_BITONE\0f\4\4NIBBLE2\0"
+ "f\x10\4BURST\0=\4FOUR\0=\xfSIXTEEN\0"
+ "b\x1fMSB\0\0",
+ 0x800f0701,
+ 33,
+ "0x800f0701<LSB,NIBBLE2=0x0>\0"
+ "0x800f0701<BURST=0xf=SIXTEEN,MSB>\0\0",
+ 62);
+
+ h_snprintb_m("\177\020b\0LSB\0b\1_BITONE\0f\4\4NIBBLE2\0"
+ "f\x10\4BURST\0=\4FOUR\0=\xfSIXTEEN\0"
+ "b\x1fMSB\0\0",
+ 0x800f0701,
+ 32,
+ "0x800f0701<LSB,NIBBLE2=0x0>\0"
+ "0x800f0701<BURST=0xf=SIXTEEN>\0"
+ "0x800f0701<MSB>\0\0",
+ 74);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, snprintb);
+ ATF_TP_ADD_TC(tp, snprintb_m);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libutil/t_sockaddr_snprintf.c b/contrib/netbsd-tests/lib/libutil/t_sockaddr_snprintf.c
new file mode 100644
index 0000000..b4e8cb3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libutil/t_sockaddr_snprintf.c
@@ -0,0 +1,185 @@
+/* $NetBSD: t_sockaddr_snprintf.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $ */
+
+/*
+ * Copyright (c) 2002, 2004, 2008, 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Christos Zoulas.
+ *
+ * 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/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008, 2010\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_sockaddr_snprintf.c,v 1.1 2010/07/16 13:56:32 jmmv Exp $");
+
+#include <sys/socket.h> /* AF_ */
+#include <sys/un.h> /* sun */
+
+#include <net/if_dl.h> /* sdl */
+#include <netatalk/at.h> /* sat */
+#include <netinet/in.h> /* sin/sin6 */
+
+#include <string.h>
+#include <util.h>
+
+#include <atf-c.h>
+
+ATF_TC(sockaddr_snprintf_in);
+ATF_TC_HEAD(sockaddr_snprintf_in, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks sockaddr_snprintf(3) with sockaddr_in");
+}
+ATF_TC_BODY(sockaddr_snprintf_in, tc)
+{
+ char buf[1024];
+ struct sockaddr_in sin4;
+ int i;
+
+ memset(&sin4, 0, sizeof(sin4));
+ sin4.sin_len = sizeof(sin4);
+ sin4.sin_family = AF_INET;
+ sin4.sin_port = ntohs(80);
+ sin4.sin_addr.s_addr = ntohl(INADDR_LOOPBACK);
+ i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %p %a",
+ (struct sockaddr *)&sin4);
+
+ ATF_REQUIRE_EQ_MSG(i, 17, "bad length for sin4");
+ ATF_REQUIRE_STREQ(buf, "2 16 80 127.0.0.1");
+}
+
+ATF_TC(sockaddr_snprintf_in6);
+ATF_TC_HEAD(sockaddr_snprintf_in6, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks sockaddr_snprintf(3) with sockaddr_in6");
+}
+ATF_TC_BODY(sockaddr_snprintf_in6, tc)
+{
+#ifdef INET6
+ char buf[1024];
+ struct sockaddr_in6 sin6;
+ int i;
+
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_len = sizeof(sin6);
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = ntohs(80);
+ sin6.sin6_addr = in6addr_nodelocal_allnodes;
+ i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %p %a",
+ (struct sockaddr *)&sin6);
+
+ ATF_REQUIRE_EQ_MSG(i, 16, "bad length for sin6");
+ ATF_REQUIRE_STREQ(buf, "24 28 80 ff01::1");
+#else
+ atf_tc_skip("Tests built with USE_INET6=no");
+#endif /* INET6 */
+}
+
+ATF_TC(sockaddr_snprintf_un);
+ATF_TC_HEAD(sockaddr_snprintf_un, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks sockaddr_snprintf(3) with sockaddr_un");
+}
+ATF_TC_BODY(sockaddr_snprintf_un, tc)
+{
+ char buf[1024];
+ struct sockaddr_un sun;
+ int i;
+
+ memset(&sun, 0, sizeof(sun));
+ sun.sun_len = sizeof(sun);
+ sun.sun_family = AF_UNIX;
+ strncpy(sun.sun_path, "/tmp/sock", sizeof(sun.sun_path));
+ i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a",
+ (struct sockaddr *)&sun);
+
+ ATF_REQUIRE_EQ_MSG(i, 15, "bad length for sun");
+ ATF_REQUIRE_STREQ(buf, "1 106 /tmp/sock");
+}
+
+ATF_TC(sockaddr_snprintf_at);
+ATF_TC_HEAD(sockaddr_snprintf_at, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks sockaddr_snprintf(3) with sockaddr_at");
+}
+ATF_TC_BODY(sockaddr_snprintf_at, tc)
+{
+ char buf[1024];
+ struct sockaddr_at sat;
+ int i;
+
+ memset(&sat, 0, sizeof(sat));
+ sat.sat_len = sizeof(sat);
+ sat.sat_family = AF_APPLETALK;
+ sat.sat_addr.s_net = ntohs(101);
+ sat.sat_addr.s_node = 3;
+ i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a",
+ (struct sockaddr *)&sat);
+
+ ATF_REQUIRE_EQ_MSG(i, 11, "bad length for sat");
+ ATF_REQUIRE_STREQ(buf, "16 16 101.3");
+}
+
+ATF_TC(sockaddr_snprintf_dl);
+ATF_TC_HEAD(sockaddr_snprintf_dl, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks sockaddr_snprintf(3) with sockaddr_dl");
+}
+ATF_TC_BODY(sockaddr_snprintf_dl, tc)
+{
+ char buf[1024];
+ struct sockaddr_dl sdl;
+ int i;
+
+ memset(&sdl, 0, sizeof(sdl));
+ sdl.sdl_len = sizeof(sdl);
+ sdl.sdl_family = AF_LINK;
+ sdl.sdl_index = 0;
+ sdl.sdl_type = 0;
+ sdl.sdl_nlen = 0;
+ sdl.sdl_alen = 6;
+ sdl.sdl_slen = 0;
+ memcpy(sdl.sdl_data, "\01\02\03\04\05\06", 6);
+ i = sockaddr_snprintf(buf, sizeof(buf), "%f %l %a",
+ (struct sockaddr *)&sdl);
+
+ ATF_REQUIRE_EQ_MSG(i, 17, "bad length for sdl");
+ ATF_REQUIRE_STREQ(buf, "18 20 1.2.3.4.5.6");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sockaddr_snprintf_in);
+ ATF_TP_ADD_TC(tp, sockaddr_snprintf_in6);
+ ATF_TP_ADD_TC(tp, sockaddr_snprintf_un);
+ ATF_TP_ADD_TC(tp, sockaddr_snprintf_at);
+ ATF_TP_ADD_TC(tp, sockaddr_snprintf_dl);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/semaphore/pthread/t_sem_pth.c b/contrib/netbsd-tests/lib/semaphore/pthread/t_sem_pth.c
new file mode 100644
index 0000000..b32d954
--- /dev/null
+++ b/contrib/netbsd-tests/lib/semaphore/pthread/t_sem_pth.c
@@ -0,0 +1,17 @@
+#define LIBNAME "pthread"
+#include "sem.c"
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, postwait);
+ ATF_TP_ADD_TC(tp, initvalue);
+ ATF_TP_ADD_TC(tp, destroy);
+ ATF_TP_ADD_TC(tp, busydestroy);
+ ATF_TP_ADD_TC(tp, blockwait);
+ ATF_TP_ADD_TC(tp, blocktimedwait);
+ ATF_TP_ADD_TC(tp, named);
+ ATF_TP_ADD_TC(tp, unlink);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/semaphore/sem.c b/contrib/netbsd-tests/lib/semaphore/sem.c
new file mode 100644
index 0000000..5967b88
--- /dev/null
+++ b/contrib/netbsd-tests/lib/semaphore/sem.c
@@ -0,0 +1,332 @@
+/* $NetBSD: sem.c,v 1.10 2012/03/09 14:25:34 joerg Exp $ */
+
+/*
+ * Common code for semaphore tests. This can be included both into
+ * programs using librt and libpthread.
+ */
+
+#include <sys/types.h>
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../../h_macros.h"
+
+ATF_TC(postwait);
+ATF_TC_HEAD(postwait, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests post and wait from a "
+ "single thread (%s)", LIBNAME);
+}
+
+ATF_TC_BODY(postwait, tc)
+{
+ sem_t sem;
+ int rv;
+
+ rump_init();
+
+ ATF_REQUIRE_EQ(sem_init(&sem, 1, 0), 0);
+
+ sem_post(&sem);
+ sem_post(&sem);
+
+ sem_wait(&sem);
+ sem_wait(&sem);
+ rv = sem_trywait(&sem);
+ ATF_REQUIRE(errno == EAGAIN);
+ ATF_REQUIRE(rv == -1);
+}
+
+ATF_TC(initvalue);
+ATF_TC_HEAD(initvalue, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests initialization with a non-zero "
+ "value (%s)", LIBNAME);
+}
+
+ATF_TC_BODY(initvalue, tc)
+{
+ sem_t sem;
+
+ rump_init();
+ sem_init(&sem, 1, 4);
+
+ ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+ ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+ ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+ ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+ ATF_REQUIRE_EQ(sem_trywait(&sem), -1);
+}
+
+ATF_TC(destroy);
+ATF_TC_HEAD(destroy, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests sem_destroy works (%s)", LIBNAME);
+}
+
+ATF_TC_BODY(destroy, tc)
+{
+ sem_t sem;
+ int rv, i;
+
+ rump_init();
+ for (i = 0; i < 2; i++) {
+ sem_init(&sem, 1, 1);
+
+ ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+ ATF_REQUIRE_EQ(sem_trywait(&sem), -1);
+ ATF_REQUIRE_EQ(sem_destroy(&sem), 0);
+ rv = sem_trywait(&sem);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+ ATF_REQUIRE_EQ(rv, -1);
+ }
+}
+
+ATF_TC(busydestroy);
+ATF_TC_HEAD(busydestroy, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests sem_destroy report EBUSY for "
+ "a busy semaphore (%s)", LIBNAME);
+}
+
+static void *
+hthread(void *arg)
+{
+ sem_t *semmarit = arg;
+
+ for (;;) {
+ sem_post(&semmarit[2]);
+ sem_wait(&semmarit[1]);
+ sem_wait(&semmarit[0]);
+ }
+
+ return NULL;
+}
+
+ATF_TC_BODY(busydestroy, tc)
+{
+ sem_t semmarit[3];
+ pthread_t pt;
+ int i;
+
+ /* use a unicpu rump kernel. this means less chance for race */
+ setenv("RUMP_NCPU", "1", 1);
+
+ rump_init();
+ sem_init(&semmarit[0], 1, 0);
+ sem_init(&semmarit[1], 1, 0);
+ sem_init(&semmarit[2], 1, 0);
+
+ pthread_create(&pt, NULL, hthread, semmarit);
+
+ /*
+ * Make a best-effort to catch the other thread with its pants down.
+ * We can't do this for sure, can we? Although, we could reach
+ * inside the rump kernel and inquire about the thread's sleep
+ * status.
+ */
+ for (i = 0; i < 1000; i++) {
+ sem_wait(&semmarit[2]);
+ usleep(1);
+ if (sem_destroy(&semmarit[1]) == -1)
+ if (errno == EBUSY)
+ break;
+
+ /*
+ * Didn't catch it? ok, recreate and post to make the
+ * other thread run
+ */
+ sem_init(&semmarit[1], 1, 0);
+ sem_post(&semmarit[0]);
+ sem_post(&semmarit[1]);
+
+ }
+ if (i == 1000)
+ atf_tc_fail("sem destroy not reporting EBUSY");
+
+ pthread_cancel(pt);
+ pthread_join(pt, NULL);
+}
+
+ATF_TC(blockwait);
+ATF_TC_HEAD(blockwait, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests sem_wait can handle blocking "
+ "(%s)", LIBNAME);
+ atf_tc_set_md_var(tc, "timeout", "2");
+}
+
+ATF_TC_BODY(blockwait, tc)
+{
+ sem_t semmarit[3];
+ pthread_t pt;
+ int i;
+
+ rump_init();
+ sem_init(&semmarit[0], 1, 0);
+ sem_init(&semmarit[1], 1, 0);
+ sem_init(&semmarit[2], 1, 0);
+
+ pthread_create(&pt, NULL, hthread, semmarit);
+
+ /*
+ * Make a best-effort. Unless we're extremely unlucky, we should
+ * at least one blocking wait.
+ */
+ for (i = 0; i < 10; i++) {
+ sem_wait(&semmarit[2]);
+ usleep(1);
+ sem_post(&semmarit[0]);
+ sem_post(&semmarit[1]);
+
+ }
+
+ pthread_cancel(pt);
+ pthread_join(pt, NULL);
+}
+
+ATF_TC(blocktimedwait);
+ATF_TC_HEAD(blocktimedwait, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests sem_timedwait can handle blocking"
+ " (%s)", LIBNAME);
+ atf_tc_set_md_var(tc, "timeout", "2");
+}
+
+ATF_TC_BODY(blocktimedwait, tc)
+{
+ sem_t semid;
+ struct timespec tp;
+
+ rump_init();
+
+ clock_gettime(CLOCK_REALTIME, &tp);
+ tp.tv_nsec += 50000000;
+ tp.tv_sec += tp.tv_nsec / 1000000000;
+ tp.tv_nsec %= 1000000000;
+
+ ATF_REQUIRE_EQ(sem_init(&semid, 1, 0), 0);
+ ATF_REQUIRE_ERRNO(ETIMEDOUT, sem_timedwait(&semid, &tp) == -1);
+}
+
+ATF_TC(named);
+ATF_TC_HEAD(named, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests named semaphores (%s)", LIBNAME);
+}
+
+/*
+ * Wow, easy naming rules. it's these times i'm really happy i can
+ * single-step into the kernel.
+ */
+#define SEM1 "/precious_sem"
+#define SEM2 "/justsem"
+ATF_TC_BODY(named, tc)
+{
+ sem_t *sem1, *sem2;
+ void *rv;
+
+ rump_init();
+ sem1 = sem_open(SEM1, 0);
+ ATF_REQUIRE_EQ(errno, ENOENT);
+ ATF_REQUIRE_EQ(sem1, NULL);
+
+ sem1 = sem_open(SEM1, O_CREAT, 0444, 1);
+ if (sem1 == NULL)
+ atf_tc_fail_errno("sem_open O_CREAT");
+
+ rv = sem_open(SEM1, O_CREAT | O_EXCL);
+ ATF_REQUIRE_EQ(errno, EEXIST);
+ ATF_REQUIRE_EQ(rv, NULL);
+
+ sem2 = sem_open(SEM2, O_CREAT, 0444, 0);
+ if (sem2 == NULL)
+ atf_tc_fail_errno("sem_open O_CREAT");
+
+ /* check that semaphores are independent */
+ ATF_REQUIRE_EQ(sem_trywait(sem2), -1);
+ ATF_REQUIRE_EQ(sem_trywait(sem1), 0);
+ ATF_REQUIRE_EQ(sem_trywait(sem1), -1);
+
+ /* check that unlinked remains valid */
+ sem_unlink(SEM2);
+ ATF_REQUIRE_EQ(sem_post(sem2), 0);
+ ATF_REQUIRE_EQ(sem_trywait(sem2), 0);
+ ATF_REQUIRE_EQ(sem_trywait(sem2), -1);
+ ATF_REQUIRE_EQ(errno, EAGAIN);
+
+#if 0 /* see unlink */
+ /* close it and check that it's gone */
+ if (sem_close(sem2) != 0)
+ atf_tc_fail_errno("sem close");
+ ATF_REQUIRE_EQ(sem_trywait(sem2), -1);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+#endif
+
+ /* check that we still have sem1 */
+ sem_post(sem1);
+ ATF_REQUIRE_EQ(sem_trywait(sem1), 0);
+ ATF_REQUIRE_EQ(sem_trywait(sem1), -1);
+ ATF_REQUIRE_EQ(errno, EAGAIN);
+}
+
+ATF_TC(unlink);
+ATF_TC_HEAD(unlink, tc)
+{
+
+ /* this is currently broken. i'll append the PR number soon */
+ atf_tc_set_md_var(tc, "descr", "tests unlinked semaphores can be "
+ "closed (%s)", LIBNAME);
+}
+
+#define SEM "/thesem"
+ATF_TC_BODY(unlink, tc)
+{
+ sem_t *sem;
+
+ rump_init();
+ sem = sem_open(SEM, O_CREAT, 0444, 0);
+ ATF_REQUIRE(sem);
+
+ if (sem_unlink(SEM) == -1)
+ atf_tc_fail_errno("unlink");
+ if (sem_close(sem) == -1)
+ atf_tc_fail_errno("close unlinked semaphore");
+}
+
+/* use rump calls for libpthread _ksem_foo() calls */
+#define F1(name, a) int _ksem_##name(a); \
+int _ksem_##name(a v1) {return rump_sys__ksem_##name(v1);}
+#define F2(name, a, b) int _ksem_##name(a, b); \
+int _ksem_##name(a v1, b v2) {return rump_sys__ksem_##name(v1, v2);}
+F2(init, unsigned int, intptr_t *);
+F1(close, intptr_t);
+F1(destroy, intptr_t);
+F1(post, intptr_t);
+F1(unlink, const char *);
+F1(trywait, intptr_t);
+F1(wait, intptr_t);
+F2(getvalue, intptr_t, unsigned int *);
+F2(timedwait, intptr_t, const struct timespec *);
+int _ksem_open(const char *, int, mode_t, unsigned int, intptr_t *);
+int _ksem_open(const char *a, int b, mode_t c, unsigned int d, intptr_t *e)
+ {return rump_sys__ksem_open(a,b,c,d,e);}
OpenPOWER on IntegriCloud