summaryrefslogtreecommitdiffstats
path: root/contrib/netbsd-tests/lib
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2014-10-04 12:42:37 +0000
committermelifaro <melifaro@FreeBSD.org>2014-10-04 12:42:37 +0000
commite8d559896cc84e0dd02a5419f74cb26abcb262e9 (patch)
treeede07b25dfc0e3d156d39f6fbfab305c429361d2 /contrib/netbsd-tests/lib
parent08c555cee75f59926d8d61bdc95449631fedce4c (diff)
parent1db3c5c0a6d331d775feb5b779ff5064c3e51a11 (diff)
downloadFreeBSD-src-e8d559896cc84e0dd02a5419f74cb26abcb262e9.zip
FreeBSD-src-e8d559896cc84e0dd02a5419f74cb26abcb262e9.tar.gz
Sync to HEAD@r272516.
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.sh920
-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.c385
-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.c136
-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.c355
-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.c151
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_getgrent.c181
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_glob.c273
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c312
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_isnan.c67
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_nice.c193
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_pause.c114
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_raise.c190
-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.c132
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_sethostname.c132
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_siginfo.c500
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_sleep.c337
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_syslog.c56
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_time.c114
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_ttyname.c188
-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.c167
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/hash/t_hash.sh67
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/t_sha2.c243
-rw-r--r--contrib/netbsd-tests/lib/libc/inet/t_inet_network.c170
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_io.c178
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c267
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c98
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c202
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c143
-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.c456
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_wctomb.c205
-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.c298
-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.c104
-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.sh93
-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.c266
-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.c210
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/regex/t_regex.sh73
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/t_regex_att.c629
-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.c157
-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.c45
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_raw.c57
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_read.c47
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_readlink.c47
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c45
-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.sh308
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c93
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_fflush.c171
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c1166
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_fopen.c442
-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.c194
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_scanf.c81
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c178
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c127
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c239
-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.c199
-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.c399
-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.c335
-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.c150
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_memmem.c100
-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.c135
-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.c210
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_chroot.c313
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c212
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_clone.c252
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_connect.c99
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_dup.c385
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_fsync.c120
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getcontext.c129
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getgroups.c171
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getitimer.c211
-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.c197
-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.c180
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_kill.c312
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_link.c229
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_listen.c134
-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.c318
-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.c192
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mlock.c244
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mmap.c505
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mprotect.c359
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgctl.c358
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgget.c292
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c342
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c338
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msync.c237
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c187
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_pipe.c163
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_pipe2.c188
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_poll.c392
-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.c186
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_select.c215
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c522
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_setuid.c122
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_sigaction.c154
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c103
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c126
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_socketpair.c137
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_stat.c417
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c133
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_timer_create.c207
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_truncate.c175
-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.c158
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_write.c226
-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.c252
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c60
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c113
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c105
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_static.c93
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c53
-rw-r--r--contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c56
-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.c168
-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.c366
-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.c567
-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.c481
-rw-r--r--contrib/netbsd-tests/lib/libm/t_libm.h62
-rw-r--r--contrib/netbsd-tests/lib/libm/t_log.c885
-rw-r--r--contrib/netbsd-tests/lib/libm/t_modf.c68
-rw-r--r--contrib/netbsd-tests/lib/libm/t_pow.c669
-rw-r--r--contrib/netbsd-tests/lib/libm/t_precision.c76
-rw-r--r--contrib/netbsd-tests/lib/libm/t_round.c85
-rw-r--r--contrib/netbsd-tests/lib/libm/t_scalbn.c523
-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.c183
-rw-r--r--contrib/netbsd-tests/lib/libpthread/h_cancel.c58
-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.c142
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_detach.c91
-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.c107
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_fpu.c148
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_join.c174
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_kill.c147
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_mutex.c316
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_name.c103
-rw-r--r--contrib/netbsd-tests/lib/libpthread/t_once.c196
-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.c307
-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.c175
-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, 83848 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..52244e3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/db/t_db.sh
@@ -0,0 +1,920 @@
+# $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
+}
+
+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
+
+ atf_check "$(prog)" -i bsize=65536 hash in
+}
+
+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..1cf6433
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c
@@ -0,0 +1,385 @@
+/* $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.
+ */
+
+
+#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);
+}
+
+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);
+}
+
+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);
+ ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent_diag);
+ 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..9561a3c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c
@@ -0,0 +1,136 @@
+/* $NetBSD: t_floatunditf.c,v 1.5 2014/02/02 08:16:22 martin 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 <atf-c/config.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..998eb85
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c
@@ -0,0 +1,355 @@
+/* $NetBSD: t_fpsetmask.c,v 1.13 2014/02/09 21:26:07 jmmv 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 <atf-c/config.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..76c287a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c
@@ -0,0 +1,151 @@
+/* $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);
+
+ errno = 0;
+
+ ATF_REQUIRE(getcwd((void *)-1, sizeof(buf)) == NULL);
+ ATF_REQUIRE(errno == EFAULT);
+}
+
+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..ff62b63
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_glob.c
@@ -0,0 +1,273 @@
+/* $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>
+
+#include "../../../h_macros.h"
+
+
+#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));
+ dir.d_reclen = _DIRENT_RECLEN(&dir, dir.d_namlen);
+ 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);
+}
+
+
+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));
+}
+
+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)
+{
+ ATF_TP_ADD_TC(tp, glob_star);
+ 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..1af579e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c
@@ -0,0 +1,312 @@
+/* $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>
+#include <util.h>
+
+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".
+ */
+ { 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" },
+ { 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..2a97b9a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c
@@ -0,0 +1,67 @@
+/* $NetBSD: t_isnan.c,v 1.4 2014/02/09 21:26:07 jmmv 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 <atf-c/config.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..f4a62e9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_nice.c
@@ -0,0 +1,193 @@
+/* $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;
+
+ /*
+ * 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)
+{
+ int i, pri, nic;
+ 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);
+
+ if (nic != pri)
+ atf_tc_fail("nice(3) and getpriority(2) conflict");
+
+ /*
+ * Also verify that the nice(3) values
+ * are inherited by child processes.
+ */
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ errno = 0;
+ pri = getpriority(PRIO_PROCESS, 0);
+ ATF_REQUIRE(errno == 0);
+
+ if (nic != pri)
+ _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];
+ int rv, val;
+ 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);
+
+ rv = pthread_create(&tid[i], NULL, threadfunc, &val);
+ 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..adc032f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_raise.c
@@ -0,0 +1,190 @@
+/* $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);
+static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2, SIGPWR };
+
+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..89818f0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c
@@ -0,0 +1,132 @@
+/* $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));
+
+ ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i])) == 0);
+ ATF_REQUIRE(getdomainname(name, sizeof(name)) == 0);
+ 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));
+
+ 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..a753ac7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c
@@ -0,0 +1,132 @@
+/* $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;
+
+ for (i = 0; i < __arraycount(hosts); i++) {
+
+ (void)memset(name, 0, sizeof(name));
+
+ ATF_REQUIRE(sethostname(hosts[i], sizeof(hosts[i])) == 0);
+ ATF_REQUIRE(gethostname(name, sizeof(name)) == 0);
+ 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)
+{
+ (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..2fb53e4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c
@@ -0,0 +1,500 @@
+/* $NetBSD: t_siginfo.c,v 1.23 2014/02/09 21:26:07 jmmv 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 <atf-c/config.h>
+
+#include <sys/inttypes.h>
+#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);
+ 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]);
+ }
+}
+
+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);
+ printf("si_utime=%lu\n", (unsigned long int)info->si_utime);
+ printf("si_stime=%lu\n", (unsigned long int)info->si_stime);
+ }
+ 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..e4dc94e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c
@@ -0,0 +1,337 @@
+/* $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 */
+
+/*
+ * 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 *);
+int do_poll(struct timespec *, struct timespec *);
+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;
+}
+
+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;
+}
+
+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);
+}
+
+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);
+}
+
+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);
+ ATF_TP_ADD_TC(tp, poll);
+ 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..bfbdc73
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_time.c
@@ -0,0 +1,114 @@
+/* $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 $");
+
+#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..0c10c24
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c
@@ -0,0 +1,188 @@
+/* $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);
+ }
+
+ 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..33b9f9a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/h_hash.c
@@ -0,0 +1,167 @@
+/* $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>
+#include <sha1.h>
+
+
+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 {
+ SHA1_CTX ctx;
+
+ SHA1Init(&ctx);
+ SHA1Update(&ctx, buf, len);
+ while (!last &&
+ fgets((char *)buf, sizeof(buf), stdin) != NULL) {
+ len = strlen((char *)buf);
+ CHOMP(buf, len, last);
+ SHA1Update(&ctx, buf, len);
+ }
+ SHA1Final(out, &ctx);
+ 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..a45e82a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/t_sha2.c
@@ -0,0 +1,243 @@
+/* $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>
+#include <sha2.h>
+#include <string.h>
+
+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..99f75b3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c
@@ -0,0 +1,170 @@
+/* $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);
+ H_REQUIRE("0x", 0xffffffff);
+ 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..782bed8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_io.c
@@ -0,0 +1,178 @@
+/* $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)
+{
+ /* 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)
+{
+ /* 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");
+ 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..b4ad841
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c
@@ -0,0 +1,267 @@
+/* $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");
+ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
+
+ (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;
+
+ 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..ec06729
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c
@@ -0,0 +1,202 @@
+/* $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");
+ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
+
+ (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..62f62b1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c
@@ -0,0 +1,143 @@
+/* $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");
+ ATF_REQUIRE(setlocale(LC_CTYPE, locale) != NULL);
+
+ 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");
+ h_mbtowc("zh_CN.GB18030", "\241", "\241\241");
+ h_mbtowc("zh_TW.Big5", "\241", "\241@");
+ h_mbtowc("zh_TW.eucTW", "\241", "\241\241");
+}
+
+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..85b1ee1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c
@@ -0,0 +1,456 @@
+/* $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>
+
+#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__)
+{ 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..f553c8c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c
@@ -0,0 +1,205 @@
+/* $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");
+ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
+
+ (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..47472de
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/h_dns_server.c
@@ -0,0 +1,298 @@
+/* $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>
+#include <netinet6/in6.h>
+
+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
+
+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
+
+ 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 DEBUG
+ daemon(0, 1);
+#else
+ daemon(0, 0);
+#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..6ca3c5b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c
@@ -0,0 +1,104 @@
+/* $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>
+
+#define ETHER_ADDR_LEN 6
+
+int ether_aton_r(u_char *dest, size_t len, const char *str);
+
+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 },
+ { { 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 },
+#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)
+{
+ u_char dest[ETHER_ADDR_LEN];
+ size_t t;
+ int e, r;
+ const char *s;
+
+ for (t = 0; tests[t].str; t++) {
+ s = tests[t].str;
+ if ((e = tests[t].error) == 0) {
+ 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 ((r = ether_aton_r(dest, sizeof(dest), s)) != e)
+ atf_tc_fail("unexpectedly succeeded on `%s' "
+ "(%d != %d)", s, r, e);
+ }
+ }
+}
+
+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..b9aa2b7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/t_servent.sh
@@ -0,0 +1,93 @@
+# $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
+
+ # 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..c1528b9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/debug.c
@@ -0,0 +1,266 @@
+/* $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>
+
+/* 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)
+{
+ 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");
+ }
+}
+
+/*
+ * 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);
+ 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;
+ }
+ }
+ 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:
+ fprintf(d, "!%d(%d)!", OP(*s), opnd);
+ 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..468492c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c
@@ -0,0 +1,210 @@
+/* $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>
+
+#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");
+ atf_tc_set_md_var(tc, "require.memory", "120M");
+}
+
+ATF_TC_BODY(regcomp_too_big, tc)
+{
+ regex_t re;
+ int e;
+
+ 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..beaeb04
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c
@@ -0,0 +1,629 @@
+/* $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>
+
+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;
+ }
+ ATF_REQUIRE_STREQ_MSG(res, matches, " at line %zu", lineno);
+ 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
+ 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..cc1ec09
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c
@@ -0,0 +1,157 @@
+/* $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;
+}
+
+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..65ed5f2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_memset.c
@@ -0,0 +1,45 @@
+/* $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);
+ return 0;
+}
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..5240af2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_read.c
@@ -0,0 +1,47 @@
+/* $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>
+
+int
+main(int argc, char *argv[])
+{
+ char b[MAXPATHLEN];
+ size_t len = atoi(argv[1]);
+ (void)read(0, b, len);
+ (void)printf("%s\n", b);
+ return 0;
+}
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..c18faed
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c
@@ -0,0 +1,47 @@
+/* $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>
+
+int
+main(int argc, char *argv[])
+{
+ char b[MAXPATHLEN];
+ size_t len = atoi(argv[1]);
+ (void)readlink("/", b, len);
+ (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..93575a8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c
@@ -0,0 +1,45 @@
+/* $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]);
+ (void)snprintf(b, len, "%s", "0123456789");
+ (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..0514348
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh
@@ -0,0 +1,308 @@
+# $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 ]"
+ eval $2 atf_check -s signal:6 -o ignore -e ignore $1
+}
+
+atf_test_case sprintf
+sprintf_head()
+{
+ atf_set "descr" "Checks sprintf(3)"
+}
+sprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_sprintf"
+
+ h_pass "$prog ok"
+ h_fail "$prog 0123456789"
+}
+
+atf_test_case vsprintf
+vsprintf_head()
+{
+ atf_set "descr" "Checks vsprintf(3)"
+}
+vsprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_vsprintf"
+
+ h_pass "$prog ok"
+ h_fail "$prog 0123456789"
+}
+
+atf_test_case snprintf
+snprintf_head()
+{
+ atf_set "descr" "Checks snprintf(3)"
+}
+snprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_snprintf"
+
+ h_pass "$prog 10"
+ h_fail "$prog 11"
+}
+
+atf_test_case vsnprintf
+vsnprintf_head()
+{
+ atf_set "descr" "Checks vsnprintf(3)"
+}
+vsnprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_vsnprintf"
+
+ h_pass "$prog 10"
+ h_fail "$prog 11"
+}
+
+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 |"
+ h_fail "$prog" "echo 0123456789 |"
+}
+
+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 |"
+ h_fail "$prog 11" "echo busted |"
+}
+
+atf_test_case memcpy
+memcpy_head()
+{
+ atf_set "descr" "Checks memcpy(3)"
+}
+memcpy_body()
+{
+ prog="$(atf_get_srcdir)/h_memcpy"
+
+ h_pass "$prog 10"
+ h_fail "$prog 11"
+}
+
+atf_test_case memmove
+memmove_head()
+{
+ atf_set "descr" "Checks memmove(3)"
+}
+memmove_body()
+{
+ prog="$(atf_get_srcdir)/h_memmove"
+
+ h_pass "$prog 10"
+ h_fail "$prog 11"
+}
+
+atf_test_case memset
+memset_head()
+{
+ atf_set "descr" "Checks memset(3)"
+}
+memset_body()
+{
+ prog="$(atf_get_srcdir)/h_memset"
+
+ h_pass "$prog 10"
+ h_fail "$prog 11"
+}
+
+atf_test_case strcpy
+strcpy_head()
+{
+ atf_set "descr" "Checks strcpy(3)"
+}
+strcpy_body()
+{
+ prog="$(atf_get_srcdir)/h_strcpy"
+
+ h_pass "$prog 0123456"
+ h_fail "$prog 0123456789"
+}
+
+atf_test_case stpcpy
+stpcpy_head()
+{
+ atf_set "descr" "Checks stpcpy(3)"
+}
+stpcpy_body()
+{
+ prog="$(atf_get_srcdir)/h_stpcpy"
+
+ h_pass "$prog 0123456"
+ h_fail "$prog 0123456789"
+}
+
+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"
+ h_fail "$prog 11"
+}
+
+atf_test_case stpncpy
+stpncpy_head()
+{
+ atf_set "descr" "Checks stpncpy(3)"
+}
+stpncpy_body()
+{
+ prog="$(atf_get_srcdir)/h_stpncpy"
+
+ h_pass "$prog 10"
+ h_fail "$prog 11"
+}
+
+atf_test_case strncat
+strncat_head()
+{
+ atf_set "descr" "Checks strncat(3)"
+}
+strncat_body()
+{
+ prog="$(atf_get_srcdir)/h_strncat"
+
+ h_pass "$prog 8"
+ h_fail "$prog 9"
+}
+
+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"
+ h_fail "$prog 10"
+}
+
+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 |"
+ h_fail "$prog 1025" "echo bar |"
+}
+
+atf_test_case readlink
+readlink_head()
+{
+ atf_set "descr" "Checks readlink(2)"
+}
+readlink_body()
+{
+ prog="$(atf_get_srcdir)/h_readlink"
+
+ h_pass "$prog 1024"
+ h_fail "$prog 1025"
+}
+
+atf_test_case getcwd
+getcwd_head()
+{
+ atf_set "descr" "Checks getcwd(3)"
+}
+getcwd_body()
+{
+ prog="$(atf_get_srcdir)/h_getcwd"
+
+ h_pass "$prog 1024"
+ h_fail "$prog 1025"
+}
+
+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..766070c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c
@@ -0,0 +1,171 @@
+/* $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;
+
+ 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..212c7c86
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c
@@ -0,0 +1,1166 @@
+/* $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(__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);
+ }
+ }
+}
+
+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);
+ }
+ }
+}
+
+ATF_TC(test13);
+ATF_TC_HEAD(test13, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test13");
+}
+ATF_TC_BODY(test13, tc)
+{
+ struct testcase *t;
+ off_t i;
+ 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);
+
+ /* 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);
+
+ /* 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);
+ }
+ }
+}
+
+const char *mode_rw1[] = {
+ "r", "rb", "r+", "rb+", "r+b",
+ "w+", "wb+",
+ NULL
+};
+
+/* 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);
+ }
+ }
+ }
+}
+
+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);
+ ATF_TP_ADD_TC(tp, test12);
+ ATF_TP_ADD_TC(tp, test13);
+ ATF_TP_ADD_TC(tp, test14);
+ 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);
+
+ 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..c5b8921
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c
@@ -0,0 +1,442 @@
+/* $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);
+ ATF_TP_ADD_TC(tp, fopen_regular);
+ 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..95b4b2c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c
@@ -0,0 +1,194 @@
+/* $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>
+
+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];
+
+ 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..fea35a7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c
@@ -0,0 +1,81 @@
+/* $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;
+
+ /* 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..b2f91c4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c
@@ -0,0 +1,178 @@
+/* $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 *);
+
+static int dso_handle_1;
+static int dso_handle_2;
+static int dso_handle_3;
+
+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));
+ 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);
+ 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..074e4dd
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c
@@ -0,0 +1,127 @@
+/* $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>
+
+#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..17258f5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c
@@ -0,0 +1,239 @@
+/* $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>
+
+#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..35d6874
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c
@@ -0,0 +1,199 @@
+/* $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>
+
+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);
+ 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..099b3e7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c
@@ -0,0 +1,399 @@
+/* $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))
+
+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);
+}
+
+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();
+}
+
+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);
+}
+
+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);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, hsearch_basic);
+ ATF_TP_ADD_TC(tp, hsearch_duplicate);
+ ATF_TP_ADD_TC(tp, hsearch_nonexistent);
+ ATF_TP_ADD_TC(tp, hsearch_two);
+
+ ATF_TP_ADD_TC(tp, hsearch_r_basic);
+ ATF_TP_ADD_TC(tp, hsearch_r_duplicate);
+ ATF_TP_ADD_TC(tp, hsearch_r_nonexistent);
+ ATF_TP_ADD_TC(tp, hsearch_r_two);
+
+ 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..d7ebe1b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c
@@ -0,0 +1,335 @@
+/* $NetBSD: t_strtod.c,v 1.31 2012/09/26 07:24: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.
+ */
+
+/* Public domain, Otto Moerbeek <otto@drijf.net>, 2006. */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_strtod.c,v 1.31 2012/09/26 07:24:38 jruoho Exp $");
+
+#include <errno.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+#include <atf-c/config.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
+
+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);
+ ATF_REQUIRE(__isnanl(ld) != 0);
+ 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..6485a88
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c
@@ -0,0 +1,150 @@
+/* $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];
+const char goodResult[] = "7b405d24bc03195474c70ddae9e1f8fb";
+
+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;
+
+ srandom(0L);
+ 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..1e87af8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_memmem.c
@@ -0,0 +1,100 @@
+/* $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)
+{
+
+ expect(memmem(b2, lb2, p0, lp0) == b2);
+ expect(memmem(b0, lb0, p0, lp0) == b0);
+ 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..c0e9c06
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strerror.c
@@ -0,0 +1,135 @@
+/* $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>
+
+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..f15afc2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_access.c
@@ -0,0 +1,210 @@
+/* $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>
+
+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)
+{
+
+ 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..ce71708
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c
@@ -0,0 +1,313 @@
+/* $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>
+
+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");
+}
+
+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");
+}
+
+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);
+ ATF_TP_ADD_TC(tp, fchroot_basic);
+ ATF_TP_ADD_TC(tp, fchroot_err);
+ ATF_TP_ADD_TC(tp, fchroot_perm);
+
+ 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..69890fd
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c
@@ -0,0 +1,212 @@
+/* $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>
+
+#include <machine/int_limits.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "../../../h_macros.h"
+
+#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..d161ee3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_connect.c
@@ -0,0 +1,99 @@
+/* $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>
+
+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..a2623c0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_dup.c
@@ -0,0 +1,385 @@
+/* $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>
+
+static char path[] = "dup";
+static void check_mode(bool, bool, bool);
+
+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;
+ ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) != -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup3(-1, -1, O_CLOEXEC) == -1);
+
+ 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..3a2d9f7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c
@@ -0,0 +1,129 @@
+/* $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);
+ for (i = 0; i < 9; i++) {
+ 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;
+
+ makecontext(&uc[i], (void *)run, 10, i,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8);
+ }
+
+ 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..9a8ec8e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c
@@ -0,0 +1,171 @@
+/* $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;
+
+ 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..b384541
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c
@@ -0,0 +1,211 @@
+/* $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);
+
+ if (ot.it_value.tv_sec != 4 || ot.it_value.tv_usec != 3)
+ atf_tc_fail("setitimer(2) did not store old values");
+}
+
+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..6c4218a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c
@@ -0,0 +1,197 @@
+/* $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
+sighandler(int signo)
+{
+ /* 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.
+ */
+ atf_tc_expect_fail("PR kern/30115");
+
+ 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");
+ }
+
+ atf_tc_fail("anticipated error did not occur");
+}
+
+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;
+
+ /*
+ * 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..73ffbf8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c
@@ -0,0 +1,180 @@
+/* $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>
+#include <sys/drvctlio.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+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");
+
+ kq = *(int *)CMSG_DATA(msg);
+ printf("child (pid %d): received kq fd %d\n", getpid(), kq);
+ exit(0);
+ }
+
+ 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));
+
+ *(int *)CMSG_DATA(msg) = kq;
+
+ 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) {
+ ATF_REQUIRE_EQ_MSG(errno, EBADF, "errno is %d", errno);
+ atf_tc_skip("PR kern/46523");
+ }
+
+ 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..b58c4c9
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_link.c
@@ -0,0 +1,229 @@
+/* $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>
+
+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..71201d3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_listen.c
@@ -0,0 +1,134 @@
+/* $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>
+
+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..553207a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c
@@ -0,0 +1,318 @@
+/* $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>
+
+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);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, mincore(map, 0, vec) == -1);
+
+ 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;
+
+ addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE | MAP_WIRED, -1, (off_t)0);
+
+ if (addr == MAP_FAILED)
+ atf_tc_skip("could not mmap wired anonymous test area, system "
+ "might be low on memory");
+
+ 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);
+ ATF_REQUIRE(check_residency(addr2, npgs) == 0);
+
+ (void)memset(addr, 0, npgs * page);
+
+ ATF_REQUIRE(madvise(addr, npgs * page, MADV_FREE) == 0);
+ ATF_REQUIRE(check_residency(addr, npgs) == 0);
+
+ (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..b394b31
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mknod.c
@@ -0,0 +1,192 @@
+/* $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));
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, mknod(path, S_IFCHR, -1) == -1);
+
+ 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));
+
+ 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..52576f7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c
@@ -0,0 +1,244 @@
+/* $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 $");
+
+#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>
+
+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)
+{
+ unsigned long vmin = 0;
+ size_t len = sizeof(vmin);
+ void *invalid_ptr;
+ int null_errno = ENOMEM; /* error expected for NULL */
+
+ 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 */
+
+ 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;
+
+ if (mlock(buf, i) != -1 || errno != EAGAIN) {
+ (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)
+{
+ static const int flags = MAP_ANON | MAP_PRIVATE | MAP_WIRED;
+ 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);
+ 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);
+ ATF_REQUIRE(mlock(buf, page) != 0);
+ 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..c6b97b1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c
@@ -0,0 +1,505 @@
+/* $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>
+#include <machine/disklabel.h>
+
+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);
+}
+
+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);
+}
+
+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.
+ */
+ if (sysctlbyname("vm.user_va0_disable", &val, &len, NULL, 0) != 0)
+ atf_tc_fail("failed to read vm.user_va0_disable");
+
+ 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);
+
+ ATF_TP_ADD_TC(tp, mmap_block);
+ 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..c534e11
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c
@@ -0,0 +1,359 @@
+/* $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>
+
+#include "../common/exec_prot.h"
+
+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);
+}
+
+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;
+ }
+}
+
+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);
+ ATF_TP_ADD_TC(tp, mprotect_exec);
+ 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..1e74d60
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c
@@ -0,0 +1,358 @@
+/* $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>
+
+#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..e32be26
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c
@@ -0,0 +1,342 @@
+/* $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>
+
+#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..5493789
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c
@@ -0,0 +1,338 @@
+/* $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>
+
+#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..9743300
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msync.c
@@ -0,0 +1,237 @@
+/* $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.
+ */
+ ATF_REQUIRE(msync_sync("error", -1) != NULL);
+ ATF_REQUIRE(msync_sync("error", INT_MAX) != NULL);
+
+ 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);
+ ATF_REQUIRE(errno == EFAULT);
+}
+
+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..317d667
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c
@@ -0,0 +1,187 @@
+/* $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
+handler(int signo)
+{
+ /* 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..51f2240
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c
@@ -0,0 +1,188 @@
+/* $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);
+
+ ATF_REQUIRE(fcntl(3, F_CLOSEM) != -1);
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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];
+
+ err = fcntl(4, F_CLOSEM);
+ ATF_REQUIRE(err == 0);
+
+ 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.
+ */
+ rl.rlim_cur = 4;
+ err = setrlimit(RLIMIT_NOFILE, &rl);
+ ATF_REQUIRE(err == 0);
+
+ err = pipe2(filedes, O_CLOEXEC);
+ ATF_REQUIRE(err == -1);
+}
+
+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);
+}
+
+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);
+}
+
+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);
+ ATF_TP_ADD_TC(tp, pipe2_nosigpipe);
+ 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..7a786d2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_poll.c
@@ -0,0 +1,392 @@
+/* $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);
+}
+
+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);
+}
+
+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);
+ ATF_TP_ADD_TC(tp, pollts_basic);
+ ATF_TP_ADD_TC(tp, pollts_err);
+ ATF_TP_ADD_TC(tp, pollts_sigmask);
+
+ 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..10fd6d6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c
@@ -0,0 +1,186 @@
+/* $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;
+
+ (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);
+
+ 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;
+
+ 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..4316acf
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_select.c
@@ -0,0 +1,215 @@
+/* $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
+sig_handler(int signum)
+{
+ keep_going = 0;
+}
+
+static void
+sigchld(int signum)
+{
+}
+
+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..c760cfb
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c
@@ -0,0 +1,522 @@
+/* $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>
+#include <lwp.h>
+#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");
+}
+
+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);
+}
+
+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);
+
+ if (res.rlim_max == UINT64_MAX) /* Overflow. */
+ 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);
+ ATF_TP_ADD_TC(tp, setrlimit_nthr);
+
+ 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..8022353
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c
@@ -0,0 +1,154 @@
+/* $NetBSD: t_sigaction.c,v 1.2 2012/11/07 16:51:16 pgoyette 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.2 2012/11/07 16:51:16 pgoyette Exp $");
+
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+#include <atf-c/config.h>
+
+#include "../../../h_macros.h"
+
+static bool handler_called = false;
+
+static void
+handler(int signo)
+{
+ 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
+catch(int sig)
+{
+ 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..f9e0c63
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c
@@ -0,0 +1,103 @@
+/* $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
+handler(int signo, siginfo_t *info, void *data)
+{
+ 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;
+
+ if (sigqueue(0, SIGUSR1, sv) != 0)
+ 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..532629c3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c
@@ -0,0 +1,137 @@
+/* $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);
+
+ ATF_REQUIRE(fcntl(3, F_CLOSEM) != -1);
+
+ 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..0312e2f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_stat.c
@@ -0,0 +1,417 @@
+/* $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>
+
+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..ce1fb99
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c
@@ -0,0 +1,207 @@
+/* $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
+timer_signal_handler(int signo, siginfo_t *si, void *osi)
+{
+ 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..50a9cba
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_truncate.c
@@ -0,0 +1,175 @@
+/* $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>
+
+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)
+{
+
+ 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;
+ ATF_REQUIRE_ERRNO(EACCES, truncate("/usr/bin/fpr", 999) == -1);
+}
+
+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..38bff4c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c
@@ -0,0 +1,158 @@
+/* $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;
+ ATF_REQUIRE_ERRNO(EBUSY, unlink("/") == -1);
+
+ 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..2b1324a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_write.c
@@ -0,0 +1,226 @@
+/* $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>
+#include <sys/syslimits.h>
+
+#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>
+
+static void sighandler(int);
+
+static bool fail = false;
+static const char *path = "write";
+
+static void
+sighandler(int signo)
+{
+ 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..c0f9cdf
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/time/t_strptime.c
@@ -0,0 +1,252 @@
+/* $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);
+
+ 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)
+
+ 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 };
+
+ ATF_REQUIRE_MSG(strptime(buf, fmt, &tm) == NULL, "strptime(\"%s\", "
+ "\"%s\", &tm) should fail, but it didn't", buf, fmt);
+}
+
+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)
+{
+
+ 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);
+ h_fail("sunday", "%EA");
+ h_pass("SaturDay", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_fail("SaturDay", "%OA");
+}
+
+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..c455d33
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c
@@ -0,0 +1,60 @@
+/* $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>
+#include <sys/tls.h>
+
+#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..591823e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c
@@ -0,0 +1,113 @@
+/* $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>
+
+#include <sys/tls.h>
+
+#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..9d242ae
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c
@@ -0,0 +1,105 @@
+/* $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>
+
+#include <sys/tls.h>
+
+#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..7751a16
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c
@@ -0,0 +1,93 @@
+/* $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>
+
+#include <sys/tls.h>
+
+#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..da3b6f0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c
@@ -0,0 +1,53 @@
+/* $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 $");
+
+#include <sys/tls.h>
+
+#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..a12e07a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c
@@ -0,0 +1,56 @@
+/* $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>
+#include <sys/tls.h>
+
+#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..b5b5739
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libexecinfo/t_backtrace.c
@@ -0,0 +1,168 @@
+/* $NetBSD: t_backtrace.c,v 1.15 2014/05/01 03:46:11 joerg 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.15 2014/05/01 03:46:11 joerg Exp $");
+
+#include <atf-c.h>
+#include <atf-c/config.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..a7de9f6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_cbrt.c
@@ -0,0 +1,366 @@
+/* $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");
+}
+
+/*
+ * 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]);
+ z = powl(x[i], 1.0 / 3.0);
+
+ 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");
+}
+
+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);
+
+ 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);
+
+ 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..6d41097
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_exp.c
@@ -0,0 +1,567 @@
+/* $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;
+
+ 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;
+
+ 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..9dd001d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_ldexp.c
@@ -0,0 +1,481 @@
+/* $NetBSD: t_ldexp.c,v 1.13 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_ldexp.c,v 1.13 2014/03/12 21:40:07 martin Exp $");
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+#include <atf-c/config.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..de5a1c6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_log.c
@@ -0,0 +1,885 @@
+/* $NetBSD: t_log.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_log.c,v 1.11 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <atf-c/config.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..62b7235
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_pow.c
@@ -0,0 +1,669 @@
+/* $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>
+
+/*
+ * 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..390be9d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_precision.c
@@ -0,0 +1,76 @@
+/* $NetBSD: t_precision.c,v 1.1 2013/11/11 11:10:45 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 <sys/cdefs.h>
+__RCSID("$NetBSD: t_precision.c,v 1.1 2013/11/11 11:10:45 joerg Exp $");
+
+#include <atf-c.h>
+#include <atf-c/config.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);
+
+ 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);
+}
+
+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..586c2c3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libm/t_scalbn.c
@@ -0,0 +1,523 @@
+/* $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++) {
+ 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..2d4c91c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/h_atexit.c
@@ -0,0 +1,183 @@
+/* $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 *);
+
+static int dso_handle_1;
+static int dso_handle_2;
+static int dso_handle_3;
+
+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));
+ 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);
+ 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..1077806
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/h_cancel.c
@@ -0,0 +1,58 @@
+/* $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";
+
+ printf("Cancellation test: Self-cancellation and disabling.\n");
+
+ 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..9b79587
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_condwait.c
@@ -0,0 +1,142 @@
+/* $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"
+
+#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..21db871
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_detach.c
@@ -0,0 +1,91 @@
+/* $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);
+
+ /*
+ * 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..ab8806d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_fork.c
@@ -0,0 +1,107 @@
+/* $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()) {
+ exit(1);
+ }
+ 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);
+ exit(thread_survived ? 1 : 0);
+ }
+}
+
+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..7f6f834
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_join.c
@@ -0,0 +1,174 @@
+/* $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>
+
+#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;
+
+ 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..1b435c2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_mutex.c
@@ -0,0 +1,316 @@
+/* $NetBSD: t_mutex.c,v 1.6 2014/02/09 21:26:07 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_mutex.c,v 1.6 2014/02/09 21:26:07 jmmv Exp $");
+
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+#include <atf-c/config.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");
+#if defined(__powerpc__)
+ atf_tc_set_md_var(tc, "timeout", "40");
+#endif
+}
+ATF_TC_BODY(mutex2, tc)
+{
+ int count, count2;
+ pthread_t new;
+ void *joinval;
+
+ printf("1: Mutex-test 2\n");
+
+#if defined(__powerpc__)
+ atf_tc_expect_timeout("PR port-powerpc/44387");
+#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);
+
+#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
+}
+
+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");
+#if defined(__powerpc__)
+ atf_tc_set_md_var(tc, "timeout", "40");
+#endif
+}
+ATF_TC_BODY(mutex3, tc)
+{
+ int count, count2;
+ pthread_t new;
+ void *joinval;
+
+ printf("1: Mutex-test 3\n");
+
+#if defined(__powerpc__)
+ atf_tc_expect_timeout("PR port-powerpc/44387");
+#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);
+
+#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
+}
+
+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..575d5d7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_once.c
@@ -0,0 +1,196 @@
+/* $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
+
+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..467d182
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libpthread/t_sem.c
@@ -0,0 +1,307 @@
+/* $NetBSD: t_sem.c,v 1.7 2012/03/09 19:46:37 joerg 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.7 2012/03/09 19:46:37 joerg 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 <atf-c/config.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;
+
+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..b6fc4db
--- /dev/null
+++ b/contrib/netbsd-tests/lib/librt/t_sem.c
@@ -0,0 +1,175 @@
+/* $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");
+
+ 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");
+
+ 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