aboutsummaryrefslogtreecommitdiff
path: root/contrib/netbsd-tests/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/netbsd-tests/lib/libc')
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/aarch64/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/aarch64/return_one.S10
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/alpha/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/alpha/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/arm/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/arm/return_one.S11
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/hppa/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/hppa/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/i386/exec_prot_support.c65
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/i386/return_one.S10
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/ia64/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/ia64/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/m68k/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/m68k/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/mips/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/mips/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/or1k/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/or1k/return_one.S12
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/powerpc/exec_prot_support.c52
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/powerpc/return_one.S11
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/powerpc64/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/powerpc64/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/riscv/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/riscv/return_one.S11
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sh3/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sh3/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sparc/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sparc/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sparc64/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/sparc64/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/vax/exec_prot_support.c41
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/vax/return_one.S8
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/x86_64/exec_prot_support.c50
-rw-r--r--contrib/netbsd-tests/lib/libc/arch/x86_64/return_one.S10
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_faccessat.c185
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_fchmodat.c197
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_fchownat.c247
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_fexecve.c94
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_fstatat.c196
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_linkat.c217
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_mkdirat.c120
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_mkfifoat.c124
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_mknodat.c150
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_o_search.c278
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_openat.c165
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_readlinkat.c157
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_renameat.c152
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_symlinkat.c150
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_unlinkat.c176
-rw-r--r--contrib/netbsd-tests/lib/libc/c063/t_utimensat.c212
-rw-r--r--contrib/netbsd-tests/lib/libc/common/exec_prot.h61
-rw-r--r--contrib/netbsd-tests/lib/libc/db/README66
-rw-r--r--contrib/netbsd-tests/lib/libc/db/h_db.c731
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/db/t_db.sh940
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c58
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/isqemu.h63
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_fileactions.c104
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/gen/posix_spawn/h_nonexec.sh3
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawn.c50
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/h_spawnattr.c90
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c392
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c184
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawnattr.c173
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_alarm.c150
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_assert.c132
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_basedirname.c200
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_closefrom.c173
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_cpuset.c114
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_dir.c165
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c135
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c117
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_fnmatch.c167
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_fpclassify.c206
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c354
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c163
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_ftok.c107
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_getcwd.c153
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_getgrent.c181
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_glob.c287
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c318
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_isnan.c66
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_nice.c221
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_pause.c114
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_raise.c194
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_randomid.c93
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_realpath.c152
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c148
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_sethostname.c150
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_siginfo.c505
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_sleep.c350
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_syslog.c56
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_time.c117
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_ttyname.c191
-rw-r--r--contrib/netbsd-tests/lib/libc/gen/t_vis.c155
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/data/md5test-in7
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/data/md5test-out7
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/data/sha1test-in2
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/data/sha1test-out2
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/data/sha1test2-out1
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/h_hash.c187
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/hash/t_hash.sh67
-rw-r--r--contrib/netbsd-tests/lib/libc/hash/t_sha2.c257
-rw-r--r--contrib/netbsd-tests/lib/libc/inet/t_inet_network.c174
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_io.c193
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c277
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c98
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c209
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c157
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c58
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_wcspbrk.c62
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_wcsspn.c60
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_wcstod.c460
-rw-r--r--contrib/netbsd-tests/lib/libc/locale/t_wctomb.c212
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/gen_ether_subr25
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/README7
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4.exp36
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/basics_v4v6.exp42
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/h_gai.c186
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4.exp38
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_host_v4v6.exp56
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4.exp14
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/no_serv_v4v6.exp16
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/scoped.exp4
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4.exp13
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/sock_raw_v4v6.exp15
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4.exp6
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/spec_fam_v4v6.exp8
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/getaddrinfo/t_getaddrinfo.sh198
-rw-r--r--contrib/netbsd-tests/lib/libc/net/getaddrinfo/unsup_fam.exp2
-rw-r--r--contrib/netbsd-tests/lib/libc/net/h_dns_server.c415
-rw-r--r--contrib/netbsd-tests/lib/libc/net/h_hostent.c195
-rw-r--r--contrib/netbsd-tests/lib/libc/net/h_nsd_recurse.c107
-rw-r--r--contrib/netbsd-tests/lib/libc/net/h_protoent.c97
-rw-r--r--contrib/netbsd-tests/lib/libc/net/h_servent.c100
-rw-r--r--contrib/netbsd-tests/lib/libc/net/hosts11
-rw-r--r--contrib/netbsd-tests/lib/libc/net/resolv.conf1
-rw-r--r--contrib/netbsd-tests/lib/libc/net/t_ether_aton.c137
-rw-r--r--contrib/netbsd-tests/lib/libc/net/t_getprotoent.c233
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/t_hostent.sh240
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/t_nsdispatch.sh51
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/t_protoent.sh91
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/net/t_servent.sh111
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/README33
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/anchor.in33
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/README8
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/basic.dat216
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/categorization.dat62
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/forcedassoc.dat30
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/leftassoc.dat16
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/nullsubexpr.dat73
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/repetition.dat140
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/att/rightassoc.dat16
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/backref.in21
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/basic.in5
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/bracket.in55
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/c_comments.in17
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/complex.in23
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/error.in30
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/meta.in21
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/nospec.in7
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/paren.in19
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/regress.in9
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/repet_bounded.in45
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/repet_multi.in21
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/repet_ordinary.in10
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/startend.in9
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/subexp.in57
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/subtle.in21
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/word_bound.in13
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/data/zero.in7
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/debug.c278
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/main.c523
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/split.c344
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/t_exhaust.c224
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/regex/t_regex.sh73
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/t_regex_att.c639
-rw-r--r--contrib/netbsd-tests/lib/libc/regex/test_regex.h44
-rw-r--r--contrib/netbsd-tests/lib/libc/rpc/h_testbits.x21
-rw-r--r--contrib/netbsd-tests/lib/libc/rpc/t_rpc.c161
-rw-r--r--contrib/netbsd-tests/lib/libc/rpc/t_xdr.c129
-rw-r--r--contrib/netbsd-tests/lib/libc/setjmp/t_setjmp.c196
-rw-r--r--contrib/netbsd-tests/lib/libc/setjmp/t_threadjmp.c218
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_fgets.c46
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_getcwd.c47
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_gets.c43
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_memcpy.c48
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_memmove.c48
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_memset.c49
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_raw.c57
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_read.c65
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_readlink.c66
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c51
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c43
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_stpcpy.c49
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_stpncpy.c56
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_strcat.c46
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_strcpy.c45
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_strncat.c48
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_strncpy.c47
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_vsnprintf.c57
-rw-r--r--contrib/netbsd-tests/lib/libc/ssp/h_vsprintf.c55
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/ssp/t_ssp.sh459
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c93
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_fflush.c175
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c1181
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_fopen.c444
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_fputc.c194
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_mktemp.c54
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_popen.c135
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_printf.c204
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_scanf.c85
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c212
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c130
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c242
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_abs.c154
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/stdlib/t_atexit.sh54
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_atoi.c121
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_div.c98
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_exit.c186
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c211
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c250
-rwxr-xr-xcontrib/netbsd-tests/lib/libc/stdlib/t_getopt.sh123
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c407
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_mi_vector_hash.c95
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_posix_memalign.c88
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_random.c82
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c342
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c234
-rw-r--r--contrib/netbsd-tests/lib/libc/stdlib/t_system.c83
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_bm.c102
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_memchr.c194
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_memcpy.c162
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_memmem.c105
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_memset.c207
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_popcount.c198
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strcat.c153
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strchr.c292
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strcmp.c136
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strcpy.c124
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strcspn.c58
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strerror.c139
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_stresep.c72
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strlen.c199
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strpbrk.c62
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strrchr.c257
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_strspn.c60
-rw-r--r--contrib/netbsd-tests/lib/libc/string/t_swab.c95
-rw-r--r--contrib/netbsd-tests/lib/libc/sync/all_sync_ops_linkable.c168
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_access.c214
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_chroot.c321
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c220
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_clone.c252
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_connect.c103
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_dup.c405
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_fsync.c120
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getcontext.c143
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getgroups.c174
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getitimer.c216
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getlogin.c237
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getpid.c134
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getrusage.c210
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_getsid.c119
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_gettimeofday.c86
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_issetugid.c148
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_kevent.c206
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_kill.c312
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_link.c233
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_listen.c138
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c247
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_lwp_ctl.c74
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mincore.c336
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_minherit.c200
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mkdir.c210
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mkfifo.c276
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mknod.c202
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mlock.c286
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mmap.c524
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_mprotect.c365
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgctl.c362
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgget.c292
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c346
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c342
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_msync.c248
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c191
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_pipe.c163
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_pipe2.c210
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_poll.c396
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c165
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_recvmmsg.c161
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_revoke.c195
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_select.c223
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c532
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_setuid.c122
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_sigaction.c165
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c115
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c126
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_socketpair.c141
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_stat.c421
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c133
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_timer_create.c211
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_truncate.c188
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_ucontext.c76
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_umask.c205
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_unlink.c162
-rw-r--r--contrib/netbsd-tests/lib/libc/sys/t_write.c236
-rw-r--r--contrib/netbsd-tests/lib/libc/t_cdb.c158
-rw-r--r--contrib/netbsd-tests/lib/libc/t_convfp.c155
-rw-r--r--contrib/netbsd-tests/lib/libc/t_gdtoa.c67
-rw-r--r--contrib/netbsd-tests/lib/libc/termios/t_tcsetpgrp.c87
-rw-r--r--contrib/netbsd-tests/lib/libc/time/t_mktime.c155
-rw-r--r--contrib/netbsd-tests/lib/libc/time/t_strptime.c281
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c62
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c115
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c107
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_static.c95
-rw-r--r--contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c55
-rw-r--r--contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c58
-rw-r--r--contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c174
-rw-r--r--contrib/netbsd-tests/lib/libc/ttyio/t_ttyio.c163
319 files changed, 45532 insertions, 0 deletions
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 000000000000..56a1be86c30b
--- /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 000000000000..d2379828404f
--- /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 000000000000..ba1cd8b0625c
--- /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 000000000000..530887685f21
--- /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 000000000000..ba1cd8b0625c
--- /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 000000000000..18800e2953d8
--- /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 000000000000..ba1cd8b0625c
--- /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 000000000000..530887685f21
--- /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 000000000000..11a20f55ca01
--- /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 000000000000..f80fd7430881
--- /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 000000000000..ba1cd8b0625c
--- /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 000000000000..530887685f21
--- /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 000000000000..ba1cd8b0625c
--- /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 000000000000..530887685f21
--- /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 000000000000..474cfc742f69
--- /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 000000000000..3495260d6f68
--- /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 000000000000..623456b9a251
--- /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 000000000000..ba3d678974f9
--- /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 000000000000..81c1d8677baa
--- /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 000000000000..d40298e11dcc
--- /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 000000000000..474cfc742f69
--- /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 000000000000..3495260d6f68
--- /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 000000000000..91c5ff420088
--- /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 000000000000..43ddd2c51822
--- /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 000000000000..474cfc742f69
--- /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 000000000000..3495260d6f68
--- /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 000000000000..474cfc742f69
--- /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 000000000000..3495260d6f68
--- /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 000000000000..474cfc742f69
--- /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 000000000000..3495260d6f68
--- /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 000000000000..474cfc742f69
--- /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 000000000000..3495260d6f68
--- /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 000000000000..2d8363d1aec0
--- /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 000000000000..090300113daf
--- /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 000000000000..c9e0cc803158
--- /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 000000000000..462d53d9e961
--- /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 000000000000..80c760683eb9
--- /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 000000000000..d557b00d92c2
--- /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 000000000000..a48cd5781384
--- /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 000000000000..b49a3f0175a1
--- /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 000000000000..23c53d79a46f
--- /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 000000000000..1ae023c3f4a6
--- /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 000000000000..b04a1595d6e5
--- /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 000000000000..d9dbe19e899f
--- /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 000000000000..79b5f38d81fd
--- /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 000000000000..d354ff59b886
--- /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 000000000000..e297f2a629af
--- /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 000000000000..d62f28912d5a
--- /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 000000000000..79aa7aa2bf70
--- /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 000000000000..9f21fd6f126a
--- /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 000000000000..6e17f97a2c12
--- /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 000000000000..68f0ec7a1c1a
--- /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 000000000000..dfb13859d3f2
--- /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 000000000000..d25650855d36
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/db/t_db.sh
@@ -0,0 +1,940 @@
+# $NetBSD: t_db.sh,v 1.4 2013/07/29 10:43:15 skrll Exp $
+#
+# Copyright (c) 2008 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+prog()
+{
+ echo $(atf_get_srcdir)/h_db
+}
+
+dict()
+{
+ if [ -f /usr/share/dict/words ]; then
+ echo /usr/share/dict/words
+ elif [ -f /usr/dict/words ]; then
+ echo /usr/dict/words
+ else
+ atf_fail "no dictionary found"
+ fi
+}
+
+# Begin FreeBSD
+dict()
+{
+ if [ -f /usr/share/dict/words ]; then
+ echo /usr/share/dict/words
+ else
+ echo /nonexistent
+ atf_skip "Test requires dict/words"
+ fi
+}
+# End FreeBSD
+
+SEVEN_SEVEN="abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg|abcdefg"
+
+atf_test_case small_btree
+small_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database using small keys and small data" \
+ "pairs: takes the first hundred entries in the dictionary," \
+ "and makes them be key/data pairs."
+}
+small_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ sed 200q $(dict) >exp
+
+ for i in `sed 200q $(dict)`; do
+ echo p
+ echo k$i
+ echo d$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" btree in
+}
+
+atf_test_case small_hash
+small_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database using small keys and small data" \
+ "pairs: takes the first hundred entries in the dictionary," \
+ "and makes them be key/data pairs."
+}
+small_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ sed 200q $(dict) >exp
+
+ for i in `sed 200q $(dict)`; do
+ echo p
+ echo k$i
+ echo d$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" hash in
+}
+
+atf_test_case small_recno
+small_recno_head()
+{
+ atf_set "descr" \
+ "Checks recno database using small keys and small data" \
+ "pairs: takes the first hundred entries in the dictionary," \
+ "and makes them be key/data pairs."
+}
+small_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ sed 200q $(dict) >exp
+
+ sed 200q $(dict) |
+ awk '{
+ ++i;
+ printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case medium_btree
+medium_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database using small keys and medium" \
+ "data pairs: takes the first 200 entries in the" \
+ "dictionary, and gives them each a medium size data entry."
+}
+medium_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
+
+ for i in $(sed 200q $(dict)); do
+ echo p
+ echo k$i
+ echo d$mdata
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" btree in
+}
+
+atf_test_case medium_hash
+medium_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database using small keys and medium" \
+ "data pairs: takes the first 200 entries in the" \
+ "dictionary, and gives them each a medium size data entry."
+}
+medium_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
+
+ for i in $(sed 200q $(dict)); do
+ echo p
+ echo k$i
+ echo d$mdata
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" hash in
+}
+
+atf_test_case medium_recno
+medium_recno_head()
+{
+ atf_set "descr" \
+ "Checks recno database using small keys and medium" \
+ "data pairs: takes the first 200 entries in the" \
+ "dictionary, and gives them each a medium size data entry."
+}
+medium_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i) print $0 }' >exp
+
+ echo $mdata |
+ awk '{ for (i = 1; i < 201; ++i)
+ printf("p\nk%d\nd%s\ng\nk%d\n", i, $0, i);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case big_btree
+big_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database using small keys and big data" \
+ "pairs: inserts the programs in /bin with their paths" \
+ "as their keys."
+}
+big_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ (find /bin -type f -print | xargs cat) >exp
+
+ for psize in 512 16384 65536; do
+ echo "checking page size: $psize"
+
+ for i in `find /bin -type f -print`; do
+ echo p
+ echo k$i
+ echo D$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check "$(prog)" -o out btree in
+ cmp -s exp out || atf_fail "test failed for page size: $psize"
+ done
+}
+
+atf_test_case big_hash
+big_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database using small keys and big data" \
+ "pairs: inserts the programs in /bin with their paths" \
+ "as their keys."
+}
+big_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ (find /bin -type f -print | xargs cat) >exp
+
+ for i in `find /bin -type f -print`; do
+ echo p
+ echo k$i
+ echo D$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check "$(prog)" -o out hash in
+ cmp -s exp out || atf_fail "test failed"
+}
+
+atf_test_case big_recno
+big_recno_head()
+{
+ atf_set "descr" \
+ "Checks recno database using small keys and big data" \
+ "pairs: inserts the programs in /bin with their paths" \
+ "as their keys."
+}
+big_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ (find /bin -type f -print | xargs cat) >exp
+
+ find /bin -type f -print |
+ awk '{
+ ++i;
+ printf("p\nk%d\nD%s\ng\nk%d\n", i, $0, i);
+ }' >in
+
+ for psize in 512 16384 65536; do
+ echo "checking page size: $psize"
+
+ atf_check "$(prog)" -o out recno in
+ cmp -s exp out || atf_fail "test failed for page size: $psize"
+ done
+}
+
+atf_test_case random_recno
+random_recno_head()
+{
+ atf_set "descr" "Checks recno database using random entries"
+}
+random_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 37; i <= 37 + 88 * 17; i += 17) {
+ if (i % 41)
+ s = substr($0, 1, i % 41);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ for (i = 1; i <= 15; ++i) {
+ if (i % 41)
+ s = substr($0, 1, i % 41);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ for (i = 19234; i <= 19234 + 61 * 27; i += 27) {
+ if (i % 41)
+ s = substr($0, 1, i % 41);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ exit
+ }' >exp
+
+ cat exp |
+ awk 'BEGIN {
+ i = 37;
+ incr = 17;
+ }
+ {
+ printf("p\nk%d\nd%s\n", i, $0);
+ if (i == 19234 + 61 * 27)
+ exit;
+ if (i == 37 + 88 * 17) {
+ i = 1;
+ incr = 1;
+ } else if (i == 15) {
+ i = 19234;
+ incr = 27;
+ } else
+ i += incr;
+ }
+ END {
+ for (i = 37; i <= 37 + 88 * 17; i += 17)
+ printf("g\nk%d\n", i);
+ for (i = 1; i <= 15; ++i)
+ printf("g\nk%d\n", i);
+ for (i = 19234; i <= 19234 + 61 * 27; i += 27)
+ printf("g\nk%d\n", i);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case reverse_recno
+reverse_recno_head()
+{
+ atf_set "descr" "Checks recno database using reverse order entries"
+}
+reverse_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk ' {
+ for (i = 1500; i; --i) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ exit;
+ }' >exp
+
+ cat exp |
+ awk 'BEGIN {
+ i = 1500;
+ }
+ {
+ printf("p\nk%d\nd%s\n", i, $0);
+ --i;
+ }
+ END {
+ for (i = 1500; i; --i)
+ printf("g\nk%d\n", i);
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case alternate_recno
+alternate_recno_head()
+{
+ atf_set "descr" "Checks recno database using alternating order entries"
+}
+alternate_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk ' {
+ for (i = 1; i < 1200; i += 2) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ for (i = 2; i < 1200; i += 2) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("input key %d: %s\n", i, s);
+ }
+ exit;
+ }' >exp
+
+ cat exp |
+ awk 'BEGIN {
+ i = 1;
+ even = 0;
+ }
+ {
+ printf("p\nk%d\nd%s\n", i, $0);
+ i += 2;
+ if (i >= 1200) {
+ if (even == 1)
+ exit;
+ even = 1;
+ i = 2;
+ }
+ }
+ END {
+ for (i = 1; i < 1200; ++i)
+ printf("g\nk%d\n", i);
+ }' >in
+
+ atf_check "$(prog)" -o out recno in
+
+ sort -o exp exp
+ sort -o out out
+
+ cmp -s exp out || atf_fail "test failed"
+}
+
+h_delete()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ type=$1
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 120; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ }' >exp
+
+ cat exp |
+ awk '{
+ printf("p\nk%d\nd%s\n", ++i, $0);
+ }
+ END {
+ printf("fR_NEXT\n");
+ for (i = 1; i <= 120; ++i)
+ printf("s\n");
+ printf("fR_CURSOR\ns\nkXX\n");
+ printf("r\n");
+ printf("fR_NEXT\ns\n");
+ printf("fR_CURSOR\ns\nk1\n");
+ printf("r\n");
+ printf("fR_FIRST\ns\n");
+ }' >in
+
+ # For btree, the records are ordered by the string representation
+ # of the key value. So sort the expected output file accordingly,
+ # and set the seek_last key to the last expected key value.
+
+ if [ "$type" = "btree" ] ; then
+ sed -e 's/kXX/k99/' < in > tmp
+ mv tmp in
+ sort -d -k4 < exp > tmp
+ mv tmp exp
+ echo $SEVEN_SEVEN |
+ awk '{
+ printf("%05d: input key %d: %s\n", 99, 99, $0);
+ printf("seq failed, no such key\n");
+ printf("%05d: input key %d: %s\n", 1, 1, $0);
+ printf("%05d: input key %d: %s\n", 10, 10, $0);
+ exit;
+ }' >> exp
+ else
+ # For recno, records are ordered by numerical key value. No sort
+ # is needed, but still need to set proper seek_last key value.
+ sed -e 's/kXX/k120/' < in > tmp
+ mv tmp in
+ echo $SEVEN_SEVEN |
+ awk '{
+ printf("%05d: input key %d: %s\n", 120, 120, $0);
+ printf("seq failed, no such key\n");
+ printf("%05d: input key %d: %s\n", 1, 1, $0);
+ printf("%05d: input key %d: %s\n", 2, 2, $0);
+ exit;
+ }' >> exp
+ fi
+
+ atf_check "$(prog)" -o out $type in
+ atf_check -o file:exp cat out
+}
+
+atf_test_case delete_btree
+delete_btree_head()
+{
+ atf_set "descr" "Checks removing records in btree database"
+}
+delete_btree_body()
+{
+ h_delete btree
+}
+
+atf_test_case delete_recno
+delete_recno_head()
+{
+ atf_set "descr" "Checks removing records in recno database"
+}
+delete_recno_body()
+{
+ h_delete recno
+}
+
+h_repeated()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo "" |
+ awk 'BEGIN {
+ for (i = 1; i <= 10; ++i) {
+ printf("p\nkkey1\nD/bin/sh\n");
+ printf("p\nkkey2\nD/bin/csh\n");
+ if (i % 8 == 0) {
+ printf("c\nkkey2\nD/bin/csh\n");
+ printf("c\nkkey1\nD/bin/sh\n");
+ printf("e\t%d of 10 (comparison)\n", i);
+ } else
+ printf("e\t%d of 10 \n", i);
+ printf("r\nkkey1\nr\nkkey2\n");
+ }
+ }' >in
+
+ $(prog) btree in
+}
+
+atf_test_case repeated_btree
+repeated_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database with repeated small keys and" \
+ "big data pairs. Makes sure that overflow pages are reused"
+}
+repeated_btree_body()
+{
+ h_repeated btree
+}
+
+atf_test_case repeated_hash
+repeated_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database with repeated small keys and" \
+ "big data pairs. Makes sure that overflow pages are reused"
+}
+repeated_hash_body()
+{
+ h_repeated hash
+}
+
+atf_test_case duplicate_btree
+duplicate_btree_head()
+{
+ atf_set "descr" "Checks btree database with duplicate keys"
+}
+duplicate_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 543; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' >exp
+
+ cat exp |
+ awk '{
+ if (i++ % 2)
+ printf("p\nkduplicatekey\nd%s\n", $0);
+ else
+ printf("p\nkunique%dkey\nd%s\n", i, $0);
+ }
+ END {
+ printf("o\n");
+ }' >in
+
+ atf_check -o file:exp -x "$(prog) -iflags=1 btree in | sort"
+}
+
+h_cursor_flags()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ type=$1
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 20; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' >exp
+
+ # Test that R_CURSOR doesn't succeed before cursor initialized
+ cat exp |
+ awk '{
+ if (i == 10)
+ exit;
+ printf("p\nk%d\nd%s\n", ++i, $0);
+ }
+ END {
+ printf("fR_CURSOR\nr\n");
+ printf("eR_CURSOR SHOULD HAVE FAILED\n");
+ }' >in
+
+ atf_check -o ignore -e ignore -s ne:0 "$(prog)" -o out $type in
+ atf_check -s ne:0 test -s out
+
+ cat exp |
+ awk '{
+ if (i == 10)
+ exit;
+ printf("p\nk%d\nd%s\n", ++i, $0);
+ }
+ END {
+ printf("fR_CURSOR\np\nk1\ndsome data\n");
+ printf("eR_CURSOR SHOULD HAVE FAILED\n");
+ }' >in
+
+ atf_check -o ignore -e ignore -s ne:0 "$(prog)" -o out $type in
+ atf_check -s ne:0 test -s out
+}
+
+atf_test_case cursor_flags_btree
+cursor_flags_btree_head()
+{
+ atf_set "descr" \
+ "Checks use of cursor flags without initialization in btree database"
+}
+cursor_flags_btree_body()
+{
+ h_cursor_flags btree
+}
+
+atf_test_case cursor_flags_recno
+cursor_flags_recno_head()
+{
+ atf_set "descr" \
+ "Checks use of cursor flags without initialization in recno database"
+}
+cursor_flags_recno_body()
+{
+ h_cursor_flags recno
+}
+
+atf_test_case reverse_order_recno
+reverse_order_recno_head()
+{
+ atf_set "descr" "Checks reverse order inserts in recno database"
+}
+reverse_order_recno_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 779; ++i)
+ printf("%05d: input key %d: %s\n", i, i, $0);
+ exit;
+ }' >exp
+
+ cat exp |
+ awk '{
+ if (i == 0) {
+ i = 1;
+ printf("p\nk1\nd%s\n", $0);
+ printf("%s\n", "fR_IBEFORE");
+ } else
+ printf("p\nk1\nd%s\n", $0);
+ }
+ END {
+ printf("or\n");
+ }' >in
+
+ atf_check -o file:exp "$(prog)" recno in
+}
+
+atf_test_case small_page_btree
+small_page_btree_head()
+{
+ atf_set "descr" \
+ "Checks btree database with lots of keys and small page" \
+ "size: takes the first 20000 entries in the dictionary," \
+ "reverses them, and gives them each a small size data" \
+ "entry. Uses a small page size to make sure the btree" \
+ "split code gets hammered."
+}
+small_page_btree_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ mdata=abcdefghijklmnopqrstuvwxy
+ echo $mdata |
+ awk '{ for (i = 1; i < 20001; ++i) print $0 }' >exp
+
+ for i in `sed 20000q $(dict) | rev`; do
+ echo p
+ echo k$i
+ echo d$mdata
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" -i psize=512 btree in
+}
+
+h_byte_orders()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ type=$1
+
+ sed 50q $(dict) >exp
+ for order in 1234 4321; do
+ for i in `sed 50q $(dict)`; do
+ echo p
+ echo k$i
+ echo d$i
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" -ilorder=$order -f byte.file $type in
+
+ for i in `sed 50q $(dict)`; do
+ echo g
+ echo k$i
+ done >in
+
+ atf_check -o file:exp "$(prog)" -s -ilorder=$order -f byte.file $type in
+ done
+}
+
+atf_test_case byte_orders_btree
+byte_orders_btree_head()
+{
+ atf_set "descr" "Checks btree database using differing byte orders"
+}
+byte_orders_btree_body()
+{
+ h_byte_orders btree
+}
+
+atf_test_case byte_orders_hash
+byte_orders_hash_head()
+{
+ atf_set "descr" "Checks hash database using differing byte orders"
+}
+byte_orders_hash_body()
+{
+ h_byte_orders hash
+}
+
+h_bsize_ffactor()
+{
+ bsize=$1
+ ffactor=$2
+
+ echo "bucketsize $bsize, fill factor $ffactor"
+ atf_check -o file:exp "$(prog)" "-ibsize=$bsize,\
+ffactor=$ffactor,nelem=25000,cachesize=65536" hash in
+}
+
+atf_test_case bsize_ffactor
+bsize_ffactor_head()
+{
+ atf_set "timeout" "480"
+ atf_set "descr" "Checks hash database with various" \
+ "bucketsizes and fill factors"
+}
+bsize_ffactor_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ echo $SEVEN_SEVEN |
+ awk '{
+ for (i = 1; i <= 10000; ++i) {
+ if (i % 34)
+ s = substr($0, 1, i % 34);
+ else
+ s = substr($0, 1);
+ printf("%s\n", s);
+ }
+ exit;
+
+ }' >exp
+
+ sed 10000q $(dict) |
+ awk 'BEGIN {
+ ds="'$SEVEN_SEVEN'"
+ }
+ {
+ if (++i % 34)
+ s = substr(ds, 1, i % 34);
+ else
+ s = substr(ds, 1);
+ printf("p\nk%s\nd%s\n", $0, s);
+ }' >in
+
+ sed 10000q $(dict) |
+ awk '{
+ ++i;
+ printf("g\nk%s\n", $0);
+ }' >>in
+
+ h_bsize_ffactor 256 11
+ h_bsize_ffactor 256 14
+ h_bsize_ffactor 256 21
+
+ h_bsize_ffactor 512 21
+ h_bsize_ffactor 512 28
+ h_bsize_ffactor 512 43
+
+ h_bsize_ffactor 1024 43
+ h_bsize_ffactor 1024 57
+ h_bsize_ffactor 1024 85
+
+ h_bsize_ffactor 2048 85
+ h_bsize_ffactor 2048 114
+ h_bsize_ffactor 2048 171
+
+ h_bsize_ffactor 4096 171
+ h_bsize_ffactor 4096 228
+ h_bsize_ffactor 4096 341
+
+ h_bsize_ffactor 8192 341
+ h_bsize_ffactor 8192 455
+ h_bsize_ffactor 8192 683
+}
+
+# FIXME: what does it test?
+atf_test_case four_char_hash
+four_char_hash_head()
+{
+ atf_set "descr" \
+ "Checks hash database with 4 char key and" \
+ "value insert on a 65536 bucket size"
+}
+four_char_hash_body()
+{
+ TMPDIR="$(pwd)/db_dir"; export TMPDIR
+ mkdir ${TMPDIR}
+
+ cat >in <<EOF
+p
+k1234
+d1234
+r
+k1234
+EOF
+
+ # Begin FreeBSD
+ if true; then
+ atf_check "$(prog)" -i bsize=32768 hash in
+ else
+ # End FreeBSD
+ atf_check "$(prog)" -i bsize=65536 hash in
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case small_btree
+ atf_add_test_case small_hash
+ atf_add_test_case small_recno
+ atf_add_test_case medium_btree
+ atf_add_test_case medium_hash
+ atf_add_test_case medium_recno
+ atf_add_test_case big_btree
+ atf_add_test_case big_hash
+ atf_add_test_case big_recno
+ atf_add_test_case random_recno
+ atf_add_test_case reverse_recno
+ atf_add_test_case alternate_recno
+ atf_add_test_case delete_btree
+ atf_add_test_case delete_recno
+ atf_add_test_case repeated_btree
+ atf_add_test_case repeated_hash
+ atf_add_test_case duplicate_btree
+ atf_add_test_case cursor_flags_btree
+ atf_add_test_case cursor_flags_recno
+ atf_add_test_case reverse_order_recno
+ atf_add_test_case small_page_btree
+ atf_add_test_case byte_orders_btree
+ atf_add_test_case byte_orders_hash
+ atf_add_test_case bsize_ffactor
+ atf_add_test_case four_char_hash
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c b/contrib/netbsd-tests/lib/libc/gen/execve/t_execve.c
new file mode 100644
index 000000000000..32de6e765780
--- /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 000000000000..7d73a227ce79
--- /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 000000000000..d92337074481
--- /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 000000000000..deee6fe720f9
--- /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 000000000000..dbf5da5efa11
--- /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 000000000000..1f13c54c9de0
--- /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 000000000000..5bbf337efd9e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_fileactions.c
@@ -0,0 +1,392 @@
+/* $NetBSD: t_fileactions.c,v 1.5 2012/04/09 19:42:07 martin Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles Zhang <charles@NetBSD.org> and
+ * Martin Husemann <martin@NetBSD.org>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifdef __FreeBSD__
+#include <sys/stat.h>
+#endif
+#include <atf-c.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <spawn.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+
+ATF_TC(t_spawn_openmode);
+
+ATF_TC_HEAD(t_spawn_openmode, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test the proper handling of 'mode' for 'open' fileactions");
+ atf_tc_set_md_var(tc, "require.progs", "/bin/cat");
+}
+
+static off_t
+filesize(const char * restrict fname)
+{
+ struct stat st;
+ int err;
+
+ err = stat(fname, &st);
+ ATF_REQUIRE(err == 0);
+ return st.st_size;
+}
+
+#define TESTFILE "./the_input_data"
+#define CHECKFILE "./the_output_data"
+#define TESTCONTENT "marry has a little lamb"
+
+static void
+make_testfile(const char *restrict file)
+{
+ FILE *f;
+ size_t written;
+
+ f = fopen(file, "w");
+ ATF_REQUIRE(f != NULL);
+ written = fwrite(TESTCONTENT, 1, strlen(TESTCONTENT), f);
+ fclose(f);
+ ATF_REQUIRE(written == strlen(TESTCONTENT));
+}
+
+static void
+empty_outfile(const char *restrict filename)
+{
+ FILE *f;
+
+ f = fopen(filename, "w");
+ ATF_REQUIRE(f != NULL);
+ fclose(f);
+}
+
+ATF_TC_BODY(t_spawn_openmode, tc)
+{
+ int status, err;
+ pid_t pid;
+ size_t insize, outsize;
+ char * const args[2] = { __UNCONST("cat"), NULL };
+ posix_spawn_file_actions_t fa;
+
+ /*
+ * try a "cat < testfile > checkfile"
+ */
+ make_testfile(TESTFILE);
+ unlink(CHECKFILE);
+
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdin),
+ TESTFILE, O_RDONLY, 0);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdout),
+ CHECKFILE, O_WRONLY|O_CREAT, 0600);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ /* ok, wait for the child to finish */
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
+
+ /* now check that input and output have the same size */
+ insize = filesize(TESTFILE);
+ outsize = filesize(CHECKFILE);
+ ATF_REQUIRE(insize == strlen(TESTCONTENT));
+ ATF_REQUIRE(insize == outsize);
+
+ /*
+ * try a "cat < testfile >> checkfile"
+ */
+ make_testfile(TESTFILE);
+ make_testfile(CHECKFILE);
+
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdin),
+ TESTFILE, O_RDONLY, 0);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdout),
+ CHECKFILE, O_WRONLY|O_APPEND, 0);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ /* ok, wait for the child to finish */
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
+
+ /* now check that output is twice as long as input */
+ insize = filesize(TESTFILE);
+ outsize = filesize(CHECKFILE);
+ ATF_REQUIRE(insize == strlen(TESTCONTENT));
+ ATF_REQUIRE(insize*2 == outsize);
+
+ /*
+ * try a "cat < testfile > checkfile" with input and output swapped
+ */
+ make_testfile(TESTFILE);
+ empty_outfile(CHECKFILE);
+
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdout),
+ TESTFILE, O_RDONLY, 0);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdin),
+ CHECKFILE, O_WRONLY, 0);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ /* ok, wait for the child to finish */
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_FAILURE);
+
+ /* now check that input and output are still the same size */
+ insize = filesize(TESTFILE);
+ outsize = filesize(CHECKFILE);
+ ATF_REQUIRE(insize == strlen(TESTCONTENT));
+ ATF_REQUIRE(outsize == 0);
+}
+
+ATF_TC(t_spawn_reopen);
+
+ATF_TC_HEAD(t_spawn_reopen, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "an open filehandle can be replaced by a 'open' fileaction");
+ atf_tc_set_md_var(tc, "require.progs", "/bin/cat");
+}
+
+ATF_TC_BODY(t_spawn_reopen, tc)
+{
+ int status, err;
+ pid_t pid;
+ char * const args[2] = { __UNCONST("cat"), NULL };
+ posix_spawn_file_actions_t fa;
+
+ /*
+ * make sure stdin is open in the parent
+ */
+ freopen("/dev/zero", "r", stdin);
+ /*
+ * now request an open for this fd again in the child
+ */
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, fileno(stdin),
+ "/dev/null", O_RDONLY, 0);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
+}
+
+ATF_TC(t_spawn_open_nonexistent);
+
+ATF_TC_HEAD(t_spawn_open_nonexistent, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "posix_spawn fails when a file to open does not exist");
+ atf_tc_set_md_var(tc, "require.progs", "/bin/cat");
+}
+
+ATF_TC_BODY(t_spawn_open_nonexistent, tc)
+{
+ int err, status;
+ pid_t pid;
+ char * const args[2] = { __UNCONST("cat"), NULL };
+ posix_spawn_file_actions_t fa;
+
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, STDIN_FILENO,
+ "./non/ex/ist/ent", O_RDONLY, 0);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ if (err == 0) {
+ /*
+ * The child has been created - it should fail and
+ * return exit code 127
+ */
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 127);
+ } else {
+ /*
+ * The error has been noticed early enough, no child has
+ * been run
+ */
+ ATF_REQUIRE(err == ENOENT);
+ }
+ posix_spawn_file_actions_destroy(&fa);
+}
+
+#ifdef __NetBSD__
+ATF_TC(t_spawn_open_nonexistent_diag);
+
+ATF_TC_HEAD(t_spawn_open_nonexistent_diag, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "posix_spawn fails when a file to open does not exist "
+ "and delivers proper diagnostic");
+ atf_tc_set_md_var(tc, "require.progs", "/bin/cat");
+}
+
+ATF_TC_BODY(t_spawn_open_nonexistent_diag, tc)
+{
+ int err;
+ pid_t pid;
+ char * const args[2] = { __UNCONST("cat"), NULL };
+ posix_spawnattr_t attr;
+ posix_spawn_file_actions_t fa;
+
+ posix_spawnattr_init(&attr);
+ /*
+ * POSIX_SPAWN_RETURNERROR is a NetBSD specific flag that
+ * will cause a "proper" return value from posix_spawn(2)
+ * instead of a (potential) success there and a 127 exit
+ * status from the child process (c.f. the non-diag variant
+ * of this test).
+ */
+ posix_spawnattr_setflags(&attr, POSIX_SPAWN_RETURNERROR);
+ posix_spawn_file_actions_init(&fa);
+ posix_spawn_file_actions_addopen(&fa, STDIN_FILENO,
+ "./non/ex/ist/ent", O_RDONLY, 0);
+ err = posix_spawn(&pid, "/bin/cat", &fa, &attr, args, NULL);
+ ATF_REQUIRE(err == ENOENT);
+ posix_spawn_file_actions_destroy(&fa);
+ posix_spawnattr_destroy(&attr);
+}
+#endif
+
+ATF_TC(t_spawn_fileactions);
+
+ATF_TC_HEAD(t_spawn_fileactions, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Tests various complex fileactions");
+}
+
+ATF_TC_BODY(t_spawn_fileactions, tc)
+{
+ int fd1, fd2, fd3, status, err;
+ pid_t pid;
+ char * const args[2] = { __UNCONST("h_fileactions"), NULL };
+ char helper[FILENAME_MAX];
+ posix_spawn_file_actions_t fa;
+
+ posix_spawn_file_actions_init(&fa);
+
+ closefrom(fileno(stderr)+1);
+
+ fd1 = open("/dev/null", O_RDONLY);
+ ATF_REQUIRE(fd1 == 3);
+
+ fd2 = open("/dev/null", O_WRONLY, O_CLOEXEC);
+ ATF_REQUIRE(fd2 == 4);
+
+ fd3 = open("/dev/null", O_WRONLY);
+ ATF_REQUIRE(fd3 == 5);
+
+ posix_spawn_file_actions_addclose(&fa, fd1);
+ posix_spawn_file_actions_addopen(&fa, 6, "/dev/null", O_RDWR, 0);
+ posix_spawn_file_actions_adddup2(&fa, 1, 7);
+
+ snprintf(helper, sizeof helper, "%s/h_fileactions",
+ atf_tc_get_config_var(tc, "srcdir"));
+ err = posix_spawn(&pid, helper, &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
+}
+
+ATF_TC(t_spawn_empty_fileactions);
+
+ATF_TC_HEAD(t_spawn_empty_fileactions, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "posix_spawn with empty fileactions (PR kern/46038)");
+ atf_tc_set_md_var(tc, "require.progs", "/bin/cat");
+}
+
+ATF_TC_BODY(t_spawn_empty_fileactions, tc)
+{
+ int status, err;
+ pid_t pid;
+ char * const args[2] = { __UNCONST("cat"), NULL };
+ posix_spawn_file_actions_t fa;
+ size_t insize, outsize;
+
+ /*
+ * try a "cat < testfile > checkfile", but set up stdin/stdout
+ * already in the parent and pass empty file actions to the child.
+ */
+ make_testfile(TESTFILE);
+ unlink(CHECKFILE);
+
+ freopen(TESTFILE, "r", stdin);
+ freopen(CHECKFILE, "w", stdout);
+
+ posix_spawn_file_actions_init(&fa);
+ err = posix_spawn(&pid, "/bin/cat", &fa, NULL, args, NULL);
+ posix_spawn_file_actions_destroy(&fa);
+
+ ATF_REQUIRE(err == 0);
+
+ /* ok, wait for the child to finish */
+ waitpid(pid, &status, 0);
+ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS);
+
+ /* now check that input and output have the same size */
+ insize = filesize(TESTFILE);
+ outsize = filesize(CHECKFILE);
+ ATF_REQUIRE(insize == strlen(TESTCONTENT));
+ ATF_REQUIRE(insize == outsize);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_spawn_fileactions);
+ ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, t_spawn_open_nonexistent_diag);
+#endif
+ ATF_TP_ADD_TC(tp, t_spawn_reopen);
+ ATF_TP_ADD_TC(tp, t_spawn_openmode);
+ ATF_TP_ADD_TC(tp, t_spawn_empty_fileactions);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c b/contrib/netbsd-tests/lib/libc/gen/posix_spawn/t_spawn.c
new file mode 100644
index 000000000000..178374b863df
--- /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 000000000000..eb99c41345c0
--- /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 000000000000..d9e903d1e722
--- /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 000000000000..140417a38aa8
--- /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 000000000000..6c82cb471c27
--- /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 000000000000..75ebabb75626
--- /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 000000000000..9eca03bae2b0
--- /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 000000000000..81412c1ae898
--- /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 000000000000..ef372f76762b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_floatunditf.c
@@ -0,0 +1,135 @@
+/* $NetBSD: t_floatunditf.c,v 1.6 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <inttypes.h>
+#include <math.h>
+
+#ifdef __HAVE_LONG_DOUBLE
+static const struct {
+ uint64_t u64;
+ long double ld;
+} testcases[] = {
+ { 0xffffffffffffffffULL, 0xf.fffffffffffffffp+60L },
+ { 0xfffffffffffffffeULL, 0xf.ffffffffffffffep+60L },
+ { 0xfffffffffffffffdULL, 0xf.ffffffffffffffdp+60L },
+ { 0xfffffffffffffffcULL, 0xf.ffffffffffffffcp+60L },
+ { 0x7fffffffffffffffULL, 0xf.ffffffffffffffep+59L },
+ { 0x3fffffffffffffffULL, 0xf.ffffffffffffffcp+58L },
+ { 0x1fffffffffffffffULL, 0xf.ffffffffffffff8p+57L },
+ { 0xfffffffffffffffULL, 0xf.ffffffffffffffp+56L },
+ { 0x7ffffffffffffffULL, 0xf.fffffffffffffep+55L },
+ { 0x3ffffffffffffffULL, 0xf.fffffffffffffcp+54L },
+ { 0x1ffffffffffffffULL, 0xf.fffffffffffff8p+53L },
+ { 0xffffffffffffffULL, 0xf.fffffffffffffp+52L },
+ { 0x7fffffffffffffULL, 0xf.ffffffffffffep+51L },
+ { 0x3fffffffffffffULL, 0xf.ffffffffffffcp+50L },
+ { 0x1fffffffffffffULL, 0xf.ffffffffffff8p+49L },
+ { 0xfffffffffffffULL, 0xf.ffffffffffffp+48L },
+ { 0x7ffffffffffffULL, 0xf.fffffffffffep+47L },
+ { 0x3ffffffffffffULL, 0xf.fffffffffffcp+46L },
+ { 0x1ffffffffffffULL, 0xf.fffffffffff8p+45L },
+ { 0xffffffffffffULL, 0xf.fffffffffffp+44L },
+ { 0x7fffffffffffULL, 0xf.ffffffffffep+43L },
+ { 0x3fffffffffffULL, 0xf.ffffffffffcp+42L },
+ { 0x1fffffffffffULL, 0xf.ffffffffff8p+41L },
+ { 0xfffffffffffULL, 0xf.ffffffffffp+40L },
+ { 0x7ffffffffffULL, 0xf.fffffffffep+39L },
+ { 0x3ffffffffffULL, 0xf.fffffffffcp+38L },
+ { 0x1ffffffffffULL, 0xf.fffffffff8p+37L },
+ { 0xffffffffffULL, 0xf.fffffffffp+36L },
+ { 0x7fffffffffULL, 0xf.ffffffffep+35L },
+ { 0x3fffffffffULL, 0xf.ffffffffcp+34L },
+ { 0x1fffffffffULL, 0xf.ffffffff8p+33L },
+ { 0xfffffffffULL, 0xf.ffffffffp+32L },
+ { 0x7ffffffffULL, 0xf.fffffffep+31L },
+ { 0x3ffffffffULL, 0xf.fffffffcp+30L },
+ { 0x1ffffffffULL, 0xf.fffffff8p+29L },
+ { 0xffffffffULL, 0xf.fffffffp+28L },
+ { 0x7fffffffULL, 0xf.ffffffep+27L },
+ { 0x3fffffffULL, 0xf.ffffffcp+26L },
+ { 0x1fffffffULL, 0xf.ffffff8p+25L },
+ { 0xfffffffULL, 0xf.ffffffp+24L },
+ { 0x7ffffffULL, 0xf.fffffep+23L },
+ { 0x3ffffffULL, 0xf.fffffcp+22L },
+ { 0x1ffffffULL, 0xf.fffff8p+21L },
+ { 0xffffffULL, 0xf.fffffp+20L },
+ { 0x7fffffULL, 0xf.ffffep+19L },
+ { 0x3fffffULL, 0xf.ffffcp+18L },
+ { 0x1fffffULL, 0xf.ffff8p+17L },
+ { 0xfffffULL, 0xf.ffffp+16L },
+ { 0x7ffffULL, 0xf.fffep+15L },
+ { 0x3ffffULL, 0xf.fffcp+14L },
+ { 0x1ffffULL, 0xf.fff8p+13L },
+ { 0xffffULL, 0xf.fffp+12L },
+ { 0x7fffULL, 0xf.ffep+11L },
+ { 0x3fffULL, 0xf.ffcp+10L },
+ { 0x1fffULL, 0xf.ff8p+9L },
+ { 0xfffULL, 0xf.ffp+8L },
+ { 0x7ffULL, 0xf.fep+7L },
+ { 0x3ffULL, 0xf.fcp+6L },
+ { 0x1ffULL, 0xf.f8p+5L },
+ { 0xffULL, 0xf.fp+4L },
+ { 0x7fULL, 0xf.ep+3L },
+ { 0x3fULL, 0xf.cp+2L },
+ { 0x1fULL, 0xf.8p+1L },
+ { 0xfULL, 0xfp+0L },
+ { 0x7ULL, 0xep-1L },
+ { 0x3ULL, 0xcp-2L },
+ { 0x1ULL, 0x8p-3L },
+};
+#endif
+
+ATF_TC(floatunditf);
+ATF_TC_HEAD(floatunditf, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Verify that uint64 -> long double conversion works");
+}
+
+ATF_TC_BODY(floatunditf, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ size_t i;
+
+ for (i = 0; i < __arraycount(testcases); ++i)
+ ATF_CHECK_MSG(
+ testcases[i].ld == (long double)testcases[i].u64,
+ "#%zu: expected %.20Lf, got %.20Lf\n", i,
+ testcases[i].ld,
+ (long double)testcases[i].u64);
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, floatunditf);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c b/contrib/netbsd-tests/lib/libc/gen/t_fmtcheck.c
new file mode 100644
index 000000000000..ab954005d566
--- /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 000000000000..f90d8cfdd0d1
--- /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 000000000000..21dea9e8fee7
--- /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 000000000000..3366c1f2f5cb
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_fpsetmask.c
@@ -0,0 +1,354 @@
+/* $NetBSD: t_fpsetmask.c,v 1.14 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 1995 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <signal.h>
+#include <float.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "isqemu.h"
+
+#ifndef _FLOAT_IEEE754
+
+ATF_TC(no_test);
+ATF_TC_HEAD(no_test, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Dummy test case");
+}
+
+ATF_TC_BODY(no_test, tc)
+{
+
+ atf_tc_skip("Test not available on this architecture.");
+}
+
+#else /* defined(_FLOAT_IEEE754) */
+
+#include <ieeefp.h>
+
+const char *skip_mesg;
+const char *skip_arch;
+
+void sigfpe(int, siginfo_t *, void *);
+
+volatile sig_atomic_t signal_caught;
+volatile int sicode;
+
+static volatile const float f_one = 1.0;
+static volatile const float f_zero = 0.0;
+static volatile const double d_one = 1.0;
+static volatile const double d_zero = 0.0;
+static volatile const long double ld_one = 1.0;
+static volatile const long double ld_zero = 0.0;
+
+static volatile const float f_huge = FLT_MAX;
+static volatile const float f_tiny = FLT_MIN;
+static volatile const double d_huge = DBL_MAX;
+static volatile const double d_tiny = DBL_MIN;
+static volatile const long double ld_huge = LDBL_MAX;
+static volatile const long double ld_tiny = LDBL_MIN;
+
+static volatile float f_x;
+static volatile double d_x;
+static volatile long double ld_x;
+
+/* trip divide by zero */
+static void
+f_dz(void)
+{
+
+ f_x = f_one / f_zero;
+}
+
+static void
+d_dz(void)
+{
+
+ d_x = d_one / d_zero;
+}
+
+static void
+ld_dz(void)
+{
+
+ ld_x = ld_one / ld_zero;
+}
+
+/* trip invalid operation */
+static void
+d_inv(void)
+{
+
+ d_x = d_zero / d_zero;
+}
+
+static void
+ld_inv(void)
+{
+
+ ld_x = ld_zero / ld_zero;
+}
+
+static void
+f_inv(void)
+{
+
+ f_x = f_zero / f_zero;
+}
+
+/* trip overflow */
+static void
+f_ofl(void)
+{
+
+ f_x = f_huge * f_huge;
+}
+
+static void
+d_ofl(void)
+{
+
+ d_x = d_huge * d_huge;
+}
+
+static void
+ld_ofl(void)
+{
+
+ ld_x = ld_huge * ld_huge;
+}
+
+/* trip underflow */
+static void
+f_ufl(void)
+{
+
+ f_x = f_tiny * f_tiny;
+}
+
+static void
+d_ufl(void)
+{
+
+ d_x = d_tiny * d_tiny;
+}
+
+static void
+ld_ufl(void)
+{
+
+ ld_x = ld_tiny * ld_tiny;
+}
+
+struct ops {
+ void (*op)(void);
+ fp_except mask;
+ int sicode;
+};
+
+static const struct ops float_ops[] = {
+ { f_dz, FP_X_DZ, FPE_FLTDIV },
+ { f_inv, FP_X_INV, FPE_FLTINV },
+ { f_ofl, FP_X_OFL, FPE_FLTOVF },
+ { f_ufl, FP_X_UFL, FPE_FLTUND },
+ { NULL, 0, 0 }
+};
+
+static const struct ops double_ops[] = {
+ { d_dz, FP_X_DZ, FPE_FLTDIV },
+ { d_inv, FP_X_INV, FPE_FLTINV },
+ { d_ofl, FP_X_OFL, FPE_FLTOVF },
+ { d_ufl, FP_X_UFL, FPE_FLTUND },
+ { NULL, 0, 0 }
+};
+
+static const struct ops long_double_ops[] = {
+ { ld_dz, FP_X_DZ, FPE_FLTDIV },
+ { ld_inv, FP_X_INV, FPE_FLTINV },
+ { ld_ofl, FP_X_OFL, FPE_FLTOVF },
+ { ld_ufl, FP_X_UFL, FPE_FLTUND },
+ { NULL, 0, 0 }
+};
+
+static sigjmp_buf b;
+
+static void
+fpsetmask_masked(const struct ops *test_ops)
+{
+ struct sigaction sa;
+ fp_except ex1, ex2;
+ const struct ops *t;
+
+ /* mask all exceptions, clear history */
+ fpsetmask(0);
+ fpsetsticky(0);
+
+ /* set up signal handler */
+ sa.sa_sigaction = sigfpe;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+ sigaction(SIGFPE, &sa, 0);
+ signal_caught = 0;
+
+ /*
+ * exceptions masked, check whether "sticky" bits are set correctly
+ */
+ for (t = test_ops; t->op != NULL; t++) {
+ (*t->op)();
+ ex1 = fpgetsticky();
+ ATF_CHECK_EQ(ex1 & t->mask, t->mask);
+ ATF_CHECK_EQ(signal_caught, 0);
+
+ /* check correct fpsetsticky() behaviour */
+ ex2 = fpsetsticky(0);
+ ATF_CHECK_EQ(fpgetsticky(), 0);
+ ATF_CHECK_EQ(ex1, ex2);
+ }
+}
+
+/* force delayed exceptions to be delivered */
+#define BARRIER() fpsetmask(0); f_x = f_one * f_one
+
+static void
+fpsetmask_unmasked(const struct ops *test_ops)
+{
+ struct sigaction sa;
+ int r;
+ const struct ops *volatile t;
+
+ /* mask all exceptions, clear history */
+ fpsetmask(0);
+ fpsetsticky(0);
+
+ /* set up signal handler */
+ sa.sa_sigaction = sigfpe;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+ sigaction(SIGFPE, &sa, 0);
+ signal_caught = 0;
+
+ /*
+ * exception unmasked, check SIGFPE delivery and correct siginfo
+ */
+ for (t = test_ops; t->op != NULL; t++) {
+ fpsetmask(t->mask);
+ r = sigsetjmp(b, 1);
+ if (!r) {
+ (*t->op)();
+ BARRIER();
+ }
+ ATF_CHECK_EQ(signal_caught, 1);
+ ATF_CHECK_EQ(sicode, t->sicode);
+ signal_caught = 0;
+ }
+}
+
+void
+sigfpe(int s, siginfo_t *si, void *c)
+{
+ signal_caught = 1;
+ sicode = si->si_code;
+ siglongjmp(b, 1);
+}
+
+#define TEST(m, t) \
+ ATF_TC(m##_##t); \
+ \
+ ATF_TC_HEAD(m##_##t, tc) \
+ { \
+ \
+ atf_tc_set_md_var(tc, "descr", \
+ "Test " ___STRING(m) " exceptions for " \
+ ___STRING(t) "values"); \
+ } \
+ \
+ ATF_TC_BODY(m##_##t, tc) \
+ { \
+ if (strcmp(MACHINE, "macppc") == 0) \
+ atf_tc_expect_fail("PR port-macppc/46319"); \
+ \
+ if (isQEMU()) \
+ atf_tc_expect_fail("PR misc/44767"); \
+ \
+ m(t##_ops); \
+ }
+
+TEST(fpsetmask_masked, float)
+TEST(fpsetmask_masked, double)
+TEST(fpsetmask_masked, long_double)
+TEST(fpsetmask_unmasked, float)
+TEST(fpsetmask_unmasked, double)
+TEST(fpsetmask_unmasked, long_double)
+
+ATF_TC(fpsetmask_basic);
+ATF_TC_HEAD(fpsetmask_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of fpsetmask(3)");
+}
+
+ATF_TC_BODY(fpsetmask_basic, tc)
+{
+ size_t i;
+ fp_except_t msk, lst[] = { FP_X_INV, FP_X_DZ, FP_X_OFL, FP_X_UFL };
+
+ msk = fpgetmask();
+ for (i = 0; i < __arraycount(lst); i++) {
+ fpsetmask(msk | lst[i]);
+ ATF_CHECK((fpgetmask() & lst[i]) != 0);
+ fpsetmask(msk & lst[i]);
+ ATF_CHECK((fpgetmask() & lst[i]) == 0);
+ }
+
+}
+
+#endif /* defined(_FLOAT_IEEE754) */
+
+ATF_TP_ADD_TCS(tp)
+{
+
+#ifndef _FLOAT_IEEE754
+ ATF_TP_ADD_TC(tp, no_test);
+#else
+ ATF_TP_ADD_TC(tp, fpsetmask_basic);
+ ATF_TP_ADD_TC(tp, fpsetmask_masked_float);
+ ATF_TP_ADD_TC(tp, fpsetmask_masked_double);
+ ATF_TP_ADD_TC(tp, fpsetmask_masked_long_double);
+ ATF_TP_ADD_TC(tp, fpsetmask_unmasked_float);
+ ATF_TP_ADD_TC(tp, fpsetmask_unmasked_double);
+ ATF_TP_ADD_TC(tp, fpsetmask_unmasked_long_double);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c b/contrib/netbsd-tests/lib/libc/gen/t_fpsetround.c
new file mode 100644
index 000000000000..0f23e74e57c8
--- /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 000000000000..100bd1bb982f
--- /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 000000000000..1f3998404f3d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_getcwd.c
@@ -0,0 +1,153 @@
+/* $NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_getcwd.c,v 1.3 2011/07/27 05:04:11 jruoho Exp $");
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fts.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+
+ATF_TC(getcwd_err);
+ATF_TC_HEAD(getcwd_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions in getcwd(3)");
+}
+
+ATF_TC_BODY(getcwd_err, tc)
+{
+ char buf[MAXPATHLEN];
+
+ errno = 0;
+
+ ATF_REQUIRE(getcwd(buf, 0) == NULL);
+ ATF_REQUIRE(errno == EINVAL);
+
+#ifdef __NetBSD__
+ errno = 0;
+
+ ATF_REQUIRE(getcwd((void *)-1, sizeof(buf)) == NULL);
+ ATF_REQUIRE(errno == EFAULT);
+#endif
+}
+
+ATF_TC(getcwd_fts);
+ATF_TC_HEAD(getcwd_fts, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of getcwd(3)");
+}
+
+ATF_TC_BODY(getcwd_fts, tc)
+{
+ const char *str = NULL;
+ char buf[MAXPATHLEN];
+ char *argv[2];
+ FTSENT *ftse;
+ FTS *fts;
+ int ops;
+ short depth;
+
+ /*
+ * Do not traverse too deep; cf. PR bin/45180.
+ */
+ depth = 2;
+
+ argv[1] = NULL;
+ argv[0] = __UNCONST("/");
+
+ /*
+ * Test that getcwd(3) works with basic
+ * system directories. Note that having
+ * no FTS_NOCHDIR specified should ensure
+ * that the current directory is visited.
+ */
+ ops = FTS_PHYSICAL | FTS_NOSTAT;
+ fts = fts_open(argv, ops, NULL);
+
+ if (fts == NULL) {
+ str = "failed to initialize fts(3)";
+ goto out;
+ }
+
+ while ((ftse = fts_read(fts)) != NULL) {
+
+ if (ftse->fts_level < 1)
+ continue;
+
+ if (ftse->fts_level > depth) {
+ (void)fts_set(fts, ftse, FTS_SKIP);
+ continue;
+ }
+
+ switch(ftse->fts_info) {
+
+ case FTS_DP:
+
+ (void)memset(buf, 0, sizeof(buf));
+
+ if (getcwd(buf, sizeof(buf)) == NULL) {
+ str = "getcwd(3) failed";
+ goto out;
+ }
+
+ if (strstr(ftse->fts_path, buf) == NULL) {
+ str = "getcwd(3) returned incorrect path";
+ goto out;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+out:
+ if (fts != NULL)
+ (void)fts_close(fts);
+
+ if (str != NULL)
+ atf_tc_fail("%s", str);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getcwd_err);
+ ATF_TP_ADD_TC(tp, getcwd_fts);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c b/contrib/netbsd-tests/lib/libc/gen/t_getgrent.c
new file mode 100644
index 000000000000..df9cdd1c0c17
--- /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 000000000000..198148c6937c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_glob.c
@@ -0,0 +1,287 @@
+/* $NetBSD: t_glob.c,v 1.3 2013/01/02 11:28:48 martin Exp $ */
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_glob.c,v 1.3 2013/01/02 11:28:48 martin Exp $");
+
+#include <atf-c.h>
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <glob.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef __FreeBSD__
+#include "h_macros.h"
+#define __gl_stat_t struct stat
+#define _S_IFDIR S_IFDIR
+#else
+#include "../../../h_macros.h"
+#endif
+
+
+#ifdef DEBUG
+#define DPRINTF(a) printf a
+#else
+#define DPRINTF(a)
+#endif
+
+struct gl_file {
+ const char *name;
+ int dir;
+};
+
+static struct gl_file a[] = {
+ { "1", 0 },
+ { "b", 1 },
+ { "3", 0 },
+ { "4", 0 },
+};
+
+static struct gl_file b[] = {
+ { "x", 0 },
+ { "y", 0 },
+ { "z", 0 },
+ { "w", 0 },
+};
+
+struct gl_dir {
+ const char *name; /* directory name */
+ const struct gl_file *dir;
+ size_t len, pos;
+};
+
+static struct gl_dir d[] = {
+ { "a", a, __arraycount(a), 0 },
+ { "a/b", b, __arraycount(b), 0 },
+};
+
+static const char *glob_star[] = {
+ "a/1", "a/3", "a/4", "a/b", "a/b/w", "a/b/x", "a/b/y", "a/b/z",
+};
+
+static const char *glob_star_not[] = {
+ "a/1", "a/3", "a/4", "a/b",
+};
+
+static void
+trim(char *buf, size_t len, const char *name)
+{
+ char *path = buf, *epath = buf + len;
+ while (path < epath && (*path++ = *name++) != '\0')
+ continue;
+ path--;
+ while (path > buf && *--path == '/')
+ *path = '\0';
+}
+
+static void *
+gl_opendir(const char *dir)
+{
+ size_t i;
+ char buf[MAXPATHLEN];
+ trim(buf, sizeof(buf), dir);
+
+ for (i = 0; i < __arraycount(d); i++)
+ if (strcmp(buf, d[i].name) == 0) {
+ DPRINTF(("opendir %s %zu\n", buf, i));
+ return &d[i];
+ }
+ errno = ENOENT;
+ return NULL;
+}
+
+static struct dirent *
+gl_readdir(void *v)
+{
+ static struct dirent dir;
+ struct gl_dir *dd = v;
+ if (dd->pos < dd->len) {
+ const struct gl_file *f = &dd->dir[dd->pos++];
+ strcpy(dir.d_name, f->name);
+ dir.d_namlen = strlen(f->name);
+ dir.d_ino = dd->pos;
+ dir.d_type = f->dir ? DT_DIR : DT_REG;
+ DPRINTF(("readdir %s %d\n", dir.d_name, dir.d_type));
+#ifdef __FreeBSD__
+ dir.d_reclen = -1; /* Does not have _DIRENT_RECLEN */
+#else
+ dir.d_reclen = _DIRENT_RECLEN(&dir, dir.d_namlen);
+#endif
+ return &dir;
+ }
+ return NULL;
+}
+
+static int
+gl_stat(const char *name , __gl_stat_t *st)
+{
+ char buf[MAXPATHLEN];
+ trim(buf, sizeof(buf), name);
+ memset(st, 0, sizeof(*st));
+
+ if (strcmp(buf, "a") == 0 || strcmp(buf, "a/b") == 0) {
+ st->st_mode |= _S_IFDIR;
+ return 0;
+ }
+
+ if (buf[0] == 'a' && buf[1] == '/') {
+ struct gl_file *f;
+ size_t offs, count;
+
+ if (buf[2] == 'b' && buf[3] == '/') {
+ offs = 4;
+ count = __arraycount(b);
+ f = b;
+ } else {
+ offs = 2;
+ count = __arraycount(a);
+ f = a;
+ }
+
+ for (size_t i = 0; i < count; i++)
+ if (strcmp(f[i].name, buf + offs) == 0)
+ return 0;
+ }
+ DPRINTF(("stat %s %d\n", buf, st->st_mode));
+ errno = ENOENT;
+ return -1;
+}
+
+static int
+gl_lstat(const char *name , __gl_stat_t *st)
+{
+ return gl_stat(name, st);
+}
+
+static void
+gl_closedir(void *v)
+{
+ struct gl_dir *dd = v;
+ dd->pos = 0;
+ DPRINTF(("closedir %p\n", dd));
+}
+
+static void
+run(const char *p, int flags, const char **res, size_t len)
+{
+ glob_t gl;
+ size_t i;
+
+ memset(&gl, 0, sizeof(gl));
+ gl.gl_opendir = gl_opendir;
+ gl.gl_readdir = gl_readdir;
+ gl.gl_closedir = gl_closedir;
+ gl.gl_stat = gl_stat;
+ gl.gl_lstat = gl_lstat;
+
+ RZ(glob(p, GLOB_ALTDIRFUNC | flags, NULL, &gl));
+
+ for (i = 0; i < gl.gl_pathc; i++)
+ DPRINTF(("%s\n", gl.gl_pathv[i]));
+
+ ATF_CHECK(len == gl.gl_pathc);
+ for (i = 0; i < gl.gl_pathc; i++)
+ ATF_CHECK_STREQ(gl.gl_pathv[i], res[i]);
+
+ globfree(&gl);
+}
+
+
+#ifndef __FreeBSD__
+ATF_TC(glob_star);
+ATF_TC_HEAD(glob_star, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test glob(3) ** with GLOB_STAR");
+}
+
+ATF_TC_BODY(glob_star, tc)
+{
+ run("a/**", GLOB_STAR, glob_star, __arraycount(glob_star));
+}
+#endif
+
+ATF_TC(glob_star_not);
+ATF_TC_HEAD(glob_star_not, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test glob(3) ** without GLOB_STAR");
+}
+
+
+ATF_TC_BODY(glob_star_not, tc)
+{
+ run("a/**", 0, glob_star_not, __arraycount(glob_star_not));
+}
+
+#if 0
+ATF_TC(glob_nocheck);
+ATF_TC_HEAD(glob_nocheck, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test glob(3) pattern with backslash and GLOB_NOCHECK");
+}
+
+
+ATF_TC_BODY(glob_nocheck, tc)
+{
+ static const char pattern[] = { 'f', 'o', 'o', '\\', ';', 'b', 'a',
+ 'r', '\0' };
+ static const char *glob_nocheck[] = {
+ pattern
+ };
+ run(pattern, GLOB_NOCHECK, glob_nocheck, __arraycount(glob_nocheck));
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+#ifndef __FreeBSD__
+ ATF_TP_ADD_TC(tp, glob_star);
+#endif
+ ATF_TP_ADD_TC(tp, glob_star_not);
+/*
+ * Remove this test for now - the GLOB_NOCHECK return value has been
+ * re-defined to return a modified pattern in revision 1.33 of glob.c
+ *
+ * ATF_TP_ADD_TC(tp, glob_nocheck);
+ */
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c
new file mode 100644
index 000000000000..5836c8629162
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_humanize_number.c
@@ -0,0 +1,318 @@
+/* $NetBSD: t_humanize_number.c,v 1.8 2012/03/18 07:14:08 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+
+#include <err.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef __FreeBSD__
+#include <libutil.h>
+#else
+#include <util.h>
+#endif
+
+const struct hnopts {
+ size_t ho_len;
+ int64_t ho_num;
+ const char *ho_suffix;
+ int ho_scale;
+ int ho_flags;
+ int ho_retval; /* expected return value */
+ const char *ho_retstr; /* expected string in buffer */
+} hnopts[] = {
+ /*
+ * Rev. 1.6 produces "10.0".
+ */
+ { 5, 10737418236ULL * 1024, "",
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10T" },
+
+ { 5, 10450000, "",
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" },
+ { 5, 10500000, "", /* just for reference */
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 3, "10M" },
+
+ /*
+ * Trailing space. Rev. 1.7 produces "1 ".
+ */
+ { 5, 1, "", 0, HN_NOSPACE, 1, "1" },
+
+ { 5, 1, "", 0, 0, 2, "1 " }, /* just for reference */
+ { 5, 1, "", 0, HN_B, 3, "1 B" }, /* and more ... */
+ { 5, 1, "", 0, HN_DECIMAL, 2, "1 " },
+ { 5, 1, "", 0, HN_NOSPACE | HN_B, 2, "1B" },
+ { 5, 1, "", 0, HN_B | HN_DECIMAL, 3, "1 B" },
+ { 5, 1, "", 0, HN_NOSPACE | HN_B | HN_DECIMAL, 2, "1B" },
+
+ /*
+ * Space and HN_B. Rev. 1.7 produces "1B".
+ */
+ { 5, 1, "", HN_AUTOSCALE, HN_B, 3, "1 B" },
+ { 5, 1000, "", /* just for reference */
+ HN_AUTOSCALE, HN_B, 3, "1 K" },
+
+ /*
+ * Truncated output. Rev. 1.7 produces "1.0 K".
+ */
+#ifndef __FreeBSD__
+ { 6, 1000, "A", HN_AUTOSCALE, HN_DECIMAL, -1, "" },
+
+ /*
+ * Failure case reported by Greg Troxel <gdt@NetBSD.org>.
+ * Rev. 1.11 incorrectly returns 5 with filling the buffer
+ * with "1000".
+ */
+ { 5, 1048258238, "",
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0G" },
+ /* Similar case it prints 1000 where it shouldn't */
+ { 5, 1023488, "",
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" },
+#endif
+ { 5, 1023999, "",
+ HN_AUTOSCALE, HN_B | HN_NOSPACE | HN_DECIMAL, 4, "1.0M" },
+};
+
+struct hnflags {
+ int hf_flags;
+ const char *hf_name;
+};
+
+const struct hnflags scale_flags[] = {
+ { HN_GETSCALE, "HN_GETSCALE" },
+ { HN_AUTOSCALE, "HN_AUTOSCALE" },
+};
+const struct hnflags normal_flags[] = {
+ { HN_DECIMAL, "HN_DECIMAL" },
+ { HN_NOSPACE, "HN_NOSPACE" },
+ { HN_B, "HN_B" },
+ { HN_DIVISOR_1000, "HN_DIVISOR_1000" },
+};
+
+const char *formatflags(char *, size_t, const struct hnflags *, size_t, int);
+void newline(void);
+void w_printf(const char *, ...) __printflike(1, 2);
+int main(int, char *[]);
+
+const char *
+formatflags(char *buf, size_t buflen, const struct hnflags *hfs,
+ size_t hfslen, int flags)
+{
+ const struct hnflags *hf;
+ char *p = buf;
+ ssize_t len = buflen;
+ unsigned int i, found;
+ int n;
+
+ if (flags == 0) {
+ snprintf(buf, buflen, "0");
+ return (buf);
+ }
+ for (i = found = 0; i < hfslen && flags & ~found; i++) {
+ hf = &hfs[i];
+ if (flags & hf->hf_flags) {
+ found |= hf->hf_flags;
+ n = snprintf(p, len, "|%s", hf->hf_name);
+ if (n >= len) {
+ p = buf;
+ len = buflen;
+ /* Print `flags' as number */
+ goto bad;
+ }
+ p += n;
+ len -= n;
+ }
+ }
+ flags &= ~found;
+ if (flags)
+bad:
+ snprintf(p, len, "|0x%x", flags);
+ return (*buf == '|' ? buf + 1 : buf);
+}
+
+static int col, bol = 1;
+void
+newline(void)
+{
+
+ fprintf(stderr, "\n");
+ col = 0;
+ bol = 1;
+}
+
+void
+w_printf(const char *fmt, ...)
+{
+ char buf[80];
+ va_list ap;
+ int n;
+
+ va_start(ap, fmt);
+ if (col >= 0) {
+ n = vsnprintf(buf, sizeof(buf), fmt, ap);
+ if (n >= (int)sizeof(buf)) {
+ col = -1;
+ goto overflow;
+ } else if (n == 0)
+ goto out;
+
+ if (!bol) {
+ if (col + n > 75)
+ fprintf(stderr, "\n "), col = 4;
+ else
+ fprintf(stderr, " "), col++;
+ }
+ fprintf(stderr, "%s", buf);
+ col += n;
+ bol = 0;
+ } else {
+overflow:
+ vfprintf(stderr, fmt, ap);
+ }
+out:
+ va_end(ap);
+}
+
+ATF_TC(humanize_number_basic);
+ATF_TC_HEAD(humanize_number_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test humanize_number(3)");
+}
+
+ATF_TC_BODY(humanize_number_basic, tc)
+{
+ char fbuf[128];
+ const struct hnopts *ho;
+ char *buf = NULL;
+ size_t buflen = 0;
+ unsigned int i;
+ int rv = 0;
+
+ for (i = 0; i < __arraycount(hnopts); i++) {
+ ho = &hnopts[i];
+ if (buflen < ho->ho_len) {
+ buflen = ho->ho_len;
+ buf = realloc(buf, buflen);
+ if (buf == NULL)
+ atf_tc_fail("realloc(..., %zu) failed", buflen);
+ }
+
+ rv = humanize_number(buf, ho->ho_len, ho->ho_num,
+ ho->ho_suffix, ho->ho_scale, ho->ho_flags);
+
+ if (rv == ho->ho_retval &&
+ (rv == -1 || strcmp(buf, ho->ho_retstr) == 0))
+ continue;
+
+ w_printf("humanize_number(\"%s\", %zu, %" PRId64 ",",
+ ho->ho_retstr, ho->ho_len, ho->ho_num);
+ w_printf("\"%s\",", ho->ho_suffix);
+ w_printf("%s,", formatflags(fbuf, sizeof(fbuf), scale_flags,
+ sizeof(scale_flags) / sizeof(scale_flags[0]),
+ ho->ho_scale));
+ w_printf("%s)", formatflags(fbuf, sizeof(fbuf), normal_flags,
+ sizeof(normal_flags) / sizeof(normal_flags[0]),
+ ho->ho_flags));
+ w_printf("= %d,", ho->ho_retval);
+ w_printf("but got");
+ w_printf("%d/[%s]", rv, rv == -1 ? "" : buf);
+ newline();
+ atf_tc_fail_nonfatal("Failed for table entry %d", i);
+ }
+}
+
+ATF_TC(humanize_number_big);
+ATF_TC_HEAD(humanize_number_big, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test humanize "
+ "big numbers (PR lib/44097)");
+}
+
+ATF_TC_BODY(humanize_number_big, tc)
+{
+ char buf[1024];
+ int rv;
+
+ /*
+ * Seems to work.
+ */
+ (void)memset(buf, 0, sizeof(buf));
+
+ rv = humanize_number(buf, 10, 10000, "", HN_AUTOSCALE, HN_NOSPACE);
+
+ ATF_REQUIRE(rv != -1);
+ ATF_CHECK_STREQ(buf, "10000");
+
+ /*
+ * A bogus value with large number.
+ */
+ (void)memset(buf, 0, sizeof(buf));
+
+ rv = humanize_number(buf, 10, INT64_MAX, "", HN_AUTOSCALE, HN_NOSPACE);
+
+ ATF_REQUIRE(rv != -1);
+ ATF_REQUIRE(strcmp(buf, "0") != 0);
+
+ /*
+ * Large buffer with HN_AUTOSCALE. Entirely bogus.
+ */
+ (void)memset(buf, 0, sizeof(buf));
+
+ rv = humanize_number(buf, sizeof(buf), 10000, "",
+ HN_AUTOSCALE, HN_NOSPACE);
+
+ ATF_REQUIRE(rv != -1);
+ ATF_REQUIRE(strcmp(buf, "0%d%s%d%s%s%s") != 0);
+
+ /*
+ * Tight buffer.
+ *
+ * The man page says that len must be at least 4.
+ * 3 works, but anything less that will not. This
+ * is because baselen starts with 2 for positive
+ * numbers.
+ */
+ (void)memset(buf, 0, sizeof(buf));
+
+ rv = humanize_number(buf, 3, 1, "", HN_AUTOSCALE, HN_NOSPACE);
+
+ ATF_REQUIRE(rv != -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, humanize_number_basic);
+ ATF_TP_ADD_TC(tp, humanize_number_big);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_isnan.c b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c
new file mode 100644
index 000000000000..2871e314066e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_isnan.c
@@ -0,0 +1,66 @@
+/* $NetBSD: t_isnan.c,v 1.5 2014/11/04 00:20:19 justin Exp $ */
+
+/*
+ * This file is in the Public Domain.
+ *
+ * The nan test is blatently copied by Simon Burge from the infinity
+ * test by Ben Harris.
+ */
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+
+#include <math.h>
+#include <string.h>
+
+ATF_TC(isnan_basic);
+ATF_TC_HEAD(isnan_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Verify that isnan(3) works");
+}
+
+ATF_TC_BODY(isnan_basic, tc)
+{
+#if defined(__m68k__)
+ atf_tc_skip("Test not applicable on " MACHINE_ARCH);
+#endif
+
+#ifdef NAN
+ /* NAN is meant to be a (float)NaN. */
+ ATF_CHECK(isnan(NAN) != 0);
+ ATF_CHECK(isnan((double)NAN) != 0);
+#else
+ atf_tc_skip("Test not applicable");
+#endif
+}
+
+ATF_TC(isinf_basic);
+ATF_TC_HEAD(isinf_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Verify that isinf(3) works");
+}
+
+ATF_TC_BODY(isinf_basic, tc)
+{
+#if defined(__m68k__)
+ atf_tc_skip("Test not applicable on " MACHINE_ARCH);
+#endif
+
+ /* HUGE_VAL is meant to be an infinity. */
+ ATF_CHECK(isinf(HUGE_VAL) != 0);
+
+ /* HUGE_VALF is the float analog of HUGE_VAL. */
+ ATF_CHECK(isinf(HUGE_VALF) != 0);
+
+ /* HUGE_VALL is the long double analog of HUGE_VAL. */
+ ATF_CHECK(isinf(HUGE_VALL) != 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, isnan_basic);
+ ATF_TP_ADD_TC(tp, isinf_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_nice.c b/contrib/netbsd-tests/lib/libc/gen/t_nice.c
new file mode 100644
index 000000000000..10b8df7ccb7f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_nice.c
@@ -0,0 +1,221 @@
+/* $NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $");
+
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <limits.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static void *threadfunc(void *);
+
+static void *
+threadfunc(void *arg)
+{
+ int pri, val;
+
+ val = *(int *)arg;
+
+ errno = 0;
+ pri = getpriority(PRIO_PROCESS, 0);
+ ATF_REQUIRE(errno == 0);
+
+ if (pri != val)
+ atf_tc_fail("nice(3) value was not propagated to threads");
+
+ return NULL;
+}
+
+ATF_TC(nice_err);
+ATF_TC_HEAD(nice_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test nice(3) for invalid parameters (PR lib/42587)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(nice_err, tc)
+{
+ int i;
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("nice(incr) with incr < 0 fails with unprivileged "
+ "users and sets errno == EPERM; see PR # 189821 for more details");
+#endif
+
+ /*
+ * The call should fail with EPERM if the
+ * supplied parameter is negative and the
+ * caller does not have privileges.
+ */
+ for (i = -20; i < 0; i++) {
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EPERM, nice(i) == -1);
+ }
+}
+
+ATF_TC(nice_priority);
+ATF_TC_HEAD(nice_priority, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test nice(3) vs. getpriority(2)");
+}
+
+ATF_TC_BODY(nice_priority, tc)
+{
+#ifdef __FreeBSD__
+ int i, pri, pri2, nic;
+#else
+ int i, pri, nic;
+#endif
+ pid_t pid;
+ int sta;
+
+ for (i = 0; i <= 20; i++) {
+
+ nic = nice(i);
+ ATF_REQUIRE(nic != -1);
+
+ errno = 0;
+ pri = getpriority(PRIO_PROCESS, 0);
+ ATF_REQUIRE(errno == 0);
+
+#ifdef __NetBSD__
+ if (nic != pri)
+ atf_tc_fail("nice(3) and getpriority(2) conflict");
+#endif
+
+ /*
+ * Also verify that the nice(3) values
+ * are inherited by child processes.
+ */
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ errno = 0;
+#ifdef __FreeBSD__
+ pri = getpriority(PRIO_PROCESS, 0);
+#else
+ pri2 = getpriority(PRIO_PROCESS, 0);
+#endif
+ ATF_REQUIRE(errno == 0);
+
+#ifdef __FreeBSD__
+ if (pri != pri2)
+#else
+ if (nic != pri)
+#endif
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("nice(3) value was not inherited");
+ }
+}
+
+ATF_TC(nice_root);
+ATF_TC_HEAD(nice_root, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that nice(3) works");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(nice_root, tc)
+{
+ int i;
+
+ for (i = -20; i <= 20; i++) {
+
+ ATF_REQUIRE(nice(i) != -1);
+ }
+}
+
+ATF_TC(nice_thread);
+ATF_TC_HEAD(nice_thread, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test nice(3) with threads");
+}
+
+ATF_TC_BODY(nice_thread, tc)
+{
+ pthread_t tid[5];
+#ifdef __FreeBSD__
+ int pri, rv, val;
+#else
+ int rv, val;
+#endif
+ size_t i;
+
+ /*
+ * Test that the scheduling priority is
+ * propagated to all system scope threads.
+ */
+ for (i = 0; i < __arraycount(tid); i++) {
+
+ val = nice(i);
+ ATF_REQUIRE(val != -1);
+
+#ifdef __FreeBSD__
+ pri = getpriority(PRIO_PROCESS, 0);
+ rv = pthread_create(&tid[i], NULL, threadfunc, &pri);
+#else
+ rv = pthread_create(&tid[i], NULL, threadfunc, &val);
+#endif
+ ATF_REQUIRE(rv == 0);
+
+ rv = pthread_join(tid[i], NULL);
+ ATF_REQUIRE(rv == 0);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, nice_err);
+ ATF_TP_ADD_TC(tp, nice_priority);
+ ATF_TP_ADD_TC(tp, nice_root);
+ ATF_TP_ADD_TC(tp, nice_thread);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_pause.c b/contrib/netbsd-tests/lib/libc/gen/t_pause.c
new file mode 100644
index 000000000000..62a74c976ba9
--- /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 000000000000..d6f888fde127
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_raise.c
@@ -0,0 +1,194 @@
+/* $NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_raise.c,v 1.5 2011/05/10 12:43:42 jruoho Exp $");
+
+#include <atf-c.h>
+
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+static bool fail;
+static int count;
+static void handler_err(int);
+static void handler_ret(int);
+static void handler_stress(int);
+#ifdef __FreeBSD__
+static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2 };
+#else
+static int sig[] = { SIGALRM, SIGIO, SIGUSR1, SIGUSR2, SIGPWR };
+#endif
+
+static void
+handler_stress(int signo)
+{
+ count++;
+}
+
+static void
+handler_err(int signo)
+{
+ size_t i;
+
+ for (i = 0; i < __arraycount(sig); i++) {
+
+ if (sig[i] == signo) {
+ fail = false;
+ break;
+ }
+ }
+}
+
+static void
+handler_ret(int signo)
+{
+
+ (void)sleep(1);
+
+ fail = false;
+}
+
+ATF_TC(raise_err);
+ATF_TC_HEAD(raise_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test raise(3) for invalid parameters");
+}
+
+ATF_TC_BODY(raise_err, tc)
+{
+ int i = 0;
+
+ while (i < 10) {
+
+ ATF_REQUIRE(raise(10240 + i) == -1);
+
+ i++;
+ }
+}
+
+ATF_TC(raise_ret);
+ATF_TC_HEAD(raise_ret, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test return order of raise(3)");
+}
+
+ATF_TC_BODY(raise_ret, tc)
+{
+ struct sigaction sa;
+
+ fail = true;
+
+ sa.sa_flags = 0;
+ sa.sa_handler = handler_ret;
+
+ /*
+ * Verify that raise(3) does not return
+ * before the signal handler returns.
+ */
+ ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
+ ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0);
+ ATF_REQUIRE(raise(SIGUSR1) == 0);
+
+ if (fail != false)
+ atf_tc_fail("raise(3) returned before signal handler");
+}
+
+ATF_TC(raise_sig);
+ATF_TC_HEAD(raise_sig, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of raise(3)");
+}
+
+ATF_TC_BODY(raise_sig, tc)
+{
+ struct timespec tv, tr;
+ struct sigaction sa;
+ size_t i;
+
+ for (i = 0; i < __arraycount(sig); i++) {
+
+ (void)memset(&sa, 0, sizeof(struct sigaction));
+
+ fail = true;
+
+ tv.tv_sec = 0;
+ tv.tv_nsec = 2;
+
+ sa.sa_flags = 0;
+ sa.sa_handler = handler_err;
+
+ ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
+ ATF_REQUIRE(sigaction(sig[i], &sa, 0) == 0);
+
+ ATF_REQUIRE(raise(sig[i]) == 0);
+ ATF_REQUIRE(nanosleep(&tv, &tr) == 0);
+
+ if (fail != false)
+ atf_tc_fail("raise(3) did not raise a signal");
+ }
+}
+
+ATF_TC(raise_stress);
+ATF_TC_HEAD(raise_stress, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic stress test with raise(3)");
+}
+
+ATF_TC_BODY(raise_stress, tc)
+{
+ static const int maxiter = 1000 * 10;
+ struct sigaction sa;
+ int i;
+
+ sa.sa_flags = 0;
+ sa.sa_handler = handler_stress;
+
+ ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
+ ATF_REQUIRE(sigaction(SIGUSR1, &sa, 0) == 0);
+
+ for (count = i = 0; i < maxiter; i++)
+ (void)raise(SIGUSR1);
+
+ if (count != maxiter)
+ atf_tc_fail("not all signals were catched");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, raise_err);
+ ATF_TP_ADD_TC(tp, raise_ret);
+ ATF_TP_ADD_TC(tp, raise_sig);
+ ATF_TP_ADD_TC(tp, raise_stress);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_randomid.c b/contrib/netbsd-tests/lib/libc/gen/t_randomid.c
new file mode 100644
index 000000000000..8377806252cd
--- /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 000000000000..d4998c7ea265
--- /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 000000000000..f51eb2a9d893
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_setdomainname.c
@@ -0,0 +1,148 @@
+/* $NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_setdomainname.c,v 1.2 2012/03/25 08:17:54 joerg Exp $");
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+static char domain[MAXHOSTNAMELEN];
+
+static const char domains[][MAXHOSTNAMELEN] = {
+ "1234567890",
+ "abcdefghijklmnopqrst",
+ "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8",
+ "--------------------------------------------------------------------"
+};
+
+ATF_TC_WITH_CLEANUP(setdomainname_basic);
+ATF_TC_HEAD(setdomainname_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of setdomainname(3)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(setdomainname_basic, tc)
+{
+ char name[MAXHOSTNAMELEN];
+ size_t i;
+
+ for (i = 0; i < __arraycount(domains); i++) {
+
+ (void)memset(name, 0, sizeof(name));
+
+#ifdef __FreeBSD__
+ /*
+ * Sanity checks to ensure that the wrong invariant isn't being
+ * tested for per PR # 181127
+ */
+ ATF_REQUIRE_EQ(sizeof(domains[i]), MAXHOSTNAMELEN);
+ ATF_REQUIRE_EQ(sizeof(name), MAXHOSTNAMELEN);
+
+ ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i]) - 1) == 0);
+ ATF_REQUIRE(getdomainname(name, sizeof(name) - 1) == 0);
+#else
+ ATF_REQUIRE(setdomainname(domains[i],sizeof(domains[i])) == 0);
+ ATF_REQUIRE(getdomainname(name, sizeof(name)) == 0);
+#endif
+ ATF_REQUIRE(strcmp(domains[i], name) == 0);
+ }
+
+ (void)setdomainname(domain, sizeof(domain));
+}
+
+ATF_TC_CLEANUP(setdomainname_basic, tc)
+{
+ (void)setdomainname(domain, sizeof(domain));
+}
+
+ATF_TC_WITH_CLEANUP(setdomainname_limit);
+ATF_TC_HEAD(setdomainname_limit, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Too long domain name errors out?");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(setdomainname_limit, tc)
+{
+ char name[MAXHOSTNAMELEN + 1];
+
+ (void)memset(name, 0, sizeof(name));
+
+#ifdef __FreeBSD__
+ ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN - 1 ) == 0);
+ ATF_REQUIRE(setdomainname(name, MAXHOSTNAMELEN) == -1);
+#endif
+ ATF_REQUIRE(setdomainname(name, sizeof(name)) == -1);
+}
+
+ATF_TC_CLEANUP(setdomainname_limit, tc)
+{
+ (void)setdomainname(domain, sizeof(domain));
+}
+
+ATF_TC_WITH_CLEANUP(setdomainname_perm);
+ATF_TC_HEAD(setdomainname_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Can normal user set the domain name?");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(setdomainname_perm, tc)
+{
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EPERM, setdomainname(domain, sizeof(domain)) == -1);
+}
+
+ATF_TC_CLEANUP(setdomainname_perm, tc)
+{
+ (void)setdomainname(domain, sizeof(domain));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ (void)memset(domain, 0, sizeof(domain));
+
+ ATF_REQUIRE(getdomainname(domain, sizeof(domain)) == 0);
+
+ ATF_TP_ADD_TC(tp, setdomainname_basic);
+ ATF_TP_ADD_TC(tp, setdomainname_limit);
+ ATF_TP_ADD_TC(tp, setdomainname_perm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c
new file mode 100644
index 000000000000..1972f7d5747b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_sethostname.c
@@ -0,0 +1,150 @@
+/* $NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_sethostname.c,v 1.3 2012/03/25 08:17:54 joerg Exp $");
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+static char host[MAXHOSTNAMELEN];
+
+static const char hosts[][MAXHOSTNAMELEN] = {
+ "1234567890",
+ "abcdefghijklmnopqrst",
+ "!#\xa4%&/(..xasS812=!=!(I(!;X;;X.as.dasa=?;,..<>|**^\xa8",
+ "--------------------------------------------------------------------"
+};
+
+ATF_TC_WITH_CLEANUP(sethostname_basic);
+ATF_TC_HEAD(sethostname_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of sethostname(3)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(sethostname_basic, tc)
+{
+ char name[MAXHOSTNAMELEN];
+ size_t i;
+
+ atf_tc_skip("screws up the test host's hostname on FreeBSD");
+
+ for (i = 0; i < __arraycount(hosts); i++) {
+
+ (void)memset(name, 0, sizeof(name));
+
+#ifdef __FreeBSD__
+ /*
+ * Sanity checks to ensure that the wrong invariant isn't being
+ * tested for per PR # 181127
+ */
+ ATF_REQUIRE_EQ(sizeof(hosts[i]), MAXHOSTNAMELEN);
+ ATF_REQUIRE_EQ(sizeof(name), MAXHOSTNAMELEN);
+
+ ATF_REQUIRE(sethostname(hosts[i], sizeof(hosts[i]) - 1) == 0);
+ ATF_REQUIRE(gethostname(name, sizeof(name) - 1) == 0);
+#else
+ ATF_REQUIRE(sethostname(hosts[i], sizeof(hosts[i])) == 0);
+ ATF_REQUIRE(gethostname(name, sizeof(name)) == 0);
+#endif
+ ATF_REQUIRE(strcmp(hosts[i], name) == 0);
+ }
+
+ (void)sethostname(host, sizeof(host));
+}
+
+ATF_TC_CLEANUP(sethostname_basic, tc)
+{
+ (void)sethostname(host, sizeof(host));
+}
+
+ATF_TC_WITH_CLEANUP(sethostname_limit);
+ATF_TC_HEAD(sethostname_limit, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Too long host name errors out?");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(sethostname_limit, tc)
+{
+ char name[MAXHOSTNAMELEN + 1];
+
+ (void)memset(name, 0, sizeof(name));
+
+ ATF_REQUIRE(sethostname(name, sizeof(name)) == -1);
+}
+
+ATF_TC_CLEANUP(sethostname_limit, tc)
+{
+#ifdef __FreeBSD__
+ ATF_REQUIRE(sethostname(host, MAXHOSTNAMELEN - 1 ) == 0);
+ ATF_REQUIRE(sethostname(host, MAXHOSTNAMELEN) == -1);
+#endif
+ (void)sethostname(host, sizeof(host));
+}
+
+ATF_TC_WITH_CLEANUP(sethostname_perm);
+ATF_TC_HEAD(sethostname_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Can normal user set the host name?");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(sethostname_perm, tc)
+{
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EPERM, sethostname(host, sizeof(host)) == -1);
+}
+
+ATF_TC_CLEANUP(sethostname_perm, tc)
+{
+ (void)sethostname(host, sizeof(host));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ (void)memset(host, 0, sizeof(host));
+
+ ATF_REQUIRE(gethostname(host, sizeof(host)) == 0);
+
+ ATF_TP_ADD_TC(tp, sethostname_basic);
+ ATF_TP_ADD_TC(tp, sethostname_limit);
+ ATF_TP_ADD_TC(tp, sethostname_perm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c
new file mode 100644
index 000000000000..9c9a3c743c0b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_siginfo.c
@@ -0,0 +1,505 @@
+/* $NetBSD: t_siginfo.c,v 1.24 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+
+#ifdef __NetBSD__
+#include <sys/inttypes.h>
+#endif
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+#include <sys/ucontext.h>
+#include <sys/wait.h>
+
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <setjmp.h>
+#include <float.h>
+
+#ifdef HAVE_FENV
+#include <fenv.h>
+#elif defined(_FLOAT_IEEE754)
+#include <ieeefp.h>
+#endif
+
+#include "isqemu.h"
+
+/* for sigbus */
+volatile char *addr;
+
+/* for sigchild */
+pid_t child;
+int code;
+int status;
+
+/* for sigfpe */
+sig_atomic_t fltdiv_signalled = 0;
+sig_atomic_t intdiv_signalled = 0;
+
+static void
+sig_debug(int signo, siginfo_t *info, ucontext_t *ctx)
+{
+ unsigned int i;
+
+ printf("%d %p %p\n", signo, info, ctx);
+ if (info != NULL) {
+ printf("si_signo=%d\n", info->si_signo);
+ printf("si_errno=%d\n", info->si_errno);
+ printf("si_code=%d\n", info->si_code);
+ printf("si_value.sival_int=%d\n", info->si_value.sival_int);
+ }
+ if (ctx != NULL) {
+ printf("uc_flags 0x%x\n", ctx->uc_flags);
+ printf("uc_link %p\n", ctx->uc_link);
+ for (i = 0; i < __arraycount(ctx->uc_sigmask.__bits); i++)
+ printf("uc_sigmask[%d] 0x%x\n", i,
+ ctx->uc_sigmask.__bits[i]);
+ printf("uc_stack %p %lu 0x%x\n", ctx->uc_stack.ss_sp,
+ (unsigned long)ctx->uc_stack.ss_size,
+ ctx->uc_stack.ss_flags);
+#ifdef __NetBSD__
+ for (i = 0; i < __arraycount(ctx->uc_mcontext.__gregs); i++)
+ printf("uc_mcontext.greg[%d] 0x%lx\n", i,
+ (long)ctx->uc_mcontext.__gregs[i]);
+#endif
+ }
+}
+
+static void
+sigalrm_action(int signo, siginfo_t *info, void *ptr)
+{
+
+ sig_debug(signo, info, (ucontext_t *)ptr);
+
+ ATF_REQUIRE_EQ(info->si_signo, SIGALRM);
+ ATF_REQUIRE_EQ(info->si_code, SI_TIMER);
+ ATF_REQUIRE_EQ(info->si_value.sival_int, ITIMER_REAL);
+
+ atf_tc_pass();
+ /* NOTREACHED */
+}
+
+ATF_TC(sigalarm);
+
+ATF_TC_HEAD(sigalarm, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGALRM handler");
+}
+
+ATF_TC_BODY(sigalarm, tc)
+{
+ struct sigaction sa;
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = sigalrm_action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGALRM, &sa, NULL);
+ for (;;) {
+ alarm(1);
+ sleep(1);
+ }
+ atf_tc_fail("SIGALRM handler wasn't called");
+}
+
+static void
+sigchild_action(int signo, siginfo_t *info, void *ptr)
+{
+ if (info != NULL) {
+ printf("info=%p\n", info);
+ printf("ptr=%p\n", ptr);
+ printf("si_signo=%d\n", info->si_signo);
+ printf("si_errno=%d\n", info->si_errno);
+ printf("si_code=%d\n", info->si_code);
+ printf("si_uid=%d\n", info->si_uid);
+ printf("si_pid=%d\n", info->si_pid);
+ printf("si_status=%d\n", info->si_status);
+#ifdef __NetBSD__
+ printf("si_utime=%lu\n", (unsigned long int)info->si_utime);
+ printf("si_stime=%lu\n", (unsigned long int)info->si_stime);
+#endif
+ }
+ ATF_REQUIRE_EQ(info->si_code, code);
+ ATF_REQUIRE_EQ(info->si_signo, SIGCHLD);
+ ATF_REQUIRE_EQ(info->si_uid, getuid());
+ ATF_REQUIRE_EQ(info->si_pid, child);
+ if (WIFEXITED(info->si_status))
+ ATF_REQUIRE_EQ(WEXITSTATUS(info->si_status), status);
+ else if (WIFSTOPPED(info->si_status))
+ ATF_REQUIRE_EQ(WSTOPSIG(info->si_status), status);
+ else if (WIFSIGNALED(info->si_status))
+ ATF_REQUIRE_EQ(WTERMSIG(info->si_status), status);
+}
+
+static void
+setchildhandler(void (*action)(int, siginfo_t *, void *))
+{
+ struct sigaction sa;
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGCHLD, &sa, NULL);
+}
+
+static void
+sigchild_setup(void)
+{
+ sigset_t set;
+ struct rlimit rlim;
+
+ (void)getrlimit(RLIMIT_CORE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max;
+ (void)setrlimit(RLIMIT_CORE, &rlim);
+
+ setchildhandler(sigchild_action);
+ sigemptyset(&set);
+ sigaddset(&set, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &set, NULL);
+}
+
+ATF_TC(sigchild_normal);
+ATF_TC_HEAD(sigchild_normal, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGCHLD handler "
+ "when child exits normally");
+}
+
+ATF_TC_BODY(sigchild_normal, tc)
+{
+ sigset_t set;
+
+ sigchild_setup();
+
+ status = 25;
+ code = CLD_EXITED;
+
+ switch ((child = fork())) {
+ case 0:
+ sleep(1);
+ exit(status);
+ case -1:
+ atf_tc_fail("fork failed");
+ default:
+ sigemptyset(&set);
+ sigsuspend(&set);
+ }
+}
+
+ATF_TC(sigchild_dump);
+ATF_TC_HEAD(sigchild_dump, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGCHLD handler "
+ "when child segfaults");
+}
+
+ATF_TC_BODY(sigchild_dump, tc)
+{
+ sigset_t set;
+
+ sigchild_setup();
+
+ status = SIGSEGV;
+ code = CLD_DUMPED;
+
+ switch ((child = fork())) {
+ case 0:
+ sleep(1);
+ *(volatile long *)0 = 0;
+ atf_tc_fail("Child did not segfault");
+ /* NOTREACHED */
+ case -1:
+ atf_tc_fail("fork failed");
+ default:
+ sigemptyset(&set);
+ sigsuspend(&set);
+ }
+}
+
+ATF_TC(sigchild_kill);
+ATF_TC_HEAD(sigchild_kill, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGCHLD handler "
+ "when child is killed");
+}
+
+ATF_TC_BODY(sigchild_kill, tc)
+{
+ sigset_t set;
+
+ sigchild_setup();
+
+ status = SIGPIPE;
+ code = CLD_KILLED;
+
+ switch ((child = fork())) {
+ case 0:
+ sigemptyset(&set);
+ sigsuspend(&set);
+ break;
+ case -1:
+ atf_tc_fail("fork failed");
+ default:
+ kill(child, SIGPIPE);
+ sigemptyset(&set);
+ sigsuspend(&set);
+ }
+}
+
+static sigjmp_buf sigfpe_flt_env;
+static void
+sigfpe_flt_action(int signo, siginfo_t *info, void *ptr)
+{
+
+ sig_debug(signo, info, (ucontext_t *)ptr);
+
+ if (fltdiv_signalled++ != 0)
+ atf_tc_fail("FPE handler called more than once");
+
+ ATF_REQUIRE_EQ(info->si_signo, SIGFPE);
+ ATF_REQUIRE_EQ(info->si_code, FPE_FLTDIV);
+ ATF_REQUIRE_EQ(info->si_errno, 0);
+
+ siglongjmp(sigfpe_flt_env, 1);
+}
+
+ATF_TC(sigfpe_flt);
+ATF_TC_HEAD(sigfpe_flt, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGFPE handler "
+ "for floating div-by-zero");
+}
+
+ATF_TC_BODY(sigfpe_flt, tc)
+{
+ struct sigaction sa;
+ double d = strtod("0", NULL);
+
+ if (isQEMU())
+ atf_tc_skip("Test does not run correctly under QEMU");
+#if defined(__powerpc__)
+ atf_tc_skip("Test not valid on powerpc");
+#endif
+ if (sigsetjmp(sigfpe_flt_env, 0) == 0) {
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = sigfpe_flt_action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGFPE, &sa, NULL);
+#ifdef HAVE_FENV
+ feenableexcept(FE_ALL_EXCEPT);
+#elif defined(_FLOAT_IEEE754)
+ fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP);
+#endif
+ printf("%g\n", 1 / d);
+ }
+ if (fltdiv_signalled == 0)
+ atf_tc_fail("FPE signal handler was not invoked");
+}
+
+static sigjmp_buf sigfpe_int_env;
+static void
+sigfpe_int_action(int signo, siginfo_t *info, void *ptr)
+{
+
+ sig_debug(signo, info, (ucontext_t *)ptr);
+
+ if (intdiv_signalled++ != 0)
+ atf_tc_fail("INTDIV handler called more than once");
+
+ ATF_REQUIRE_EQ(info->si_signo, SIGFPE);
+ ATF_REQUIRE_EQ(info->si_code, FPE_INTDIV);
+ atf_tc_expect_pass();
+ ATF_REQUIRE_EQ(info->si_errno, 0);
+
+ siglongjmp(sigfpe_int_env, 1);
+}
+
+ATF_TC(sigfpe_int);
+ATF_TC_HEAD(sigfpe_int, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGFPE handler "
+ "for integer div-by-zero (PR port-i386/43655)");
+}
+
+ATF_TC_BODY(sigfpe_int, tc)
+{
+ struct sigaction sa;
+ long l = strtol("0", NULL, 10);
+
+#if defined(__powerpc__)
+ atf_tc_skip("Test not valid on powerpc");
+#endif
+ if (sigsetjmp(sigfpe_int_env, 0) == 0) {
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = sigfpe_int_action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGFPE, &sa, NULL);
+#ifdef HAVE_FENV
+ feenableexcept(FE_ALL_EXCEPT);
+#elif defined(_FLOAT_IEEE754)
+ fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP);
+#endif
+ printf("%ld\n", 1 / l);
+ }
+ if (intdiv_signalled == 0)
+ atf_tc_fail("FPE signal handler was not invoked");
+}
+
+static void
+sigsegv_action(int signo, siginfo_t *info, void *ptr)
+{
+
+ sig_debug(signo, info, (ucontext_t *)ptr);
+
+ ATF_REQUIRE_EQ(info->si_signo, SIGSEGV);
+ ATF_REQUIRE_EQ(info->si_errno, 0);
+ ATF_REQUIRE_EQ(info->si_code, SEGV_MAPERR);
+ ATF_REQUIRE_EQ(info->si_addr, (void *)0);
+
+ atf_tc_pass();
+ /* NOTREACHED */
+}
+
+ATF_TC(sigsegv);
+ATF_TC_HEAD(sigsegv, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGSEGV handler");
+}
+
+ATF_TC_BODY(sigsegv, tc)
+{
+ struct sigaction sa;
+
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = sigsegv_action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGSEGV, &sa, NULL);
+
+ *(volatile long *)0 = 0;
+ atf_tc_fail("Test did not fault as expected");
+}
+
+static void
+sigbus_action(int signo, siginfo_t *info, void *ptr)
+{
+
+ printf("si_addr = %p\n", info->si_addr);
+ sig_debug(signo, info, (ucontext_t *)ptr);
+
+ ATF_REQUIRE_EQ(info->si_signo, SIGBUS);
+ ATF_REQUIRE_EQ(info->si_errno, 0);
+ ATF_REQUIRE_EQ(info->si_code, BUS_ADRALN);
+
+#if defined(__i386__) || defined(__x86_64__)
+ atf_tc_expect_fail("x86 architecture does not correctly "
+ "report the address where the unaligned access occured");
+#endif
+ ATF_REQUIRE_EQ(info->si_addr, (volatile void *)addr);
+
+ atf_tc_pass();
+ /* NOTREACHED */
+}
+
+ATF_TC(sigbus_adraln);
+ATF_TC_HEAD(sigbus_adraln, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that signal trampoline correctly calls SIGBUS handler "
+ "for invalid address alignment");
+}
+
+ATF_TC_BODY(sigbus_adraln, tc)
+{
+ struct sigaction sa;
+
+#if defined(__alpha__)
+ int rv, val;
+ size_t len = sizeof(val);
+ rv = sysctlbyname("machdep.unaligned_sigbus", &val, &len, NULL, 0);
+ ATF_REQUIRE(rv == 0);
+ if (val == 0)
+ atf_tc_skip("SIGBUS signal not enabled for unaligned accesses");
+#endif
+
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = sigbus_action;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGBUS, &sa, NULL);
+
+ /* Enable alignment checks for x86. 0x40000 is PSL_AC. */
+#if defined(__i386__)
+ __asm__("pushf; orl $0x40000, (%esp); popf");
+#elif defined(__amd64__)
+ __asm__("pushf; orl $0x40000, (%rsp); popf");
+#endif
+
+ addr = calloc(2, sizeof(int));
+ ATF_REQUIRE(addr != NULL);
+
+ if (isQEMU())
+ atf_tc_expect_fail("QEMU fails to trap unaligned accesses");
+
+ /* Force an unaligned access */
+ addr++;
+ printf("now trying to access unaligned address %p\n", addr);
+ ATF_REQUIRE_EQ(*(volatile int *)addr, 0);
+
+ atf_tc_fail("Test did not fault as expected");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sigalarm);
+ ATF_TP_ADD_TC(tp, sigchild_normal);
+ ATF_TP_ADD_TC(tp, sigchild_dump);
+ ATF_TP_ADD_TC(tp, sigchild_kill);
+ ATF_TP_ADD_TC(tp, sigfpe_flt);
+ ATF_TP_ADD_TC(tp, sigfpe_int);
+ ATF_TP_ADD_TC(tp, sigsegv);
+ ATF_TP_ADD_TC(tp, sigbus_adraln);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_sleep.c b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c
new file mode 100644
index 000000000000..f722ec9691b4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_sleep.c
@@ -0,0 +1,350 @@
+/* $NetBSD: t_sleep.c,v 1.8 2014/07/15 14:56:34 gson Exp $ */
+
+/*-
+ * Copyright (c) 2006 Frank Kardel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <errno.h>
+#include <poll.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <sys/cdefs.h>
+#include <sys/event.h>
+#include <sys/signal.h>
+
+#include "isqemu.h"
+
+#define BILLION 1000000000LL /* nano-seconds per second */
+#define MILLION 1000000LL /* nano-seconds per milli-second */
+
+#define ALARM 6 /* SIGALRM after this many seconds */
+#define MAXSLEEP 22 /* Maximum delay in seconds */
+#define KEVNT_TIMEOUT 10300 /* measured in milli-seconds */
+#define FUZZ (40 * MILLION) /* scheduling fuzz accepted - 40 ms */
+
+#ifdef __FreeBSD__
+#include <sys/time.h>
+#include <inttypes.h>
+#endif
+
+/*
+ * Timer notes
+ *
+ * Most tests use FUZZ as their initial delay value, but 'sleep'
+ * starts at 1sec (since it cannot handle sub-second intervals).
+ * Subsequent passes double the previous interval, up to MAXSLEEP.
+ *
+ * The current values result in 5 passes for the 'sleep' test (at 1,
+ * 2, 4, 8, and 16 seconds) and 10 passes for the other tests (at
+ * 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, and 20.48
+ * seconds).
+ *
+ * The ALARM is only set if the current pass's delay is longer, and
+ * only if the ALARM has not already been triggered.
+ *
+ * The 'kevent' test needs the ALARM to be set on a different pass
+ * from when the KEVNT_TIMEOUT fires. So set ALARM to fire on the
+ * penultimate pass, and the KEVNT_TIMEOUT on the final pass. We
+ * set KEVNT_TIMEOUT just barely long enough to put it into the
+ * last test pass, and set MAXSLEEP a couple seconds longer than
+ * necessary, in order to avoid a QEMU bug which nearly doubles
+ * some timers.
+ */
+
+static volatile int sig;
+
+int sleeptest(int (*)(struct timespec *, struct timespec *), bool, bool);
+int do_nanosleep(struct timespec *, struct timespec *);
+int do_select(struct timespec *, struct timespec *);
+#ifdef __NetBSD__
+int do_poll(struct timespec *, struct timespec *);
+#endif
+int do_sleep(struct timespec *, struct timespec *);
+int do_kevent(struct timespec *, struct timespec *);
+void sigalrm(int);
+
+void
+sigalrm(int s)
+{
+
+ sig++;
+}
+
+int
+do_nanosleep(struct timespec *delay, struct timespec *remain)
+{
+ int ret;
+
+ if (nanosleep(delay, remain) == -1)
+ ret = (errno == EINTR ? 0 : errno);
+ else
+ ret = 0;
+ return ret;
+}
+
+int
+do_select(struct timespec *delay, struct timespec *remain)
+{
+ int ret;
+ struct timeval tv;
+
+ TIMESPEC_TO_TIMEVAL(&tv, delay);
+ if (select(0, NULL, NULL, NULL, &tv) == -1)
+ ret = (errno == EINTR ? 0 : errno);
+ else
+ ret = 0;
+ return ret;
+}
+
+#ifdef __NetBSD__
+int
+do_poll(struct timespec *delay, struct timespec *remain)
+{
+ int ret;
+ struct timeval tv;
+
+ TIMESPEC_TO_TIMEVAL(&tv, delay);
+ if (pollts(NULL, 0, delay, NULL) == -1)
+ ret = (errno == EINTR ? 0 : errno);
+ else
+ ret = 0;
+ return ret;
+}
+#endif
+
+int
+do_sleep(struct timespec *delay, struct timespec *remain)
+{
+ struct timeval tv;
+
+ TIMESPEC_TO_TIMEVAL(&tv, delay);
+ remain->tv_sec = sleep(delay->tv_sec);
+ remain->tv_nsec = 0;
+
+ return 0;
+}
+
+int
+do_kevent(struct timespec *delay, struct timespec *remain)
+{
+ struct kevent ktimer;
+ struct kevent kresult;
+ int rtc, kq, kerrno;
+ int tmo;
+
+ ATF_REQUIRE_MSG((kq = kqueue()) != -1, "kqueue: %s", strerror(errno));
+
+ tmo = KEVNT_TIMEOUT;
+
+ /*
+ * If we expect the KEVNT_TIMEOUT to fire, and we're running
+ * under QEMU, make sure the delay is long enough to account
+ * for the effects of PR kern/43997 !
+ */
+ if (isQEMU() &&
+ tmo/1000 < delay->tv_sec && tmo/500 > delay->tv_sec)
+ delay->tv_sec = MAXSLEEP;
+
+ EV_SET(&ktimer, 1, EVFILT_TIMER, EV_ADD, 0, tmo, 0);
+
+ rtc = kevent(kq, &ktimer, 1, &kresult, 1, delay);
+ kerrno = errno;
+
+ (void)close(kq);
+
+ if (rtc == -1) {
+ ATF_REQUIRE_MSG(kerrno == EINTR, "kevent: %s", strerror(errno));
+ return 0;
+ }
+
+ if (delay->tv_sec * BILLION + delay->tv_nsec > tmo * MILLION)
+ ATF_REQUIRE_MSG(rtc > 0,
+ "kevent: KEVNT_TIMEOUT did not cause EVFILT_TIMER event");
+
+ return 0;
+}
+
+ATF_TC(nanosleep);
+ATF_TC_HEAD(nanosleep, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test nanosleep(2) timing");
+ atf_tc_set_md_var(tc, "timeout", "65");
+}
+
+ATF_TC_BODY(nanosleep, tc)
+{
+
+ sleeptest(do_nanosleep, true, false);
+}
+
+ATF_TC(select);
+ATF_TC_HEAD(select, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test select(2) timing");
+ atf_tc_set_md_var(tc, "timeout", "65");
+}
+
+ATF_TC_BODY(select, tc)
+{
+
+ sleeptest(do_select, true, true);
+}
+
+#ifdef __NetBSD__
+ATF_TC(poll);
+ATF_TC_HEAD(poll, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test poll(2) timing");
+ atf_tc_set_md_var(tc, "timeout", "65");
+}
+
+ATF_TC_BODY(poll, tc)
+{
+
+ sleeptest(do_poll, true, true);
+}
+#endif
+
+ATF_TC(sleep);
+ATF_TC_HEAD(sleep, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test sleep(3) timing");
+ atf_tc_set_md_var(tc, "timeout", "65");
+}
+
+ATF_TC_BODY(sleep, tc)
+{
+
+ sleeptest(do_sleep, false, false);
+}
+
+ATF_TC(kevent);
+ATF_TC_HEAD(kevent, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test kevent(2) timing");
+ atf_tc_set_md_var(tc, "timeout", "65");
+}
+
+ATF_TC_BODY(kevent, tc)
+{
+
+ sleeptest(do_kevent, true, true);
+}
+
+int
+sleeptest(int (*test)(struct timespec *, struct timespec *),
+ bool subsec, bool sim_remain)
+{
+ struct timespec tsa, tsb, tslp, tremain;
+ int64_t delta1, delta2, delta3, round;
+
+ sig = 0;
+ signal(SIGALRM, sigalrm);
+
+ if (subsec) {
+ round = 1;
+ delta3 = FUZZ;
+ } else {
+ round = 1000000000;
+ delta3 = round;
+ }
+
+ tslp.tv_sec = delta3 / 1000000000;
+ tslp.tv_nsec = delta3 % 1000000000;
+
+ while (tslp.tv_sec <= MAXSLEEP) {
+ /*
+ * disturb sleep by signal on purpose
+ */
+ if (tslp.tv_sec > ALARM && sig == 0)
+ alarm(ALARM);
+
+ clock_gettime(CLOCK_REALTIME, &tsa);
+ (*test)(&tslp, &tremain);
+ clock_gettime(CLOCK_REALTIME, &tsb);
+
+ if (sim_remain) {
+ timespecsub(&tsb, &tsa, &tremain);
+ timespecsub(&tslp, &tremain, &tremain);
+ }
+
+ delta1 = (int64_t)tsb.tv_sec - (int64_t)tsa.tv_sec;
+ delta1 *= BILLION;
+ delta1 += (int64_t)tsb.tv_nsec - (int64_t)tsa.tv_nsec;
+
+ delta2 = (int64_t)tremain.tv_sec * BILLION;
+ delta2 += (int64_t)tremain.tv_nsec;
+
+ delta3 = (int64_t)tslp.tv_sec * BILLION;
+ delta3 += (int64_t)tslp.tv_nsec - delta1 - delta2;
+
+ delta3 /= round;
+ delta3 *= round;
+
+ if (delta3 > FUZZ || delta3 < -FUZZ) {
+ if (!sim_remain)
+ atf_tc_expect_fail("Long reschedule latency "
+ "due to PR kern/43997");
+
+ atf_tc_fail("Reschedule latency %"PRId64" exceeds "
+ "allowable fuzz %lld", delta3, FUZZ);
+ }
+ delta3 = (int64_t)tslp.tv_sec * 2 * BILLION;
+ delta3 += (int64_t)tslp.tv_nsec * 2;
+
+ delta3 /= round;
+ delta3 *= round;
+ if (delta3 < FUZZ)
+ break;
+ tslp.tv_sec = delta3 / BILLION;
+ tslp.tv_nsec = delta3 % BILLION;
+ }
+ ATF_REQUIRE_MSG(sig == 1, "Alarm did not fire!");
+
+ atf_tc_pass();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, nanosleep);
+ ATF_TP_ADD_TC(tp, select);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, poll);
+#endif
+ ATF_TP_ADD_TC(tp, sleep);
+ ATF_TP_ADD_TC(tp, kevent);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_syslog.c b/contrib/netbsd-tests/lib/libc/gen/t_syslog.c
new file mode 100644
index 000000000000..c9417c06f302
--- /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 000000000000..790f3caada48
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_time.c
@@ -0,0 +1,117 @@
+/* $NetBSD: t_time.c,v 1.2 2011/11/11 05:03:38 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_time.c,v 1.2 2011/11/11 05:03:38 jruoho Exp $");
+
+#ifdef __FreeBSD__
+#include <sys/time.h>
+#endif
+#include <atf-c.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+ATF_TC(time_copy);
+ATF_TC_HEAD(time_copy, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test the return values of time(3)");
+}
+
+ATF_TC_BODY(time_copy, tc)
+{
+ time_t t1, t2 = 0;
+
+ t1 = time(&t2);
+
+ if (t1 != t2)
+ atf_tc_fail("incorrect return values from time(3)");
+}
+
+ATF_TC(time_mono);
+ATF_TC_HEAD(time_mono, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test monotonicity of time(3)");
+}
+
+ATF_TC_BODY(time_mono, tc)
+{
+ const size_t maxiter = 10;
+ time_t t1, t2;
+ size_t i;
+
+ for (i = 0; i < maxiter; i++) {
+
+ t1 = time(NULL);
+ (void)sleep(1);
+ t2 = time(NULL);
+
+ (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n",
+ (int64_t)t1, (int64_t)t2);
+
+ if (t1 >= t2)
+ atf_tc_fail("time(3) is not monotonic");
+ }
+}
+
+ATF_TC(time_timeofday);
+ATF_TC_HEAD(time_timeofday, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test time(3) vs. gettimeofday(2)");
+}
+
+ATF_TC_BODY(time_timeofday, tc)
+{
+ struct timeval tv = { 0, 0 };
+ time_t t;
+
+ t = time(NULL);
+ ATF_REQUIRE(gettimeofday(&tv, NULL) == 0);
+
+ (void)fprintf(stderr, "%"PRId64" vs. %"PRId64"\n",
+ (int64_t)t, (int64_t)tv.tv_sec);
+
+ if (t != tv.tv_sec)
+ atf_tc_fail("time(3) and gettimeofday(2) differ");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, time_copy);
+ ATF_TP_ADD_TC(tp, time_mono);
+ ATF_TP_ADD_TC(tp, time_timeofday);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c
new file mode 100644
index 000000000000..bb9d26420c3c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/gen/t_ttyname.c
@@ -0,0 +1,191 @@
+/* $NetBSD: t_ttyname.c,v 1.3 2011/05/01 18:14:01 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_ttyname.c,v 1.3 2011/05/01 18:14:01 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static long ttymax = 0;
+
+ATF_TC(ttyname_err);
+ATF_TC_HEAD(ttyname_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors in ttyname(3)");
+}
+
+ATF_TC_BODY(ttyname_err, tc)
+{
+ int fd;
+
+ fd = open("XXX", O_RDONLY);
+
+ if (fd < 0) {
+
+ errno = 0;
+
+ ATF_REQUIRE(isatty(fd) != -1);
+ ATF_REQUIRE(errno == EBADF);
+
+ errno = 0;
+
+ ATF_REQUIRE(ttyname(fd) == NULL);
+ ATF_REQUIRE(errno == EBADF);
+ }
+
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd >= 0) {
+
+ errno = 0;
+
+ ATF_REQUIRE(isatty(fd) != -1);
+ ATF_REQUIRE(errno == ENOTTY);
+
+ errno = 0;
+
+ ATF_REQUIRE(ttyname(fd) == NULL);
+ ATF_REQUIRE(errno == ENOTTY);
+ }
+}
+
+ATF_TC(ttyname_r_err);
+ATF_TC_HEAD(ttyname_r_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors in ttyname_r(3)");
+}
+
+ATF_TC_BODY(ttyname_r_err, tc)
+{
+ char sbuf[0];
+ char *buf;
+ int fd;
+ int rv;
+
+ buf = malloc(ttymax + 1);
+
+ if (buf == NULL)
+ return;
+
+ (void)memset(buf, '\0', ttymax + 1);
+
+ if (isatty(STDIN_FILENO) != 0) {
+
+ rv = ttyname_r(STDIN_FILENO, sbuf, sizeof(sbuf));
+ ATF_REQUIRE(rv == ERANGE);
+ }
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("FreeBSD returns ENOTTY instead of EBADF; see bin/191936");
+#endif
+ rv = ttyname_r(-1, buf, ttymax);
+ ATF_REQUIRE(rv == EBADF);
+
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd >= 0) {
+ rv = ttyname_r(fd, buf, ttymax);
+ ATF_REQUIRE(rv == ENOTTY);
+ ATF_REQUIRE(close(fd) == 0);
+ }
+
+ free(buf);
+}
+
+ATF_TC(ttyname_r_stdin);
+ATF_TC_HEAD(ttyname_r_stdin, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ttyname_r(3) with stdin(3)");
+}
+
+ATF_TC_BODY(ttyname_r_stdin, tc)
+{
+ const char *str;
+ char *buf;
+ int rv;
+
+ if (isatty(STDIN_FILENO) == 0)
+ return;
+
+ buf = malloc(ttymax + 1);
+
+ if (buf == NULL)
+ return;
+
+ (void)memset(buf, '\0', ttymax + 1);
+
+ str = ttyname(STDIN_FILENO);
+ rv = ttyname_r(STDIN_FILENO, buf, ttymax);
+
+ ATF_REQUIRE(rv == 0);
+ ATF_REQUIRE(str != NULL);
+
+ if (strcmp(str, buf) != 0)
+ atf_tc_fail("ttyname(3) and ttyname_r(3) conflict");
+
+ free(buf);
+}
+
+ATF_TC(ttyname_stdin);
+ATF_TC_HEAD(ttyname_stdin, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ttyname(3) with stdin(3)");
+}
+
+ATF_TC_BODY(ttyname_stdin, tc)
+{
+
+ if (isatty(STDIN_FILENO) != 0)
+ ATF_REQUIRE(ttyname(STDIN_FILENO) != NULL);
+
+ (void)close(STDIN_FILENO);
+
+ ATF_REQUIRE(isatty(STDIN_FILENO) != 1);
+ ATF_REQUIRE(ttyname(STDIN_FILENO) == NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ttymax = sysconf(_SC_TTY_NAME_MAX);
+ ATF_REQUIRE(ttymax >= 0);
+
+ ATF_TP_ADD_TC(tp, ttyname_err);
+ ATF_TP_ADD_TC(tp, ttyname_r_err);
+ ATF_TP_ADD_TC(tp, ttyname_r_stdin);
+ ATF_TP_ADD_TC(tp, ttyname_stdin);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/gen/t_vis.c b/contrib/netbsd-tests/lib/libc/gen/t_vis.c
new file mode 100644
index 000000000000..525bafafb17e
--- /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 000000000000..763e4f91ccae
--- /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 000000000000..bb86bb6556dc
--- /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 000000000000..632d13358459
--- /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 000000000000..c23a05876c27
--- /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 000000000000..a483a0e3c378
--- /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 000000000000..6e20a4889a25
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/h_hash.c
@@ -0,0 +1,187 @@
+/* $NetBSD: h_hash.c,v 1.1 2011/01/02 22:03:25 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Combined MD5/SHA1 time and regression test.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <md5.h>
+#ifdef __NetBSD__
+#include <sha1.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <sha.h>
+#endif
+
+int mflag, rflag, sflag, tflag;
+
+static void
+usage(void)
+{
+ (void)fprintf(stderr,
+ "Usage:\t%s -r[ms] < test-file\n"
+ "\t%s -t[ms]\n",
+ getprogname(), getprogname());
+ exit(1);
+ /* NOTREACHED */
+}
+
+static void
+hexdump (unsigned char *buf, int len)
+{
+ int i;
+ for (i=0; i<len; i++) {
+ printf("%02x", buf[i]);
+ }
+ printf("\n");
+}
+
+
+static void
+timetest(void)
+{
+ printf("sorry, not yet\n");
+}
+
+#define CHOMP(buf, len, last) \
+ if ((len > 0) && \
+ (buf[len-1] == '\n')) { \
+ buf[len-1] = '\0'; \
+ len--; \
+ last = 1; \
+ }
+
+static void
+regress(void)
+{
+ unsigned char buf[1024];
+ unsigned char out[20];
+ int len, outlen, last;
+
+ while (fgets((char *)buf, sizeof(buf), stdin) != NULL) {
+ last = 0;
+
+ len = strlen((char *)buf);
+ CHOMP(buf, len, last);
+ if (mflag) {
+ MD5_CTX ctx;
+
+ MD5Init(&ctx);
+ MD5Update(&ctx, buf, len);
+ while (!last &&
+ fgets((char *)buf, sizeof(buf), stdin) != NULL) {
+ len = strlen((char *)buf);
+ CHOMP(buf, len, last);
+ MD5Update(&ctx, buf, len);
+ }
+ MD5Final(out, &ctx);
+ outlen = 16;
+ } else {
+#ifdef __FreeBSD__
+ SHA_CTX ctx;
+
+ SHA1_Init(&ctx);
+ SHA1_Update(&ctx, buf, len);
+#else
+ SHA1_CTX ctx;
+
+ SHA1Init(&ctx);
+ SHA1Update(&ctx, buf, len);
+#endif
+ while (!last &&
+ fgets((char *)buf, sizeof(buf), stdin) != NULL) {
+ len = strlen((char *)buf);
+ CHOMP(buf, len, last);
+#ifdef __FreeBSD__
+ SHA1_Update(&ctx, buf, len);
+#else
+ SHA1Update(&ctx, buf, len);
+#endif
+ }
+#ifdef __FreeBSD__
+ SHA1_Final(out, &ctx);
+#else
+ SHA1Final(out, &ctx);
+#endif
+ outlen = 20;
+ }
+ hexdump(out, outlen);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ int ch;
+
+ while ((ch = getopt(argc, argv, "mrst")) != -1)
+ switch (ch) {
+ case 'm':
+ mflag = 1;
+ break;
+ case 'r':
+ rflag = 1;
+ break;
+ case 's':
+ sflag = 1;
+ break;
+ case 't':
+ tflag = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc > 0)
+ usage();
+
+ if (!(mflag || sflag))
+ mflag = 1;
+
+ if ((mflag ^ sflag) != 1)
+ usage();
+
+ if ((tflag ^ rflag) != 1)
+ usage();
+
+ if (tflag)
+ timetest();
+
+ if (rflag)
+ regress();
+
+ exit(0);
+
+}
diff --git a/contrib/netbsd-tests/lib/libc/hash/t_hash.sh b/contrib/netbsd-tests/lib/libc/hash/t_hash.sh
new file mode 100755
index 000000000000..719f19d30e67
--- /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 000000000000..ce2c80d31a80
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/hash/t_sha2.c
@@ -0,0 +1,257 @@
+/* $NetBSD: t_sha2.c,v 1.3 2012/09/26 22:23:30 joerg Exp $ */
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_sha2.c,v 1.3 2012/09/26 22:23:30 joerg Exp $");
+
+#include <atf-c.h>
+#include <sys/types.h>
+#ifdef __NetBSD__
+#include <sha2.h>
+#endif
+#include <string.h>
+
+#ifdef __FreeBSD__
+#include <openssl/sha.h>
+typedef SHA512_CTX SHA384_CTX;
+/* From /usr/src/crypto/openssh/openbsd-compat/sha2.h */
+#define SHA256_DIGEST_LENGTH 32
+#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
+#define SHA384_DIGEST_LENGTH 48
+#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
+#define SHA512_DIGEST_LENGTH 64
+#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
+#endif
+
+ATF_TC(t_sha256);
+ATF_TC(t_sha384);
+ATF_TC(t_sha512);
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_sha256);
+ ATF_TP_ADD_TC(tp, t_sha384);
+ ATF_TP_ADD_TC(tp, t_sha512);
+
+ return atf_no_error();
+}
+
+struct testvector {
+ const char *vector;
+ const char *hash;
+};
+
+static const struct testvector test256[] = {
+ { "hello, world", "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b" },
+ { "", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" },
+ { "a", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb" },
+ { "ab", "fb8e20fc2e4c3f248c60c39bd652f3c1347298bb977b8b4d5903b85055620603" },
+ { "abc", "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" },
+ { "abcd", "88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589" },
+ { "abcde", "36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0c44ca42c" },
+ { "abcdef", "bef57ec7f53a6d40beb640a780a639c83bc29ac8a9816f1fc6c5c6dcd93c4721" },
+ { "abcdefg", "7d1a54127b222502f5b79b5fb0803061152a44f92b37e23c6527baf665d4da9a" },
+ { "abcdefgh", "9c56cc51b374c3ba189210d5b6d4bf57790d351c96c47c02190ecf1e430635ab" },
+ { "abcdefghi", "19cc02f26df43cc571bc9ed7b0c4d29224a3ec229529221725ef76d021c8326f" },
+ { "abcdefghij", "72399361da6a7754fec986dca5b7cbaf1c810a28ded4abaf56b2106d06cb78b0" },
+ { "abcdefghijk", "ca2f2069ea0c6e4658222e06f8dd639659cbb5e67cbbba6734bc334a3799bc68" },
+ { "abcdefghijkl", "d682ed4ca4d989c134ec94f1551e1ec580dd6d5a6ecde9f3d35e6e4a717fbde4" },
+ { "abcdefghijklm", "ff10304f1af23606ede1e2d8abcdc94c229047a61458d809d8bbd53ede1f6598" },
+ { "abcdefghijklmn", "0653c7e992d7aad40cb2635738b870e4c154afb346340d02c797d490dd52d5f9" },
+ { "abcdefghijklmno", "41c7760c50efde99bf574ed8fffc7a6dd3405d546d3da929b214c8945acf8a97" },
+ { "abcdefghijklmnop", "f39dac6cbaba535e2c207cd0cd8f154974223c848f727f98b3564cea569b41cf" },
+ { "abcdefghijklmnopq", "918a954ac4dfb54ac39f068d9868227f69ab39bc362e2c9b0083bf6a109d6ad7" },
+ { "abcdefghijklmnopqr", "2d1222692afaf56e95a8ab00879ed023a00db3e26fa14236e542748579285efa" },
+ { "abcdefghijklmnopqrs", "e250f886728b77ba63722c7e65fc73e203101a84281b32332fd67cc6a1ae3e22" },
+ { "abcdefghijklmnopqrst", "dd65eea0329dcb94b17187af9dff28c31a1d78026737a16af75979a1fa4618e5" },
+ { "abcdefghijklmnopqrstu", "25f62a5a3d414ec6e20907df7f367f2b72625aade552db64c07933f6044fc49a" },
+ { "abcdefghijklmnopqrstuv", "f69f9b70d1c9a5442258ca76f8b0a7a45fcb4e31c36141b6357ec591328b0624" },
+ { "abcdefghijklmnopqrstuvw", "7f07818e14d08944ce145629ca54332f5cfad148c590efbcb5c377f4d336e5f4" },
+ { "abcdefghijklmnopqrstuvwq", "063132d7fbec0acb79b2f228777eec8885e7f09bc1896b3ce5aa1843e83de048" },
+};
+
+static const struct testvector test384[] = {
+ { "hello, world", "1fcdb6059ce05172a26bbe2a3ccc88ed5a8cd5fc53edfd9053304d429296a6da23b1cd9e5c9ed3bb34f00418a70cdb7e" },
+ { "", "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" },
+ { "a", "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31" },
+ { "ab", "c7be03ba5bcaa384727076db0018e99248e1a6e8bd1b9ef58a9ec9dd4eeebb3f48b836201221175befa74ddc3d35afdd" },
+ { "abc", "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7" },
+ { "abcd", "1165b3406ff0b52a3d24721f785462ca2276c9f454a116c2b2ba20171a7905ea5a026682eb659c4d5f115c363aa3c79b" },
+ { "abcde", "4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813521565abc0ec57a37ee4d8be89d097c0d2ad52f0" },
+ { "abcdef", "c6a4c65b227e7387b9c3e839d44869c4cfca3ef583dea64117859b808c1e3d8ae689e1e314eeef52a6ffe22681aa11f5" },
+ { "abcdefg", "9f11fc131123f844c1226f429b6a0a6af0525d9f40f056c7fc16cdf1b06bda08e302554417a59fa7dcf6247421959d22" },
+ { "abcdefgh", "9000cd7cada59d1d2eb82912f7f24e5e69cc5517f68283b005fa27c285b61e05edf1ad1a8a9bded6fd29eb87d75ad806" },
+ { "abcdefghi", "ef54915b60cf062b8dd0c29ae3cad69abe6310de63ac081f46ef019c5c90897caefd79b796cfa81139788a260ded52df" },
+ { "abcdefghij", "a12070030a02d86b0ddacd0d3a5b598344513d0a051e7355053e556a0055489c1555399b03342845c4adde2dc44ff66c" },
+ { "abcdefghijk", "2440d0e751fe5b8b1aba067e20be00b9deecc5e218b0b4b37202de824bcd04294d67c8d0b73e393afa844fa9ca25fa51" },
+ { "abcdefghijkl", "103ca96c06a1ce798f08f8eff0dfb0ccdb567d48b285b23d0cd773454667a3c2fa5f1b58d9cdf2329bd9979730bfaaff" },
+ { "abcdefghijklm", "89a7179df195462f047393c36e4843183eb38404bdfbacfd0b0f9c2556632a2799f19c3ecf48bdb7c9bdf95d3f6c3704" },
+ { "abcdefghijklmn", "3bc463b0a5614d39fd207cbfd108534bce68d5438235c6c577b34b70fe219954adceaf8808d1fad4a44fc9c420ea8ff1" },
+ { "abcdefghijklmno", "5149860ee76dd6666308189e60090d615e36ce0c0ef753a610cca0524a022900489d70167a47cc74c4dd9f9f340066af" },
+ { "abcdefghijklmnop", "96d3c1b54b1938600abe5b57232e185df1c5856f74656b8f9837c5317cf5b22ac38226fafc8c946b9d20aca1b0c53a98" },
+ { "abcdefghijklmnopq", "dae0d8c29d8f1137df3afb8f502dc474d3bbb56de0c10fc219547826f23f38f37ec29e4ed203908e6e7955c83a138129" },
+ { "abcdefghijklmnopqr", "5cfa62716d985d3b1efab0ed3460e7b7f6af9439ae8ee5c58b20e68607eeec3e8c6df8481f5f36e726eaa56512acea6e" },
+ { "abcdefghijklmnopqrs", "c5d404fc93b0e59ecb5f40446da201876faf18a0af46e577ae2f7a4fe56dc4c419afff7edec90ff3de160d0c5e7a5ec1" },
+ { "abcdefghijklmnopqrst", "bc1511cd8b813544cb60b13d1ceb63e81f46aa3ca114a23fc5c3aba54f9965cdf9afa68e2dc2a680934e429dff5aa7f2" },
+ { "abcdefghijklmnopqrstu", "8f18622d37e0aceabba191e3836b30e8970aca202ce6e811f586ec5f950edb7bf799cc88a18468a3effb063397242d95" },
+ { "abcdefghijklmnopqrstuv", "c8a4f46e609626543ce6c1362721fcbe95c8e7405aaee61da4f2da1740f0351172c98a66530f8607bf8609e387ff8456" },
+ { "abcdefghijklmnopqrstuvw", "2daff33b3bd67de61550070696b431d54b1397b40d053912b07a94260812185907726e3efbe9ae9fc078659cd2ce36db" },
+ { "abcdefghijklmnopqrstuvwq", "87dc70a2eaa0dd0b687f91f26383866161026e41bb310a9e32b7a17c99284db85b9743476a30caeedf3fbb3c8072bc5e" },
+};
+
+static const struct testvector test512[] = {
+ { "hello, world", "8710339dcb6814d0d9d2290ef422285c9322b7163951f9a0ca8f883d3305286f44139aa374848e4174f5aada663027e4548637b6d19894aec4fb6c46a139fbf9" },
+ { "", "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" },
+ { "a", "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75" },
+ { "ab", "2d408a0717ec188158278a796c689044361dc6fdde28d6f04973b80896e1823975cdbf12eb63f9e0591328ee235d80e9b5bf1aa6a44f4617ff3caf6400eb172d" },
+ { "abc", "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" },
+ { "abcd", "d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f" },
+ { "abcde", "878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665bef2289a5c70b0a1" },
+ { "abcdef", "e32ef19623e8ed9d267f657a81944b3d07adbb768518068e88435745564e8d4150a0a703be2a7d88b61e3d390c2bb97e2d4c311fdc69d6b1267f05f59aa920e7" },
+ { "abcdefg", "d716a4188569b68ab1b6dfac178e570114cdf0ea3a1cc0e31486c3e41241bc6a76424e8c37ab26f096fc85ef9886c8cb634187f4fddff645fb099f1ff54c6b8c" },
+ { "abcdefgh", "a3a8c81bc97c2560010d7389bc88aac974a104e0e2381220c6e084c4dccd1d2d17d4f86db31c2a851dc80e6681d74733c55dcd03dd96f6062cdda12a291ae6ce" },
+ { "abcdefghi", "f22d51d25292ca1d0f68f69aedc7897019308cc9db46efb75a03dd494fc7f126c010e8ade6a00a0c1a5f1b75d81e0ed5a93ce98dc9b833db7839247b1d9c24fe" },
+ { "abcdefghij", "ef6b97321f34b1fea2169a7db9e1960b471aa13302a988087357c520be957ca119c3ba68e6b4982c019ec89de3865ccf6a3cda1fe11e59f98d99f1502c8b9745" },
+ { "abcdefghijk", "2798fd001ee8800e3da09ee99ae9600de2d0ccf464ab782c92fcc06ce3847cef0743365f1d49c2c8b4426db1635433f937d508672a9d0cb673b84f368eca1b23" },
+ { "abcdefghijkl", "17807c728ee3ba35e7cf7af823116d26e41e5d4d6c2ff1f3720d3d96aacb6f69de642e63d5b73fc396c12be38b2bd5d884257c32c8f6d0854ae6b540f86dda2e" },
+ { "abcdefghijklm", "e11a66f7b9a2acda5663e9434377137d73ea560a32782230412642a463c8558123bfb7c0dbf17851e9aa58cc9587c3b4f5e3f7f38dcb6f890702e5bed4d5b54a" },
+ { "abcdefghijklmn", "8334134081070bf7fcc8bf1c242d24bb3182a5119e5fb19d8bbf6b9d0cdb7fed5336e83415fce93094c0e55123cf69e14d7ae41b22289232699824e31125b6d9" },
+ { "abcdefghijklmno", "db723f341a042d8de1aa813efd5e02fc1745ccbe259486257514804e2ec4bcebb2a46f1e4ad442154943f9e97e1bc47c3ae0eddab7de0c01a9c51f15342a5b19" },
+ { "abcdefghijklmnop", "d0cadd6834fa0c157b36cca30ee8b0b1435d841aa5b5ac850c11ae80a1440f51743e98fb1f1e7376c70f2f65404f088c28bcb4a511df2e64111f8f7424364b60" },
+ { "abcdefghijklmnopq", "6196942a8495b721f82bbc385c74c1f10eeadf35db8adc9cf1a05ddeed19351228279644cd5d686ee48a31631ebb64747a2b68b733dd6015e3d27750878fa875" },
+ { "abcdefghijklmnopqr", "fb3bd1fc157ea6f7a6728986a59b271b766fb723f6b7cf2b4194437435f2c497f33b6a56ae7eb3830fa9e04d5ebb4cb5e3f4d4bd812c498bdf0167e125de3fba" },
+ { "abcdefghijklmnopqrs", "836f9ecf2aa02f522a94f1370af45a9fd538ac3c70e3b709d614b2f8981881d6b0070fc6387b74ee371fc2549309f82926e78084b401deb61a106c399089bee8" },
+ { "abcdefghijklmnopqrst", "8cd9c137651425fb32d193d99b281735ec68eb5fd296f16459d1b33eac7badcfce0dca22eadaa5f209fa4ac3bbecd41342bac8b8a5dc3626e7f22cdc96e17cb4" },
+ { "abcdefghijklmnopqrstu", "7079853a3e36241a8d83639f168ef38e883d7f72851a84ef3ed4d91c6a3896cf542b8b4518c2816fb19d4692a4b9aae65cb857e3642ce0a3936e20363bcbd4ca" },
+ { "abcdefghijklmnopqrstuv", "a4e8a90b7058fb078e6cdcfd0c6a33c366437eb9084eac657830356804c9f9b53f121496d8e972d8707a4cf02615e6f58ed1a770c28ac79ffd845401fe18a928" },
+ { "abcdefghijklmnopqrstuvw", "d91b1fd7c7785975493826719f333d090b214ff42351c84d8f8b2538509a28d2d59a36d0ac798d99d3908083b072a4be606ae391def5daa74156350fec71dd24" },
+ { "abcdefghijklmnopqrstuvwq", "404eb5652173323320cac6bf8d9714aef0747693a8ab4570700c6262268d367f30e31c44fa66860568ff058fe39c9aa8dac76bc78566c691a884cb9052c4aa0a" },
+};
+
+static void
+digest2string(const uint8_t *digest, char *string, size_t len)
+{
+ while (len--) {
+ if (*digest / 16 < 10)
+ *string++ = '0' + *digest / 16;
+ else
+ *string++ = 'a' + *digest / 16 - 10;
+ if (*digest % 16 < 10)
+ *string++ = '0' + *digest % 16;
+ else
+ *string++ = 'a' + *digest % 16 - 10;
+ ++digest;
+ }
+ *string = '\0';
+}
+
+ATF_TC_HEAD(t_sha256, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test SHA256 functions for consistent results");
+}
+
+ATF_TC_BODY(t_sha256, tc)
+{
+ size_t i, j, len;
+ SHA256_CTX ctx;
+ unsigned char buf[256];
+ unsigned char digest[8 + SHA256_DIGEST_LENGTH];
+ char output[SHA256_DIGEST_STRING_LENGTH];
+
+ for (i = 0; i < sizeof(test256) / sizeof(test256[0]); ++i) {
+ len = strlen(test256[i].vector);
+ for (j = 0; j < 8; ++j) {
+ SHA256_Init(&ctx);
+ memcpy(buf + j, test256[i].vector, len);
+ SHA256_Update(&ctx, buf + j, len);
+ SHA256_Final(digest + j, &ctx);
+ digest2string(digest + j, output, SHA256_DIGEST_LENGTH);
+ ATF_CHECK_STREQ(test256[i].hash, output);
+ }
+ }
+}
+
+ATF_TC_HEAD(t_sha384, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test SHA384 functions for consistent results");
+}
+
+ATF_TC_BODY(t_sha384, tc)
+{
+ size_t i, j, len;
+ SHA384_CTX ctx;
+ unsigned char buf[384];
+ unsigned char digest[8 + SHA384_DIGEST_LENGTH];
+ char output[SHA384_DIGEST_STRING_LENGTH];
+
+ for (i = 0; i < sizeof(test384) / sizeof(test384[0]); ++i) {
+ len = strlen(test384[i].vector);
+ for (j = 0; j < 8; ++j) {
+ SHA384_Init(&ctx);
+ memcpy(buf + j, test384[i].vector, len);
+ SHA384_Update(&ctx, buf + j, len);
+ SHA384_Final(digest + j, &ctx);
+ digest2string(digest + j, output, SHA384_DIGEST_LENGTH);
+ ATF_CHECK_STREQ(test384[i].hash, output);
+ }
+ }
+}
+
+ATF_TC_HEAD(t_sha512, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test SHA512 functions for consistent results");
+}
+
+ATF_TC_BODY(t_sha512, tc)
+{
+ size_t i, j, len;
+ SHA512_CTX ctx;
+ unsigned char buf[512];
+ unsigned char digest[8 + SHA512_DIGEST_LENGTH];
+ char output[SHA512_DIGEST_STRING_LENGTH];
+
+ for (i = 0; i < sizeof(test512) / sizeof(test512[0]); ++i) {
+ len = strlen(test512[i].vector);
+ for (j = 0; j < 8; ++j) {
+ SHA512_Init(&ctx);
+ memcpy(buf + j, test512[i].vector, len);
+ SHA512_Update(&ctx, buf + j, len);
+ SHA512_Final(digest + j, &ctx);
+ digest2string(digest + j, output, SHA512_DIGEST_LENGTH);
+ ATF_CHECK_STREQ(test512[i].hash, output);
+ }
+ }
+}
diff --git a/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c b/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c
new file mode 100644
index 000000000000..a6a6c62b61dc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/inet/t_inet_network.c
@@ -0,0 +1,174 @@
+/* $NetBSD: t_inet_network.c,v 1.3 2011/07/15 11:27:23 jruoho Exp $ */
+
+/*
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Brian Ginsbach.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_inet_network.c,v 1.3 2011/07/15 11:27:23 jruoho Exp $");
+
+#include <arpa/inet.h>
+
+#include <atf-c.h>
+#include <stdio.h>
+#include <string.h>
+
+#define H_REQUIRE(input, expected) \
+ ATF_REQUIRE_EQ_MSG(inet_network(input), (in_addr_t) expected, \
+ "inet_network(%s) returned: 0x%08X, expected: %s", #input, \
+ inet_network(input), #expected)
+
+ATF_TC(inet_addr_basic);
+ATF_TC_HEAD(inet_addr_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks inet_addr(3)");
+}
+
+ATF_TC_BODY(inet_addr_basic, tc)
+{
+ static const char *addrs[] = {
+ "127.0.0.1", "99.99.99.99", "0.0.0.0", "255.255.255.255" };
+
+ struct in_addr ia;
+ const char *ian;
+ in_addr_t addr;
+ size_t i;
+
+ for (i = 0; i < __arraycount(addrs); i++) {
+
+ (void)fprintf(stderr, "checking %s\n", addrs[i]);;
+
+ addr = inet_addr(addrs[i]);
+ ia.s_addr = addr;
+ ian = inet_ntoa(ia);
+
+ ATF_REQUIRE(ian != NULL);
+ ATF_CHECK(strcmp(ian, addrs[i]) == 0);
+ }
+}
+
+ATF_TC(inet_addr_err);
+ATF_TC_HEAD(inet_addr_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Invalid addresses with inet_addr(3)");
+}
+
+ATF_TC_BODY(inet_addr_err, tc)
+{
+ static const char *addrs[] = {
+ ". . . .", "1.2.3.", "0.0.0.256", "255.255.255.256",
+ "................................................",
+ "a.b.c.d", "0x0.0x1.0x2.0x3", "-1.-1.-1.-1", "", " "};
+
+ struct in_addr ia;
+ const char *ian;
+ in_addr_t addr;
+ size_t i;
+
+ for (i = 0; i < __arraycount(addrs); i++) {
+
+ (void)fprintf(stderr, "checking %s\n", addrs[i]);;
+
+ addr = inet_addr(addrs[i]);
+ ia.s_addr = addr;
+ ian = inet_ntoa(ia);
+
+ ATF_REQUIRE(ian != NULL);
+ ATF_CHECK(strcmp(ian, addrs[i]) != 0);
+ }
+}
+
+ATF_TC(inet_network_basic);
+ATF_TC_HEAD(inet_network_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks inet_network(3)");
+}
+
+ATF_TC_BODY(inet_network_basic, tc)
+{
+
+ H_REQUIRE("0x12", 0x00000012);
+ H_REQUIRE("127.1", 0x00007f01);
+ H_REQUIRE("127.1.2.3", 0x7f010203);
+ H_REQUIRE("0X12", 0x00000012);
+ H_REQUIRE("0", 0x0);
+ H_REQUIRE("01.02.07.077", 0x0102073f);
+ H_REQUIRE("0x1.23.045.0", 0x01172500);
+ H_REQUIRE("0x12.0x34", 0x00001234);
+
+ /* This is valid (because of the trailing space after the digit). */
+ H_REQUIRE("1 bar", 0x00000001);
+}
+
+ATF_TC(inet_network_err);
+ATF_TC_HEAD(inet_network_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Invalid addresses w/ inet_network(3)");
+}
+
+ATF_TC_BODY(inet_network_err, tc)
+{
+ /* Malformed requests. */
+ H_REQUIRE("4.2.3.1.", 0xffffffff);
+ H_REQUIRE("0x123456", 0xffffffff);
+ H_REQUIRE("0x12.0x345", 0xffffffff);
+ H_REQUIRE("1.2.3.4.5", 0xffffffff);
+ H_REQUIRE("1..3.4", 0xffffffff);
+ H_REQUIRE(".", 0xffffffff);
+ H_REQUIRE("1.", 0xffffffff);
+ H_REQUIRE(".1", 0xffffffff);
+#if defined(__FreeBSD__) || defined(__APPLE__)
+ H_REQUIRE("0x", 0x0);
+#else
+ H_REQUIRE("0x", 0xffffffff);
+#endif
+ H_REQUIRE("", 0xffffffff);
+ H_REQUIRE(" ", 0xffffffff);
+ H_REQUIRE("bar", 0xffffffff);
+ H_REQUIRE("1.2bar", 0xffffffff);
+ H_REQUIRE("1.", 0xffffffff);
+ H_REQUIRE("\xc3\x8a\xc3\x83\xc3\x95\xc3\x8b\xc3\x85\xc3\x8e",
+ 0xffffffff);
+ H_REQUIRE("255.255.255.255", 0xffffffff);
+ H_REQUIRE("x", 0xffffffff);
+ H_REQUIRE("078", 0xffffffff);
+ H_REQUIRE("127.0xfff", 0xffffffff);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, inet_addr_basic);
+ ATF_TP_ADD_TC(tp, inet_addr_err);
+ ATF_TP_ADD_TC(tp, inet_network_basic);
+ ATF_TP_ADD_TC(tp, inet_network_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_io.c b/contrib/netbsd-tests/lib/libc/locale/t_io.c
new file mode 100644
index 000000000000..86029e934d58
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_io.c
@@ -0,0 +1,193 @@
+/* $NetBSD: t_io.c,v 1.4 2014/01/21 00:32:16 yamt Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_io.c,v 1.4 2014/01/21 00:32:16 yamt Exp $");
+
+#include <sys/param.h>
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+
+ATF_TC(bad_big5_wprintf);
+ATF_TC_HEAD(bad_big5_wprintf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar wprintf");
+}
+
+ATF_TC_BODY(bad_big5_wprintf, tc)
+{
+#ifdef __FreeBSD__
+ atf_tc_skip("does not fail as expected (may be implementation "
+ "specific issue with the test)");
+#endif
+
+ /* XXX implementation detail knowledge (wchar_t encoding) */
+ wchar_t ibuf[] = { 0xcf10, 0 };
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+
+ ATF_REQUIRE_ERRNO(EILSEQ, wprintf(L"%ls\n", ibuf) < 0);
+ ATF_REQUIRE(ferror(stdout));
+}
+
+ATF_TC(bad_big5_swprintf);
+ATF_TC_HEAD(bad_big5_swprintf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar swprintf");
+}
+
+ATF_TC_BODY(bad_big5_swprintf, tc)
+{
+#ifdef __FreeBSD__
+ atf_tc_skip("does not fail as expected (may be implementation "
+ "specific issue with the test)");
+#endif
+
+ /* XXX implementation detail knowledge (wchar_t encoding) */
+ wchar_t ibuf[] = { 0xcf10, 0 };
+ wchar_t obuf[20];
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+
+ ATF_REQUIRE_ERRNO(EILSEQ,
+ swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf) < 0);
+}
+
+ATF_TC(good_big5_wprintf);
+ATF_TC_HEAD(good_big5_wprintf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test good big5 wchar wprintf");
+}
+
+ATF_TC_BODY(good_big5_wprintf, tc)
+{
+ /* XXX implementation detail knowledge (wchar_t encoding) */
+ wchar_t ibuf[] = { 0xcf40, 0 };
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+ ATF_REQUIRE_EQ(wprintf(L"%ls\n", ibuf), 2);
+}
+
+ATF_TC(good_big5_swprintf);
+ATF_TC_HEAD(good_big5_swprintf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test good big5 wchar swprintf");
+}
+
+ATF_TC_BODY(good_big5_swprintf, tc)
+{
+ /* XXX implementation detail knowledge (wchar_t encoding) */
+ wchar_t ibuf[] = { 0xcf40, 0 };
+ wchar_t obuf[20];
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+ ATF_REQUIRE_EQ(swprintf(obuf, sizeof(obuf), L"%ls\n", ibuf), 2);
+}
+
+struct ibuf {
+ off_t off;
+ size_t buflen;
+ const char *buf;
+};
+
+static int
+readfn(void *vp, char *buf, int len)
+{
+ struct ibuf *ib = vp;
+ size_t todo = MIN((size_t)len, ib->buflen - ib->off);
+
+ memcpy(buf, ib->buf + ib->off, todo);
+ ib->off += todo;
+ return todo;
+}
+
+ATF_TC(good_big5_getwc);
+ATF_TC_HEAD(good_big5_getwc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test good big5 wchar getwc");
+}
+
+ATF_TC_BODY(good_big5_getwc, tc)
+{
+ const char buf[] = { 0xcf, 0x40 };
+ struct ibuf ib = {
+ .buf = buf,
+ .buflen = sizeof(buf),
+ };
+ FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL);
+
+ ATF_REQUIRE(fp != NULL);
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+ /* XXX implementation detail knowledge (wchar_t encoding) */
+ ATF_REQUIRE_EQ(getwc(fp), 0xcf40);
+ fclose(fp);
+}
+
+ATF_TC(bad_big5_getwc);
+ATF_TC_HEAD(bad_big5_getwc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test bad big5 wchar getwc");
+}
+
+ATF_TC_BODY(bad_big5_getwc, tc)
+{
+ const char buf[] = { 0xcf, 0x20 };
+ struct ibuf ib = {
+ .buf = buf,
+ .buflen = sizeof(buf),
+ };
+ FILE *fp = funopen(&ib, readfn, NULL, NULL, NULL);
+
+ ATF_REQUIRE(fp != NULL);
+ setlocale(LC_CTYPE, "zh_TW.Big5");
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("does not return WEOF as expected");
+#endif
+ ATF_REQUIRE_EQ(getwc(fp), WEOF);
+ fclose(fp);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, bad_big5_wprintf);
+ ATF_TP_ADD_TC(tp, bad_big5_swprintf);
+ ATF_TP_ADD_TC(tp, good_big5_wprintf);
+ ATF_TP_ADD_TC(tp, good_big5_swprintf);
+ ATF_TP_ADD_TC(tp, good_big5_getwc);
+ ATF_TP_ADD_TC(tp, bad_big5_getwc);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c
new file mode 100644
index 000000000000..8b3876fa7882
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_mbrtowc.c
@@ -0,0 +1,277 @@
+/* $NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by YAMAMOTO Takashi
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c)2003 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_mbrtowc.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $");
+
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vis.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+#define SIZE 256
+
+static struct test {
+ const char *locale;
+ const char *data;
+ const wchar_t wchars[64];
+ const wchar_t widths[64];
+ size_t length;
+} tests[] = {
+{
+ "C",
+ "ABCD01234_\\",
+ { 0x41, 0x42, 0x43, 0x44, 0x30, 0x31, 0x32, 0x33, 0x34, 0x5F, 0x5C },
+ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ 11
+}, {
+ "en_US.UTF-8",
+ "[\001\177][\302\200\337\277][\340\240\200\357\277\277][\360\220\200"
+ "\200\367\277\277\277][\370\210\200\200\200\373\277\277\277\277][\374"
+ "\204\200\200\200\200\375\277\277\277\277\277]",
+ { 0x5b, 0x01, 0x7f, 0x5d, 0x5b, 0x80, 0x7ff, 0x5d, 0x5b, 0x800, 0xffff,
+ 0x5d, 0x5b, 0x10000, 0x1fffff, 0x5d, 0x5b, 0x200000, 0x3ffffff, 0x5d,
+ 0x5b, 0x4000000, 0x7fffffff, 0x5d },
+ { 1, 1, 1, 1, 1, 2, 2, 1, 1, 3, 3, 1, 1, 4, 4, 1, 1, 5, 5, 1, 1, 6, 6, 1 },
+ 24
+}, {
+ "ja_JP.ISO2022-JP2",
+ "\033$BF|K\1348l\033(BA\033$B$\"\033(BB\033$B$$\033(B",
+ { 0x4200467c, 0x42004b5c, 0x4200386c, 0x41, 0x42002422, 0x42, 0x42002424 },
+ { 5, 2, 2, 4, 5, 4, 5 },
+ 7
+}, {
+ "ja_JP.SJIS",
+ "\223\372\226{\214\352A\202\240B\202\242",
+ { 0x93fa, 0x967b, 0x8cea, 0x41, 0x82a0, 0x42, 0x82a2 },
+ { 2, 2, 2, 1, 2, 1, 2 },
+ 7
+}, {
+ "ja_JP.eucJP",
+ "\306\374\313\334\270\354A\244\242B\244\244",
+ { 0xc6fc, 0xcbdc, 0xb8ec, 0x41, 0xa4a2, 0x42, 0xa4a4 },
+ { 2, 2, 2, 1, 2, 1, 2 },
+ 7
+}, {
+ NULL,
+ NULL,
+ { },
+ { },
+ 0
+}
+};
+
+static void
+h_ctype2(const struct test *t, bool use_mbstate)
+{
+ mbstate_t *stp;
+ mbstate_t st;
+ char buf[SIZE];
+ char *str;
+ size_t n;
+
+ ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
+#ifdef __NetBSD__
+ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
+#else
+ if (setlocale(LC_CTYPE, t->locale) == NULL) {
+ fprintf(stderr, "Locale %s not found.\n", t->locale);
+ return;
+ }
+#endif
+
+ (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Checking string: \"%s\"\n", buf);
+
+ ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL);
+ (void)printf("Using locale: %s\n", str);
+
+ (void)printf("Using mbstate: %s\n", use_mbstate ? "yes" : "no");
+
+ (void)memset(&st, 0, sizeof(st));
+// mbrtowc(0, 0, 0, &st); /* XXX for ISO2022-JP */
+ stp = use_mbstate ? &st : 0;
+
+ for (n = 9; n > 0; n--) {
+ const char *src = t->data;
+ wchar_t dst;
+ size_t nchar = 0;
+ int width = 0;
+
+ ATF_REQUIRE(mbsinit(stp) != 0);
+
+ for (;;) {
+ size_t rv = mbrtowc(&dst, src, n, stp);
+
+ if (rv == 0)
+ break;
+
+ if (rv == (size_t)-2) {
+ src += n;
+ width += n;
+
+ continue;
+ }
+ if (rv == (size_t)-1) {
+ ATF_REQUIRE_EQ(errno, EILSEQ);
+ atf_tc_fail("Invalid sequence");
+ /* NOTREACHED */
+ }
+
+ width += rv;
+ src += rv;
+
+ if (dst != t->wchars[nchar] ||
+ width != t->widths[nchar]) {
+ (void)printf("At position %zd:\n", nchar);
+ (void)printf(" expected: 0x%04X (%u)\n",
+ t->wchars[nchar], t->widths[nchar]);
+ (void)printf(" got : 0x%04X (%u)\n",
+ dst, width);
+ atf_tc_fail("Test failed");
+ }
+
+ nchar++;
+ width = 0;
+ }
+
+ ATF_REQUIRE_EQ_MSG(dst, 0, "Incorrect terminating character: "
+ "0x%04X (expected: 0x00)", dst);
+
+ ATF_REQUIRE_EQ_MSG(nchar, t->length, "Incorrect length: "
+ "%zd (expected: %zd)", nchar, t->length);
+ }
+
+ {
+ wchar_t wbuf[SIZE];
+ size_t rv;
+ char const *src = t->data;
+ int i;
+
+ (void)memset(wbuf, 0xFF, sizeof(wbuf));
+
+ rv = mbsrtowcs(wbuf, &src, SIZE, stp);
+
+ ATF_REQUIRE_EQ_MSG(rv, t->length, "Incorrect length: %zd "
+ "(expected: %zd)", rv, t->length);
+ ATF_REQUIRE_EQ(src, NULL);
+
+ for (i = 0; wbuf[i] != 0; ++i) {
+ if (wbuf[i] == t->wchars[i])
+ continue;
+
+ (void)printf("At position %d:\n", i);
+ (void)printf(" expected: 0x%04X\n", t->wchars[i]);
+ (void)printf(" got : 0x%04X\n", wbuf[i]);
+ atf_tc_fail("Test failed");
+ }
+
+ ATF_REQUIRE_EQ_MSG((size_t)i, t->length, "Incorrect length: "
+ "%d (expected: %zd)", i, t->length);
+ }
+
+ (void)printf("Ok.\n");
+}
+
+ATF_TC(mbrtowc_internal);
+ATF_TC_HEAD(mbrtowc_internal, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks mbrtowc(3) and mbsrtowcs(3) (using internal "
+ "state) with different locales");
+}
+ATF_TC_BODY(mbrtowc_internal, tc)
+{
+ struct test *t;
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("ja_* locale fails");
+#endif
+ for (t = &tests[0]; t->data != NULL; ++t)
+ h_ctype2(t, false);
+}
+
+ATF_TC(mbrtowc_object);
+ATF_TC_HEAD(mbrtowc_object, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks mbrtowc(3) and mbsrtowcs(3) (using state "
+ "object) with different locales");
+}
+ATF_TC_BODY(mbrtowc_object, tc)
+{
+ struct test *t;
+
+ for (t = &tests[0]; t->data != NULL; ++t)
+ h_ctype2(t, true);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mbrtowc_internal);
+ ATF_TP_ADD_TC(tp, mbrtowc_object);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c b/contrib/netbsd-tests/lib/libc/locale/t_mbsnrtowcs.c
new file mode 100644
index 000000000000..446d7ef499d3
--- /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 000000000000..f8c06d394d68
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_mbstowcs.c
@@ -0,0 +1,209 @@
+/* $NetBSD: t_mbstowcs.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c)2003 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_mbstowcs.c,v 1.1 2011/07/15 07:35:21 jruoho Exp $");
+
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vis.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+#define REQUIRE_ERRNO(x, v) \
+ ATF_REQUIRE_MSG((x) != (v), "%s: %s", #x, strerror(errno))
+
+#define SIZE 256
+
+static struct test {
+ const char *locale;
+ const char *data;
+ wchar_t wchars[64];
+ int widths[64];
+ int width;
+} tests[] = {
+{
+ "en_US.UTF-8",
+ "[\001\177][\302\200\337\277][\340\240\200\357\277\277][\360\220\200"
+ "\200\367\277\277\277][\370\210\200\200\200\373\277\277\277\277][\374"
+ "\204\200\200\200\200\375\277\277\277\277\277]",
+ {
+ 0x5B, 0x01, 0x7F, 0x5D, 0x5B, 0x80, 0x07FF, 0x5D, 0x5B, 0x0800,
+ 0xFFFF, 0x5D, 0x5B, 0x10000, 0x1FFFFF, 0x5D, 0x5B, 0x200000,
+ 0x3FFFFFF, 0x5D, 0x5B, 0x4000000, 0x7FFFFFFF, 0x5D, 0x0A
+ },
+ { 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1,
+ 1, 1, -1, -1, 1, 1, -1, -1, 1, -1
+ },
+ -1
+}, {
+ "ja_JP.ISO2022-JP",
+ "\033$B#J#I#S$G$9!#\033(Baaaa\033$B$\"$$$&$($*\033(B",
+ {
+ 0x4200234A, 0x42002349, 0x42002353, 0x42002447, 0x42002439,
+ 0x42002123, 0x61, 0x61, 0x61, 0x61, 0x42002422, 0x42002424,
+ 0x42002426, 0x42002428, 0x4200242A, 0x0A
+ },
+ { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 },
+ 26
+}, {
+ "ja_JP.SJIS",
+ "\202r\202i\202h\202r\202\305\202\267\201Baaaa\202\240\202\242"
+ "\202\244\202\246\202\250",
+ {
+ 0x8272, 0x8269, 0x8268, 0x8272, 0x82C5, 0x82B7, 0x8142, 0x61,
+ 0x61, 0x61, 0x61, 0x82A0, 0x82A2, 0x82A4, 0x82A6, 0x82A8, 0x0A
+ },
+ { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 },
+ 28
+}, {
+ "ja_JP.eucJP",
+ "\243\305\243\325\243\303\244\307\244\271\241\243aaaa\244\242\244"
+ "\244\244\246\244\250\244\252",
+ {
+ 0xA3C5, 0xA3D5, 0xA3C3, 0xA4C7, 0xA4B9, 0xA1A3, 0x61, 0x61, 0x61,
+ 0x61, 0xA4A2, 0xA4A4, 0xA4A6, 0xA4A8, 0xA4AA, 0x0A
+ },
+ { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, -1 },
+ 26
+}, {
+ NULL,
+ NULL,
+ {},
+ {},
+ 0
+}
+};
+
+ATF_TC(mbstowcs_basic);
+ATF_TC_HEAD(mbstowcs_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks wide character functions with different locales");
+}
+ATF_TC_BODY(mbstowcs_basic, tc)
+{
+ struct test *t;
+
+ for (t = &tests[0]; t->data != NULL; ++t) {
+ wchar_t wbuf[SIZE];
+ char buf[SIZE];
+ char visbuf[SIZE];
+ char *str;
+ int i;
+
+ ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
+#ifdef __NetBSD__
+ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
+#else
+ if (setlocale(LC_CTYPE, t->locale) == NULL) {
+ fprintf(stderr, "Locale %s not found.\n", t->locale);
+ continue;
+ }
+#endif
+
+ (void)strvis(visbuf, t->data, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Checking string: \"%s\"\n", visbuf);
+
+ ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL);
+ (void)printf("Using locale: %s\n", str);
+
+ REQUIRE_ERRNO((ssize_t)mbstowcs(wbuf, t->data, SIZE-1), -1);
+ REQUIRE_ERRNO((ssize_t)wcstombs(buf, wbuf, SIZE-1), -1);
+
+ if (strcmp(buf, t->data) != 0) {
+ (void)strvis(visbuf, buf, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Conversion to wcs and back failed: "
+ "\"%s\"\n", visbuf);
+ atf_tc_fail("Test failed");
+ }
+
+ /* The output here is implementation-dependent. */
+
+ for (i = 0; wbuf[i] != 0; ++i) {
+ if (wbuf[i] == t->wchars[i] &&
+ wcwidth(wbuf[i]) == t->widths[i])
+ continue;
+
+ (void)printf("At position %d:\n", i);
+ (void)printf(" expected: 0x%04X (%d)\n",
+ t->wchars[i], t->widths[i]);
+ (void)printf(" got : 0x%04X (%d)\n", wbuf[i],
+ wcwidth(wbuf[i]));
+ atf_tc_fail("Test failed");
+ }
+
+ if (wcswidth(wbuf, SIZE-1) != t->width) {
+ (void)printf("Incorrect wcswidth:\n");
+ (void)printf(" expected: %d\n", t->width);
+ (void)printf(" got : %d\n", wcswidth(wbuf, SIZE-1));
+ atf_tc_fail("Test failed");
+ }
+
+ (void)printf("Ok.\n");
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, mbstowcs_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c
new file mode 100644
index 000000000000..7816260e9281
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_mbtowc.c
@@ -0,0 +1,157 @@
+/* $NetBSD: t_mbtowc.c,v 1.1 2011/04/09 17:45:25 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c)2007 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_mbtowc.c,v 1.1 2011/04/09 17:45:25 pgoyette Exp $");
+
+#include <errno.h>
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vis.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+static void
+h_mbtowc(const char *locale, const char *illegal, const char *legal)
+{
+ char buf[64];
+ size_t stateful, ret;
+ char *str;
+
+ ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
+#ifdef __NetBSD__
+ ATF_REQUIRE(setlocale(LC_CTYPE, locale) != NULL);
+#else
+ if (setlocale(LC_CTYPE, locale) == NULL) {
+ fprintf(stderr, "Locale %s not found.\n", locale);
+ return;
+ }
+#endif
+
+ ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL);
+ (void)printf("Using locale: %s\n", str);
+
+ stateful = wctomb(NULL, L'\0');
+ (void)printf("Locale is state-%sdependent\n",
+ stateful ? "in" : "");
+
+ /* initialize internal state */
+ ret = mbtowc(NULL, NULL, 0);
+ ATF_REQUIRE(stateful ? ret : !ret);
+
+ (void)strvis(buf, illegal, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Checking illegal sequence: \"%s\"\n", buf);
+
+ ret = mbtowc(NULL, illegal, strlen(illegal));
+ (void)printf("mbtowc() returned: %zd\n", ret);
+ ATF_REQUIRE_EQ(ret, (size_t)-1);
+ (void)printf("errno: %s\n", strerror(errno));
+ ATF_REQUIRE_EQ(errno, EILSEQ);
+
+ /* if this is stateless encoding, this re-initialization is not required. */
+ if (stateful) {
+ /* re-initialize internal state */
+ ret = mbtowc(NULL, NULL, 0);
+ ATF_REQUIRE(stateful ? ret : !ret);
+ }
+
+ /* valid multibyte sequence case */
+ (void)strvis(buf, legal, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Checking legal sequence: \"%s\"\n", buf);
+
+ errno = 0;
+ ret = mbtowc(NULL, legal, strlen(legal));
+ (void)printf("mbtowc() returned: %zd\n", ret);
+ ATF_REQUIRE(ret != (size_t)-1);
+ (void)printf("errno: %s\n", strerror(errno));
+ ATF_REQUIRE_EQ(errno, 0);
+
+ (void)printf("Ok.\n");
+}
+
+ATF_TC(mbtowc);
+ATF_TC_HEAD(mbtowc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks mbtowc(3)");
+}
+ATF_TC_BODY(mbtowc, tc)
+{
+ h_mbtowc("en_US.UTF-8", "\240", "\302\240");
+ h_mbtowc("ja_JP.ISO2022-JP", "\033$B", "\033$B$\"\033(B");
+ h_mbtowc("ja_JP.SJIS", "\202", "\202\240");
+ h_mbtowc("ja_JP.eucJP", "\244", "\244\242");
+#ifndef __FreeBSD__
+ /* Moved last as it fails */
+ h_mbtowc("zh_CN.GB18030", "\241", "\241\241");
+#endif
+ h_mbtowc("zh_TW.Big5", "\241", "\241@");
+ h_mbtowc("zh_TW.eucTW", "\241", "\241\241");
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("zh_CN.GB18030");
+ h_mbtowc("zh_CN.GB18030", "\241", "\241\241");
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, mbtowc);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c b/contrib/netbsd-tests/lib/libc/locale/t_wcscspn.c
new file mode 100644
index 000000000000..10756b5cc4e2
--- /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 000000000000..57c1ac54be3c
--- /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 000000000000..2083650b331a
--- /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 000000000000..8d1ef33a1a2d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_wcstod.c
@@ -0,0 +1,460 @@
+/* $NetBSD: t_wcstod.c,v 1.3 2011/10/01 17:56:11 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c)2005 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_wcstod.c,v 1.3 2011/10/01 17:56:11 christos Exp $");
+
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+
+#include <atf-c.h>
+
+#ifdef __FreeBSD__
+#include <stdio.h>
+#endif
+
+#define ALT_HUGE_VAL -1
+#define ALT_MINUS_HUGE_VAL -2
+#define ALT_NAN -3
+
+#if !defined(__vax__)
+static struct test {
+ const wchar_t *wcs;
+ size_t len;
+ double val;
+ int err;
+} tests[] = {
+{ L"IN", 0, 0, 0 },
+{ L"+IN", 0, 0, 0 },
+{ L"-IN", 0, 0, 0 },
+{ L"INX", 0, 0, 0 },
+{ L"+INX", 0, 0, 0 },
+{ L"-INX", 0, 0, 0 },
+{ L"INF", 3, ALT_HUGE_VAL, 0 },
+{ L"+INF", 4, ALT_HUGE_VAL, 0 },
+{ L"-INF", 4, ALT_MINUS_HUGE_VAL, 0 },
+{ L"INFX", 3, ALT_HUGE_VAL, 0 },
+{ L"+INFX", 4, ALT_HUGE_VAL, 0 },
+{ L"-INFX", 4, ALT_MINUS_HUGE_VAL, 0 },
+{ L" IN", 0, 0, 0 },
+{ L" +IN", 0, 0, 0 },
+{ L" -IN", 0, 0, 0 },
+{ L" INX", 0, 0, 0 },
+{ L" +INX", 0, 0, 0 },
+{ L" -INX", 0, 0, 0 },
+{ L"+ INF", 0, 0, 0 },
+{ L"- INF", 0, 0, 0 },
+{ L" INF", 8, ALT_HUGE_VAL, 0 },
+{ L" +INF", 9, ALT_HUGE_VAL, 0 },
+{ L" -INF", 9, ALT_MINUS_HUGE_VAL, 0 },
+{ L" INFX", 8, ALT_HUGE_VAL, 0 },
+{ L" +INFX", 9, ALT_HUGE_VAL, 0 },
+{ L" -INFX", 9, ALT_MINUS_HUGE_VAL, 0 },
+{ L" INFINIT", 8, ALT_HUGE_VAL, 0 },
+{ L" +INFINIT", 9, ALT_HUGE_VAL, 0 },
+{ L" -INFINIT", 9, ALT_MINUS_HUGE_VAL, 0 },
+{ L" INFINITY", 13, ALT_HUGE_VAL, 0 },
+{ L" +INFINITY", 14, ALT_HUGE_VAL, 0 },
+{ L" -INFINITY", 14, ALT_MINUS_HUGE_VAL, 0 },
+{ L" INFINITYX", 13, ALT_HUGE_VAL, 0 },
+{ L" +INFINITYX", 14, ALT_HUGE_VAL, 0 },
+{ L" -INFINITYX", 14, ALT_MINUS_HUGE_VAL, 0 },
+
+/* NAN */
+{ L"NA", 0, 0, 0 },
+{ L"+NA", 0, 0, 0 },
+{ L"-NA", 0, 0, 0 },
+{ L"NAX", 0, 0, 0 },
+{ L"+NAX", 0, 0, 0 },
+{ L"-NAX", 0, 0, 0 },
+{ L"NAN", 3, ALT_NAN, 0 },
+{ L"+NAN", 4, ALT_NAN, 0 },
+{ L"-NAN", 4, ALT_NAN, 0 },
+{ L"NANX", 3, ALT_NAN, 0 },
+{ L"+NANX", 4, ALT_NAN, 0 },
+{ L"-NANX", 4, ALT_NAN, 0 },
+{ L" NA", 0, 0, 0 },
+{ L" +NA", 0, 0, 0 },
+{ L" -NA", 0, 0, 0 },
+{ L" NAX", 0, 0, 0 },
+{ L" +NAX", 0, 0, 0 },
+{ L" -NAX", 0, 0, 0 },
+{ L"+ NAN", 0, 0, 0 },
+{ L"- NAN", 0, 0, 0 },
+{ L" NAN", 8, ALT_NAN, 0 },
+{ L" +NAN", 9, ALT_NAN, 0 },
+{ L" -NAN", 9, ALT_NAN, 0 },
+{ L" NANX", 8, ALT_NAN, 0 },
+{ L" +NANX", 9, ALT_NAN, 0 },
+{ L" -NANX", 9, ALT_NAN, 0 },
+
+{ L"0", 1, 0, 0 },
+{ L"+0", 2, 0, 0 },
+{ L"-0", 2, 0, 0 },
+{ L" 0", 11, 0, 0 },
+{ L" +0", 12, 0, 0 },
+{ L" -0", 12, 0, 0 },
+{ L"+ 0", 0, 0, 0 },
+{ L"- 0", 0, 0, 0 },
+
+{ L".", 0, 0, 0 },
+{ L".0", 2, 0, 0 },
+{ L".00", 3, 0, 0 },
+{ L".000", 4, 0, 0 },
+
+{ L"0.", 2, 0, 0 },
+{ L"+0.", 3, 0, 0 },
+{ L"-0.", 3, 0, 0 },
+{ L" 0.", 12, 0, 0 },
+{ L" +0.", 13, 0, 0 },
+{ L" -0.", 13, 0, 0 },
+
+{ L"0.0", 3, 0, 0 },
+{ L"+0.0", 4, 0, 0 },
+{ L"-0.0", 4, 0, 0 },
+{ L" 0.0", 13, 0, 0 },
+{ L" +0.0", 14, 0, 0 },
+{ L" -0.0", 14, 0, 0 },
+
+{ L"000", 3, 0, 0 },
+{ L"+000", 4, 0, 0 },
+{ L"-000", 4, 0, 0 },
+{ L" 000", 13, 0, 0 },
+{ L" +000", 14, 0, 0 },
+{ L" -000", 14, 0, 0 },
+
+{ L"000.", 4, 0, 0 },
+{ L"+000.", 5, 0, 0 },
+{ L"-000.", 5, 0, 0 },
+{ L" 000.", 14, 0, 0 },
+{ L" +000.", 15, 0, 0 },
+{ L" -000.", 15, 0, 0 },
+
+{ L"000.0", 5, 0, 0 },
+{ L"+000.0", 6, 0, 0 },
+{ L"-000.0", 6, 0, 0 },
+{ L" 000.0", 15, 0, 0 },
+{ L" +000.0", 16, 0, 0 },
+{ L" -000.0", 16, 0, 0 },
+
+
+{ L"0.0.", 3, 0, 0 },
+{ L"+0.0.", 4, 0, 0 },
+{ L"-0.0.", 4, 0, 0 },
+{ L" 0.0.", 13, 0, 0 },
+{ L" +0.0.", 14, 0, 0 },
+{ L" -0.0.", 14, 0, 0 },
+
+{ L"0.0.0", 3, 0, 0 },
+{ L"+0.0.0", 4, 0, 0 },
+{ L"-0.0.0", 4, 0, 0 },
+{ L" 0.0.0", 13, 0, 0 },
+{ L" +0.0.0", 14, 0, 0 },
+{ L" -0.0.0", 14, 0, 0 },
+
+/* XXX: FIXME */
+#if defined(__linux__)
+{ L"0X", 2, 0, 0 },
+{ L"+0X", 3, 0, 0 },
+{ L"-0X", 3, 0, 0 },
+#else
+{ L"0X", 1, 0, 0 },
+{ L"+0X", 2, 0, 0 },
+{ L"-0X", 2, 0, 0 },
+#endif
+
+/* XXX: SunOS 5.8's wcstod(3) doesn't accept hex */
+#if !defined(__SunOS__)
+#if defined(__linux__)
+{ L"0X.", 3, 0, 0 },
+{ L"+0X.", 4, 0, 0 },
+{ L"-0X.", 4, 0, 0 },
+{ L" 0X.", 13, 0, 0 },
+{ L" +0X.", 14, 0, 0 },
+{ L" -0X.", 14, 0, 0 },
+#else
+{ L"0X.", 1, 0, 0 },
+{ L"+0X.", 2, 0, 0 },
+{ L"-0X.", 2, 0, 0 },
+{ L" 0X.", 11, 0, 0 },
+{ L" +0X.", 12, 0, 0 },
+{ L" -0X.", 12, 0, 0 },
+#endif
+/* XXX: FIXME */
+#if defined(__NetBSD__) || defined(__linux__) || defined(__FreeBSD__)
+{ L"0X.0", 4, 0, 0 },
+{ L"+0X.0", 5, 0, 0 },
+{ L"-0X.0", 5, 0, 0 },
+{ L" 0X.0", 14, 0, 0 },
+{ L" +0X.0", 15, 0, 0 },
+{ L" -0X.0", 15, 0, 0 },
+
+{ L"0X.0P", 4, 0, 0 },
+{ L"+0X.0P", 5, 0, 0 },
+{ L"-0X.0P", 5, 0, 0 },
+{ L" 0X.0P", 14, 0, 0 },
+{ L" +0X.0P", 15, 0, 0 },
+{ L" -0X.0P", 15, 0, 0 },
+#else
+{ L"0X.0", 1, 0, 0 },
+{ L"+0X.0", 2, 0, 0 },
+{ L"-0X.0", 2, 0, 0 },
+{ L" 0X.0", 11, 0, 0 },
+{ L" +0X.0", 12, 0, 0 },
+{ L" -0X.0", 12, 0, 0 },
+
+{ L"0X.0P", 1, 0, 0 },
+{ L"+0X.0P", 2, 0, 0 },
+{ L"-0X.0P", 2, 0, 0 },
+{ L" 0X.0P", 11, 0, 0 },
+{ L" +0X.0P", 12, 0, 0 },
+{ L" -0X.0P", 12, 0, 0 },
+#endif
+
+{ L"0X0", 3, 0, 0 },
+{ L"+0X0", 4, 0, 0 },
+{ L"-0X0", 4, 0, 0 },
+{ L" 0X0", 13, 0, 0 },
+{ L" +0X0", 14, 0, 0 },
+{ L" -0X0", 14, 0, 0 },
+
+{ L"00X0.0", 2, 0, 0 },
+{ L"+00X0.0", 3, 0, 0 },
+{ L"-00X0.0", 3, 0, 0 },
+{ L" 00X0.0", 12, 0, 0 },
+{ L" +00X0.0", 13, 0, 0 },
+{ L" -00X0.0", 13, 0, 0 },
+
+{ L"0X0P", 3, 0, 0 },
+{ L"+0X0P", 4, 0, 0 },
+{ L"-0X0P", 4, 0, 0 },
+{ L" 0X0P", 13, 0, 0 },
+{ L" +0X0P", 14, 0, 0 },
+{ L" -0X0P", 14, 0, 0 },
+
+{ L"0X0.", 4, 0, 0 },
+{ L"+0X0.", 5, 0, 0 },
+{ L"-0X0.", 5, 0, 0 },
+{ L" 0X0.", 14, 0, 0 },
+{ L" +0X0.", 15, 0, 0 },
+{ L" -0X0.", 15, 0, 0 },
+
+{ L"0X0.0", 5, 0, 0 },
+{ L"+0X0.0", 6, 0, 0 },
+{ L"-0X0.0", 6, 0, 0 },
+{ L" 0X0.0", 15, 0, 0 },
+{ L" +0X0.0", 16, 0, 0 },
+{ L" -0X0.0", 16, 0, 0 },
+
+{ L"0X0.P", 4, 0, 0 },
+{ L"+0X0.P", 5, 0, 0 },
+{ L"-0X0.P", 5, 0, 0 },
+{ L" 0X0.P", 14, 0, 0 },
+{ L" +0X0.P", 15, 0, 0 },
+{ L" -0X0.P", 15, 0, 0 },
+
+{ L"0X0.P", 4, 0, 0 },
+{ L"+0X0.P", 5, 0, 0 },
+{ L"-0X0.P", 5, 0, 0 },
+{ L" 0X0.P", 14, 0, 0 },
+{ L" +0X0.P", 15, 0, 0 },
+{ L" -0X0.P", 15, 0, 0 },
+
+#endif
+{ L"0.12345678", 10, 0.12345678, 0 },
+{ L"+0.12345678", 11, +0.12345678, 0 },
+{ L"-0.12345678", 11, -0.12345678, 0 },
+{ L" 0.12345678", 15, 0.12345678, 0 },
+{ L" +0.12345678", 16, +0.12345678, 0 },
+{ L" -0.12345678", 16, -0.12345678, 0 },
+
+{ L"0.12345E67", 10, 0.12345E67, 0 },
+{ L"+0.12345E67", 11, +0.12345E67, 0 },
+{ L"-0.12345E67", 11, -0.12345E67, 0 },
+{ L" 0.12345E67", 15, 0.12345E67, 0 },
+{ L" +0.12345E67", 16, +0.12345E67, 0 },
+{ L" -0.12345E67", 16, -0.12345E67, 0 },
+
+{ L"0.12345E+6", 10, 0.12345E+6, 0 },
+{ L"+0.12345E+6", 11, +0.12345E+6, 0 },
+{ L"-0.12345E+6", 11, -0.12345E+6, 0 },
+{ L" 0.12345E+6", 15, 0.12345E+6, 0 },
+{ L" +0.12345E+6", 16, +0.12345E+6, 0 },
+{ L" -0.12345E+6", 16, -0.12345E+6, 0 },
+
+{ L"0.98765E-4", 10, 0.98765E-4, 0 },
+{ L"+0.98765E-4", 11, +0.98765E-4, 0 },
+{ L"-0.98765E-4", 11, -0.98765E-4, 0 },
+{ L" 0.98765E-4", 15, 0.98765E-4, 0 },
+{ L" +0.98765E-4", 16, +0.98765E-4, 0 },
+{ L" -0.98765E-4", 16, -0.98765E-4, 0 },
+
+{ L"12345678E9", 10, 12345678E9, 0 },
+{ L"+12345678E9", 11, +12345678E9, 0 },
+{ L"-12345678E9", 11, -12345678E9, 0 },
+{ L" 12345678E9", 15, 12345678E9, 0 },
+{ L" +12345678E9", 16, +12345678E9, 0 },
+{ L" -12345678E9", 16, -12345678E9, 0 },
+
+/* XXX: SunOS 5.8's wcstod(3) doesn't accept hex */
+#if !defined(__SunOS__)
+{ L"0x1P+2", 6, 4, 0 },
+{ L"+0x1P+2", 7, +4, 0 },
+{ L"-0x1P+2", 7, -4, 0 },
+{ L" 0x1P+2", 11, 4, 0 },
+{ L" +0x1P+2", 12, +4, 0 },
+{ L" -0x1P+2", 12, -4, 0 },
+
+{ L"0x1.0P+2", 8, 4, 0 },
+{ L"+0x1.0P+2", 9, +4, 0 },
+{ L"-0x1.0P+2", 9, -4, 0 },
+{ L" 0x1.0P+2", 13, 4, 0 },
+{ L" +0x1.0P+2", 14, +4, 0 },
+{ L" -0x1.0P+2", 14, -4, 0 },
+
+{ L"0x1P-2", 6, 0.25, 0 },
+{ L"+0x1P-2", 7, +0.25, 0 },
+{ L"-0x1P-2", 7, -0.25, 0 },
+{ L" 0x1P-2", 11, 0.25, 0 },
+{ L" +0x1P-2", 12, +0.25, 0 },
+{ L" -0x1P-2", 12, -0.25, 0 },
+
+{ L"0x1.0P-2", 8, 0.25, 0 },
+{ L"+0x1.0P-2", 9, +0.25, 0 },
+{ L"-0x1.0P-2", 9, -0.25, 0 },
+{ L" 0x1.0P-2", 13, 0.25, 0 },
+{ L" +0x1.0P-2", 14, +0.25, 0 },
+{ L" -0x1.0P-2", 14, -0.25, 0 },
+#endif
+
+{ NULL, 0, 0, 0 }
+};
+#endif /* !defined(__vax__) */
+
+ATF_TC(wcstod);
+ATF_TC_HEAD(wcstod, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks wcstod(3)");
+}
+ATF_TC_BODY(wcstod, tc)
+{
+#if defined(__vax__)
+#else
+ struct test *t;
+#endif
+
+#if !defined(__vax__)
+ for (t = &tests[0]; t->wcs != NULL; ++t) {
+ double d;
+ size_t n;
+ wchar_t *tail;
+ char *buf;
+
+ /* we do not supported %ls nor %S yet. */
+ n = wcstombs(NULL, t->wcs, 0);
+ ATF_REQUIRE((buf = (void *)malloc(n + 1)) != NULL);
+ (void)wcstombs(buf, t->wcs, n + 1);
+ (void)printf("Checking wcstod(\"%s\", &tail):\n", buf);
+ free(buf);
+
+ errno = 0;
+ d = wcstod(t->wcs, &tail);
+ (void)printf("[errno]\n");
+ (void)printf(" got : %s\n", strerror(errno));
+ (void)printf(" expected: %s\n", strerror(t->err));
+ ATF_REQUIRE_EQ(errno, t->err);
+
+ n = (size_t)(tail - t->wcs);
+ (void)printf("[endptr - nptr]\n");
+ (void)printf(" got : %zd\n", n);
+ (void)printf(" expected: %zd\n", t->len);
+ ATF_REQUIRE_EQ(n, t->len);
+
+ (void)printf("[result]\n");
+ (void)printf(" real: %F\n", d);
+ if (t->val == ALT_HUGE_VAL) {
+ (void)printf(" expected: %F\n", HUGE_VAL);
+ ATF_REQUIRE(isinf(d));
+ ATF_REQUIRE_EQ(d, HUGE_VAL);
+ } else if (t->val == ALT_MINUS_HUGE_VAL) {
+ (void)printf(" expected: %F\n", -HUGE_VAL);
+ ATF_REQUIRE(isinf(d));
+ ATF_REQUIRE_EQ(d, -HUGE_VAL);
+ } else if (t->val == ALT_NAN) {
+ (void)printf(" expected: %F\n", NAN);
+ ATF_REQUIRE(isnan(d));
+ } else {
+ (void)printf(" expected: %F\n", t->val);
+ ATF_REQUIRE_EQ(d, t->val);
+ }
+
+ (void)printf("\n");
+ }
+#else /* !defined(__vax__) */
+ atf_tc_skip("Test is unavailable on vax.");
+#endif /* !defined(__vax__) */
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, wcstod);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c
new file mode 100644
index 000000000000..3405e9761017
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/locale/t_wctomb.c
@@ -0,0 +1,212 @@
+/* $NetBSD: t_wctomb.c,v 1.3 2013/03/25 15:31:03 gson Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c)2004 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_wctomb.c,v 1.3 2013/03/25 15:31:03 gson Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <vis.h>
+#include <wchar.h>
+#include <string.h>
+#include <limits.h>
+
+#include <atf-c.h>
+
+#define TC_WCTOMB 0
+#define TC_WCRTOMB 1
+#define TC_WCRTOMB_ST 2
+
+static struct test {
+ const char *locale;
+ const char *data;
+ size_t wclen;
+ size_t mblen[16];
+} tests[] = {
+{
+ "ja_JP.ISO2022-JP",
+ "\x1b$B" /* JIS X 0208-1983 */
+ "\x46\x7c\x4b\x5c\x38\x6c" /* "nihongo" */
+ "\x1b(B" /* ISO 646 */
+ "ABC"
+ "\x1b(I" /* JIS X 0201 katakana */
+ "\xb1\xb2\xb3" /* "aiu" */
+ "\x1b(B", /* ISO 646 */
+ 3 + 3 + 3,
+ { 3+2, 2, 2, 3+1, 1, 1, 3+1, 1, 1, 3+1 }
+}, {
+ "C",
+ "ABC",
+ 3,
+ { 1, 1, 1, 1 }
+}, { NULL, NULL, 0, { } }
+};
+
+static void
+h_wctomb(const struct test *t, char tc)
+{
+ wchar_t wcs[16 + 2];
+ char buf[128];
+ char cs[MB_LEN_MAX];
+ const char *pcs;
+ char *str;
+ mbstate_t st;
+ mbstate_t *stp = NULL;
+ size_t sz, ret, i;
+
+ ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
+#ifdef __NetBSD__
+ ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
+#else
+ if (setlocale(LC_CTYPE, t->locale) == NULL) {
+ fprintf(stderr, "Locale %s not found.\n", t->locale);
+ return;
+ }
+#endif
+
+ (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL);
+ (void)printf("Checking sequence: \"%s\"\n", buf);
+
+ ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL);
+ (void)printf("Using locale: %s\n", str);
+
+ if (tc == TC_WCRTOMB_ST) {
+ (void)memset(&st, 0, sizeof(st));
+ stp = &st;
+ }
+
+ wcs[t->wclen] = L'X'; /* poison */
+ pcs = t->data;
+ sz = mbsrtowcs(wcs, &pcs, t->wclen + 2, NULL);
+ ATF_REQUIRE_EQ_MSG(sz, t->wclen, "mbsrtowcs() returned: "
+ "%zu, expected: %zu", sz, t->wclen);
+ ATF_REQUIRE_EQ(wcs[t->wclen], 0);
+
+ for (i = 0; i < t->wclen + 1; i++) {
+ if (tc == TC_WCTOMB)
+ ret = wctomb(cs, wcs[i]);
+ else
+ ret = wcrtomb(cs, wcs[i], stp);
+
+ if (ret == t->mblen[i])
+ continue;
+
+ (void)printf("At position %zd:\n", i);
+ (void)printf(" expected: %zd\n", t->mblen[i]);
+ (void)printf(" got : %zd\n", ret);
+ atf_tc_fail("Test failed");
+ /* NOTREACHED */
+ }
+
+ (void)printf("Ok.\n");
+}
+
+ATF_TC(wctomb);
+ATF_TC_HEAD(wctomb, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks wctomb(3)");
+}
+ATF_TC_BODY(wctomb, tc)
+{
+ struct test *t;
+
+ (void)printf("Checking wctomb()\n");
+
+ for (t = &tests[0]; t->data != NULL; ++t)
+ h_wctomb(t, TC_WCTOMB);
+}
+
+ATF_TC(wcrtomb_state);
+ATF_TC_HEAD(wcrtomb_state, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks wcrtomb(3) (using state object)");
+}
+ATF_TC_BODY(wcrtomb_state, tc)
+{
+ struct test *t;
+
+ (void)printf("Checking wcrtomb() (with state object)\n");
+
+ for (t = &tests[0]; t->data != NULL; ++t)
+ h_wctomb(t, TC_WCRTOMB_ST);
+}
+
+ATF_TC(wcrtomb);
+ATF_TC_HEAD(wcrtomb, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks wcrtomb(3) (using internal state)");
+}
+ATF_TC_BODY(wcrtomb, tc)
+{
+ struct test *t;
+
+ (void)printf("Checking wcrtomb() (using internal state)\n");
+
+ for (t = &tests[0]; t->data != NULL; ++t)
+ h_wctomb(t, TC_WCRTOMB);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, wctomb);
+ ATF_TP_ADD_TC(tp, wcrtomb);
+ ATF_TP_ADD_TC(tp, wcrtomb_state);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/gen_ether_subr b/contrib/netbsd-tests/lib/libc/net/gen_ether_subr
new file mode 100755
index 000000000000..9f9b63c7d049
--- /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 000000000000..e856fe7e9a5e
--- /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 000000000000..d2945f2bc270
--- /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 000000000000..0238f83bbd5f
--- /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 000000000000..939fcdb355f8
--- /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 000000000000..21059c7aa063
--- /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 000000000000..7d30fea6a81c
--- /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 000000000000..9de5c56db6f2
--- /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 000000000000..1df56636ec50
--- /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 000000000000..d06d163c24e4
--- /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 000000000000..bc850e02836f
--- /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 000000000000..a4f2fb81fd1e
--- /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 000000000000..1c0ce43b2147
--- /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 000000000000..e24036e8a27a
--- /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 000000000000..94a3c0b2e52c
--- /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 000000000000..b6133c004e0e
--- /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 000000000000..a8f0caa41312
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/h_dns_server.c
@@ -0,0 +1,415 @@
+/* $NetBSD: h_dns_server.c,v 1.4 2014/03/29 16:10:54 gson Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Andreas Gustafsson.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * A minimal DNS server capable of providing canned answers to the
+ * specific queries issued by t_hostent.sh and nothing more.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: h_dns_server.c,v 1.4 2014/03/29 16:10:54 gson Exp $");
+
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#ifdef __NetBSD__
+#include <netinet6/in6.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <paths.h>
+#endif
+
+union sockaddr_either {
+ struct sockaddr s;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+};
+
+#ifdef DEBUG
+#define DPRINTF(...) fprintf(stderr, __VA_ARGS__)
+#else
+#define DPRINTF(...)
+#endif
+
+/* A DNS question and its corresponding answer */
+
+struct dns_data {
+ size_t qname_size;
+ const char *qname; /* Wire-encode question name */
+ int qtype;
+ size_t answer_size;
+ const char *answer; /* One wire-encoded answer RDATA */
+};
+
+/* Convert C string constant to length + data pair */
+#define STR_DATA(s) sizeof(s) - 1, s
+
+/* Canned DNS queestion-answer pairs */
+struct dns_data data[] = {
+ /* Forward mappings */
+ /* localhost IN A -> 127.0.0.1 */
+ { STR_DATA("\011localhost\000"), 1,
+ STR_DATA("\177\000\000\001") },
+ /* localhost IN AAAA -> ::1 */
+ { STR_DATA("\011localhost\000"), 28,
+ STR_DATA("\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001") },
+ /* sixthavenue.astron.com IN A -> 38.117.134.16 */
+ { STR_DATA("\013sixthavenue\006astron\003com\000"), 1,
+ STR_DATA("\046\165\206\020") },
+ /* sixthavenue.astron.com IN AAAA -> 2620:106:3003:1f00:3e4a:92ff:fef4:e180 */
+ { STR_DATA("\013sixthavenue\006astron\003com\000"), 28,
+ STR_DATA("\x26\x20\x01\x06\x30\x03\x1f\x00\x3e\x4a\x92\xff\xfe\xf4\xe1\x80") },
+ /* Reverse mappings */
+ { STR_DATA("\0011\0010\0010\003127\007in-addr\004arpa\000"), 12,
+ STR_DATA("\011localhost\000") },
+ { STR_DATA("\0011\0010\0010\0010\0010\0010\0010\0010"
+ "\0010\0010\0010\0010\0010\0010\0010\0010"
+ "\0010\0010\0010\0010\0010\0010\0010\0010"
+ "\0010\0010\0010\0010\0010\0010\0010\0010"
+ "\003ip6\004arpa\000"), 12,
+ STR_DATA("\011localhost\000") },
+ { STR_DATA("\00216\003134\003117\00238"
+ "\007in-addr\004arpa\000"), 12,
+ STR_DATA("\013sixthavenue\006astron\003com\000") },
+ { STR_DATA("\0010\0018\0011\001e\0014\001f\001e\001f"
+ "\001f\001f\0012\0019\001a\0014\001e\0013"
+ "\0010\0010\001f\0011\0013\0010\0010\0013"
+ "\0016\0010\0011\0010\0010\0012\0016\0012"
+ "\003ip6\004arpa\000"), 12,
+ STR_DATA("\013sixthavenue\006astron\003com\000") },
+ /* End marker */
+ { STR_DATA(""), 0, STR_DATA("") }
+};
+
+/*
+ * Compare two DNS names for equality. If equal, return their
+ * length, and if not, return zero. Does not handle compression.
+ */
+static int
+name_eq(const unsigned char *a, const unsigned char *b) {
+ const unsigned char *a_save = a;
+ for (;;) {
+ int i;
+ int lena = *a++;
+ int lenb = *b++;
+ if (lena != lenb)
+ return 0;
+ if (lena == 0)
+ return a - a_save;
+ for (i = 0; i < lena; i++)
+ if (tolower(a[i]) != tolower(b[i]))
+ return 0;
+ a += lena;
+ b += lena;
+ }
+}
+
+#ifdef DEBUG
+static char *
+name2str(const void *v, char *buf, size_t buflen) {
+ const unsigned char *a = v;
+ char *b = buf;
+ char *eb = buf + buflen;
+
+#define ADDC(c) do { \
+ if (b < eb) \
+ *b++ = c; \
+ else \
+ return NULL; \
+ } while (/*CONSTCOND*/0)
+ for (int did = 0;; did++) {
+ int lena = *a++;
+ if (lena == 0) {
+ ADDC('\0');
+ return buf;
+ }
+ if (did)
+ ADDC('.');
+ for (int i = 0; i < lena; i++)
+ ADDC(a[i]);
+ a += lena;
+ }
+}
+#endif
+
+#ifdef __FreeBSD__
+/* XXX the daemon2_* functions should be in a library */
+
+int __daemon2_detach_pipe[2];
+
+static int
+daemon2_fork(void)
+{
+ int r;
+ int fd;
+ int i;
+
+ /*
+ * Set up the pipe, making sure the write end does not
+ * get allocated one of the file descriptors that will
+ * be closed in daemon2_detach().
+ */
+ for (i = 0; i < 3; i++) {
+ r = pipe(__daemon2_detach_pipe);
+ if (r < 0)
+ return -1;
+ if (__daemon2_detach_pipe[1] <= STDERR_FILENO &&
+ (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+ (void)dup2(fd, __daemon2_detach_pipe[0]);
+ (void)dup2(fd, __daemon2_detach_pipe[1]);
+ if (fd > STDERR_FILENO)
+ (void)close(fd);
+ continue;
+ }
+ break;
+ }
+
+ r = fork();
+ if (r < 0) {
+ return -1;
+ } else if (r == 0) {
+ /* child */
+ close(__daemon2_detach_pipe[0]);
+ return 0;
+ }
+ /* Parent */
+
+ (void) close(__daemon2_detach_pipe[1]);
+
+ for (;;) {
+ char dummy;
+ r = read(__daemon2_detach_pipe[0], &dummy, 1);
+ if (r < 0) {
+ if (errno == EINTR)
+ continue;
+ _exit(1);
+ } else if (r == 0) {
+ _exit(1);
+ } else { /* r > 0 */
+ _exit(0);
+ }
+ }
+}
+
+static int
+daemon2_detach(int nochdir, int noclose)
+{
+ int r;
+ int fd;
+
+ if (setsid() == -1)
+ return -1;
+
+ if (!nochdir)
+ (void)chdir("/");
+
+ if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
+ (void)dup2(fd, STDIN_FILENO);
+ (void)dup2(fd, STDOUT_FILENO);
+ (void)dup2(fd, STDERR_FILENO);
+ if (fd > STDERR_FILENO)
+ (void)close(fd);
+ }
+
+ while (1) {
+ r = write(__daemon2_detach_pipe[1], "", 1);
+ if (r < 0) {
+ if (errno == EINTR)
+ continue;
+ /* May get "broken pipe" here if parent is killed */
+ return -1;
+ } else if (r == 0) {
+ /* Should not happen */
+ return -1;
+ } else {
+ break;
+ }
+ }
+
+ (void) close(__daemon2_detach_pipe[1]);
+
+ return 0;
+}
+#endif
+
+int main(int argc, char **argv) {
+ int s, r, protocol;
+ union sockaddr_either saddr;
+ struct dns_data *dp;
+ unsigned char *p;
+ char pidfile_name[40];
+ FILE *f;
+ int one = 1;
+#ifdef DEBUG
+ char buf1[1024], buf2[1024];
+#endif
+
+#ifdef __FreeBSD__
+ daemon2_fork();
+#endif
+ if (argc < 2 || ((protocol = argv[1][0]) != '4' && protocol != '6'))
+ errx(1, "usage: dns_server 4 | 6");
+ s = socket(protocol == '4' ? PF_INET : PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (s < 0)
+ err(1, "socket");
+ if (protocol == '4') {
+ memset(&saddr.sin, 0, sizeof(saddr.sin));
+ saddr.sin.sin_family = AF_INET;
+ saddr.sin.sin_len = sizeof(saddr.sin);
+ saddr.sin.sin_port = htons(53);
+ saddr.sin.sin_addr.s_addr = INADDR_ANY;
+ } else {
+ static struct in6_addr loopback = IN6ADDR_LOOPBACK_INIT;
+ memset(&saddr.sin6, 0, sizeof(saddr.sin6));
+ saddr.sin6.sin6_family = AF_INET6;
+ saddr.sin6.sin6_len = sizeof(saddr.sin6);
+ saddr.sin6.sin6_port = htons(53);
+ saddr.sin6.sin6_addr = loopback;
+ }
+
+ r = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one);
+ if (r < 0)
+ err(1, "setsockopt");
+
+ r = bind(s,
+ (struct sockaddr *) &saddr,
+ protocol == '4' ? sizeof(struct sockaddr_in) :
+ sizeof(struct sockaddr_in6));
+ if (r < 0)
+ err(1, "bind");
+
+ snprintf(pidfile_name, sizeof pidfile_name,
+ "dns_server_%c.pid", protocol);
+ f = fopen(pidfile_name, "w");
+ fprintf(f, "%d", getpid());
+ fclose(f);
+#ifdef __FreeBSD__
+#ifdef DEBUG
+ daemon2_detach(0, 1);
+#else
+ daemon2_detach(0, 0);
+#endif
+#else
+#ifdef DEBUG
+ daemon(0, 1);
+#else
+ daemon(0, 0);
+#endif
+#endif
+
+ for (;;) {
+ unsigned char buf[512];
+ union sockaddr_either from;
+ ssize_t nrecv, nsent;
+ socklen_t fromlen =
+ protocol == '4' ? sizeof(struct sockaddr_in) :
+ sizeof(struct sockaddr_in6);
+ memset(buf, 0, sizeof buf);
+ nrecv = recvfrom(s, buf, sizeof buf, 0, &from.s, &fromlen);
+ if (nrecv < 0)
+ err(1, "recvfrom");
+ if (nrecv < 12) {
+ DPRINTF("Too short %zd\n", nrecv);
+ continue;
+ }
+ if ((buf[2] & 0x80) != 0) {
+ DPRINTF("Not a query 0x%x\n", buf[2]);
+ continue;
+ }
+ if (!(buf[4] == 0 && buf[5] == 1)) {
+ DPRINTF("QCOUNT is not 1 0x%x 0x%x\n", buf[4], buf[5]);
+ continue; /* QDCOUNT is not 1 */
+ }
+
+ for (dp = data; dp->qname_size != 0; dp++) {
+ int qtype, qclass;
+ p = buf + 12; /* Point to QNAME */
+ int n = name_eq(p, (const unsigned char *) dp->qname);
+ if (n == 0) {
+ DPRINTF("no match name %s != %s\n",
+ name2str(p, buf1, sizeof(buf1)),
+ name2str(dp->qname, buf2, sizeof(buf2)));
+ continue; /* Name does not match */
+ }
+ DPRINTF("match name %s\n",
+ name2str(p, buf1, sizeof(buf1)));
+ p += n; /* Skip QNAME */
+ qtype = *p++ << 8;
+ qtype |= *p++;
+ if (qtype != dp->qtype) {
+ DPRINTF("no match name 0x%x != 0x%x\n",
+ qtype, dp->qtype);
+ continue;
+ }
+ DPRINTF("match type 0x%x\n", qtype);
+ qclass = *p++ << 8;
+ qclass |= *p++;
+ if (qclass != 1) { /* IN */
+ DPRINTF("no match class %d != 1\n", qclass);
+ continue;
+ }
+ DPRINTF("match class %d\n", qclass);
+ goto found;
+ }
+ continue;
+ found:
+ buf[2] |= 0x80; /* QR */
+ buf[3] |= 0x80; /* RA */
+ memset(buf + 6, 0, 6); /* Clear ANCOUNT, NSCOUNT, ARCOUNT */
+ buf[7] = 1; /* ANCOUNT */
+ memcpy(p, dp->qname, dp->qname_size);
+ p += dp->qname_size;
+ *p++ = dp->qtype >> 8;
+ *p++ = dp->qtype & 0xFF;
+ *p++ = 0;
+ *p++ = 1; /* IN */
+ memset(p, 0, 4); /* TTL = 0 */
+ p += 4;
+ *p++ = 0; /* RDLENGTH MSB */
+ *p++ = dp->answer_size; /* RDLENGTH LSB */
+ memcpy(p, dp->answer, dp->answer_size);
+ p += dp->answer_size;
+ nsent = sendto(s, buf, p - buf, 0, &from.s, fromlen);
+ DPRINTF("sent %zd\n", nsent);
+ if (nsent != p - buf)
+ warn("sendto");
+ }
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/h_hostent.c b/contrib/netbsd-tests/lib/libc/net/h_hostent.c
new file mode 100644
index 000000000000..4a7292320f3d
--- /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 000000000000..2f315d2b4194
--- /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 000000000000..f37a85c26e5e
--- /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 000000000000..6d7efd80f5e1
--- /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 000000000000..87ccbe8884a0
--- /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 000000000000..bbc8559cd54f
--- /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 000000000000..2a9106072386
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/t_ether_aton.c
@@ -0,0 +1,137 @@
+/* $NetBSD: t_ether_aton.c,v 1.1 2011/11/01 22:36:53 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_ether_aton.c,v 1.1 2011/11/01 22:36:53 pgoyette Exp $");
+
+#include <atf-c.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <err.h>
+#include <string.h>
+#include <errno.h>
+
+#ifndef __NetBSD__
+#ifdef __linux__
+#include <netinet/ether.h>
+#endif
+#include <net/ethernet.h>
+#endif
+
+#ifdef __NetBSD__
+#define ETHER_ADDR_LEN 6
+
+int ether_aton_r(u_char *dest, size_t len, const char *str);
+#endif
+
+static const struct {
+ u_char res[ETHER_ADDR_LEN];
+ const char *str;
+ int error;
+} tests[] = {
+ { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab }, "01:23:45:67:89:ab", 0 },
+#ifdef __NetBSD__
+ { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "0:1:22-3:14:05", 0 },
+ { { 0x00, 0x01, 0x22, 0x03, 0x14, 0x05 }, "000122031405", 0 },
+ { { 0x0a, 0x0B, 0xcc, 0xdD, 0xEE, 0x0f }, "0a0BccdDEE0f", 0 },
+#endif
+#define ZERO { 0, 0, 0, 0, 0, 0 }
+ { ZERO, "0:1:2-3:04:05:06", ENAMETOOLONG },
+ { ZERO, "0:1:2-3:04:", ENOBUFS },
+ { ZERO, "0:1:2-3:04:x7", EINVAL },
+ { ZERO, "1:x-3:04:05:7", EINVAL },
+ { ZERO, NULL, 0 },
+};
+
+ATF_TC(tc_ether_aton);
+ATF_TC_HEAD(tc_ether_aton, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check that ether_aton(3) works");
+}
+
+ATF_TC_BODY(tc_ether_aton, tc)
+{
+#ifdef __NetBSD__
+ u_char dest[ETHER_ADDR_LEN];
+#else
+ struct ether_addr dest;
+#endif
+ size_t t;
+#ifdef __NetBSD__
+ int e, r;
+#else
+ int e;
+ struct ether_addr *r;
+#endif
+ const char *s;
+
+ for (t = 0; tests[t].str; t++) {
+ s = tests[t].str;
+ if ((e = tests[t].error) == 0) {
+#ifdef __NetBSD__
+ if (ether_aton_r(dest, sizeof(dest), s) != e)
+ atf_tc_fail("failed on `%s'", s);
+ if (memcmp(dest, tests[t].res, sizeof(dest)) != 0)
+ atf_tc_fail("unexpected result on `%s'", s);
+#else
+ if (ether_aton_r(s, &dest) == NULL && e == 0)
+ atf_tc_fail("failed on `%s'", s);
+ if (memcmp(&dest, tests[t].res, sizeof(dest)) != 0)
+ atf_tc_fail("unexpected result on `%s'", s);
+#endif
+ } else {
+#ifdef __NetBSD__
+ if ((r = ether_aton_r(dest, sizeof(dest), s)) != e)
+ atf_tc_fail("unexpectedly succeeded on `%s' "
+ "(%d != %d)", s, r, e);
+#else
+ if ((r = ether_aton_r(s, &dest)) != NULL && e != 0)
+ atf_tc_fail("unexpectedly succeeded on `%s' "
+ "(%p != %d)", s, r, e);
+#endif
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, tc_ether_aton);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c b/contrib/netbsd-tests/lib/libc/net/t_getprotoent.c
new file mode 100644
index 000000000000..1c1a0e060445
--- /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 000000000000..b597b6d57c76
--- /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 000000000000..b58436958a9f
--- /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 000000000000..322d426a29bb
--- /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 000000000000..0979eb37dc84
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/net/t_servent.sh
@@ -0,0 +1,111 @@
+# $NetBSD: t_servent.sh,v 1.1 2011/01/12 17:32:27 pgoyette Exp $
+#
+# Copyright (c) 2008 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+atf_test_case servent
+servent_head()
+{
+ atf_set "descr" "Checks {get,set,end}servent(3)"
+}
+servent_body()
+{
+ #
+ # Munge original to:
+ # (1) match output format of the test program
+ # (2) fold all names for the same port/proto together
+ # (3) prune duplicates
+ #
+ tr '\t' ' ' </etc/services | awk '
+ function add(key, name, i, n, ar) {
+ n = split(names[key], ar);
+ for (i=1; i<=n; i++) {
+ if (name == ar[i]) {
+ return;
+ }
+ }
+ delete ar;
+ names[key] = names[key] " " name;
+ }
+
+ {
+ sub("#.*", "", $0);
+ gsub(" *", " ", $0);
+ if (NF==0) {
+ next;
+ }
+ add($2, $1, 0);
+ for (i=3; i<=NF; i++) {
+ add($2, $i, 1);
+ }
+ }
+ END {
+ for (key in names) {
+ portproto = key;
+ sub("/", ", proto=", portproto);
+ portproto = "port=" portproto;
+
+ n = split(names[key], ar);
+ printf "name=%s, %s, aliases=", ar[1], portproto;
+ for (i=2; i<=n; i++) {
+ if (i>2) {
+ printf " ";
+ }
+ printf "%s", ar[i];
+ }
+ printf "\n";
+ delete ar;
+ }
+ }
+ ' | sort >exp
+
+ case "$(uname)" in
+ FreeBSD)
+ # (3) Don't prune duplicates
+ tr '\t' ' ' < /etc/services |
+ sed 's/#.*//;s/ */ /g; /^$/d;s#\([0-9]\)/#\1 #;s/ *$//' |
+ sort |
+ while read l; do
+ set $l
+ name=$1; shift
+ port=$1; shift
+ proto=$1; shift
+ alias="$@"
+ printf "name=%s, port=%s, proto=%s, aliases=%s\n" \
+ $name $port $proto "$alias"
+ done > exp
+ ;;
+ esac
+
+ # run test program
+ "$(atf_get_srcdir)/h_servent" | sed 's/ *$//' | sort >out
+
+ diff -u exp out || atf_fail "Observed output does not match reference output"
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case servent
+}
diff --git a/contrib/netbsd-tests/lib/libc/regex/README b/contrib/netbsd-tests/lib/libc/regex/README
new file mode 100644
index 000000000000..6d9a28cf60ca
--- /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 000000000000..d1454082475c
--- /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 000000000000..e2ee6f6ef705
--- /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 000000000000..4399ca135448
--- /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 000000000000..d34851278f22
--- /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 000000000000..39f3111dab20
--- /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 000000000000..9c068c61bfc8
--- /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 000000000000..c73d8f09eed5
--- /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 000000000000..c24749c7cc18
--- /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 000000000000..ed7f28e6211d
--- /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 000000000000..cc59b06e5f75
--- /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 000000000000..d1e3aa9dadb2
--- /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 000000000000..53a0b20d3c84
--- /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 000000000000..ea3faf9ddf62
--- /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 000000000000..e1140588e71a
--- /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 000000000000..61e0ea4e41c0
--- /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 000000000000..4533d3591bc6
--- /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 000000000000..baf8d0403dc7
--- /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 000000000000..9d206cea7acd
--- /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 000000000000..afd832a51cb4
--- /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 000000000000..ee6ff4cd190c
--- /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 000000000000..da97badde978
--- /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 000000000000..08bc286e5be2
--- /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 000000000000..c396e58ac4d4
--- /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 000000000000..c7bcc06175ea
--- /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 000000000000..92d68bb9c29b
--- /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 000000000000..e09a329afd1b
--- /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 000000000000..2786944eb227
--- /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 000000000000..f1d2b15de633
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/debug.c
@@ -0,0 +1,278 @@
+/* $NetBSD: debug.c,v 1.2 2011/10/10 04:32:41 christos Exp $ */
+
+/*-
+ * Copyright (c) 1993 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <limits.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/types.h>
+#ifdef __FreeBSD__
+#include <wchar.h>
+#include <wctype.h>
+#endif
+
+/* Don't sort these! */
+#include "utils.h"
+#include "regex2.h"
+
+#include "test_regex.h"
+
+static void s_print(struct re_guts *, FILE *);
+static char *regchar(int);
+
+/*
+ * regprint - print a regexp for debugging
+ */
+void
+regprint(regex_t *r, FILE *d)
+{
+#ifdef __NetBSD__
+ struct re_guts *g = r->re_g;
+ int c;
+ int last;
+ int nincat[NC];
+
+ fprintf(d, "%ld states, %zu categories", (long)g->nstates,
+ g->ncategories);
+ fprintf(d, ", first %ld last %ld", (long)g->firststate,
+ (long)g->laststate);
+ if (g->iflags&USEBOL)
+ fprintf(d, ", USEBOL");
+ if (g->iflags&USEEOL)
+ fprintf(d, ", USEEOL");
+ if (g->iflags&BAD)
+ fprintf(d, ", BAD");
+ if (g->nsub > 0)
+ fprintf(d, ", nsub=%ld", (long)g->nsub);
+ if (g->must != NULL)
+ fprintf(d, ", must(%ld) `%*s'", (long)g->mlen, (int)g->mlen,
+ g->must);
+ if (g->backrefs)
+ fprintf(d, ", backrefs");
+ if (g->nplus > 0)
+ fprintf(d, ", nplus %ld", (long)g->nplus);
+ fprintf(d, "\n");
+ s_print(g, d);
+ for (size_t i = 0; i < g->ncategories; i++) {
+ nincat[i] = 0;
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (g->categories[c] == i)
+ nincat[i]++;
+ }
+ fprintf(d, "cc0#%d", nincat[0]);
+ for (size_t i = 1; i < g->ncategories; i++)
+ if (nincat[i] == 1) {
+ for (c = CHAR_MIN; c <= CHAR_MAX; c++)
+ if (g->categories[c] == i)
+ break;
+ fprintf(d, ", %zu=%s", i, regchar(c));
+ }
+ fprintf(d, "\n");
+ for (size_t i = 1; i < g->ncategories; i++)
+ if (nincat[i] != 1) {
+ fprintf(d, "cc%zu\t", i);
+ last = -1;
+ for (c = CHAR_MIN; c <= CHAR_MAX+1; c++) /* +1 does flush */
+ if (c <= CHAR_MAX && g->categories[c] == i) {
+ if (last < 0) {
+ fprintf(d, "%s", regchar(c));
+ last = c;
+ }
+ } else {
+ if (last >= 0) {
+ if (last != c-1)
+ fprintf(d, "-%s",
+ regchar(c-1));
+ last = -1;
+ }
+ }
+ fprintf(d, "\n");
+ }
+#endif
+}
+
+/*
+ * s_print - print the strip for debugging
+ */
+static void
+s_print(struct re_guts *g, FILE *d)
+{
+ sop *s;
+ cset *cs;
+ int done = 0;
+ sop opnd;
+ int col = 0;
+ ssize_t last;
+ sopno offset = 2;
+# define GAP() { if (offset % 5 == 0) { \
+ if (col > 40) { \
+ fprintf(d, "\n\t"); \
+ col = 0; \
+ } else { \
+ fprintf(d, " "); \
+ col++; \
+ } \
+ } else \
+ col++; \
+ offset++; \
+ }
+
+ if (OP(g->strip[0]) != OEND)
+ fprintf(d, "missing initial OEND!\n");
+ for (s = &g->strip[1]; !done; s++) {
+ opnd = OPND(*s);
+ switch (OP(*s)) {
+ case OEND:
+ fprintf(d, "\n");
+ done = 1;
+ break;
+ case OCHAR:
+ if (strchr("\\|()^$.[+*?{}!<> ", (char)opnd) != NULL)
+ fprintf(d, "\\%c", (char)opnd);
+ else
+ fprintf(d, "%s", regchar((char)opnd));
+ break;
+ case OBOL:
+ fprintf(d, "^");
+ break;
+ case OEOL:
+ fprintf(d, "$");
+ break;
+ case OBOW:
+ fprintf(d, "\\{");
+ break;
+ case OEOW:
+ fprintf(d, "\\}");
+ break;
+ case OANY:
+ fprintf(d, ".");
+ break;
+ case OANYOF:
+ fprintf(d, "[(%ld)", (long)opnd);
+#ifdef __NetBSD__
+ cs = &g->sets[opnd];
+ last = -1;
+ for (size_t i = 0; i < g->csetsize+1; i++) /* +1 flushes */
+ if (CHIN(cs, i) && i < g->csetsize) {
+ if (last < 0) {
+ fprintf(d, "%s", regchar(i));
+ last = i;
+ }
+ } else {
+ if (last >= 0) {
+ if (last != (ssize_t)i - 1)
+ fprintf(d, "-%s",
+ regchar(i - 1));
+ last = -1;
+ }
+ }
+#endif
+ fprintf(d, "]");
+ break;
+ case OBACK_:
+ fprintf(d, "(\\<%ld>", (long)opnd);
+ break;
+ case O_BACK:
+ fprintf(d, "<%ld>\\)", (long)opnd);
+ break;
+ case OPLUS_:
+ fprintf(d, "(+");
+ if (OP(*(s+opnd)) != O_PLUS)
+ fprintf(d, "<%ld>", (long)opnd);
+ break;
+ case O_PLUS:
+ if (OP(*(s-opnd)) != OPLUS_)
+ fprintf(d, "<%ld>", (long)opnd);
+ fprintf(d, "+)");
+ break;
+ case OQUEST_:
+ fprintf(d, "(?");
+ if (OP(*(s+opnd)) != O_QUEST)
+ fprintf(d, "<%ld>", (long)opnd);
+ break;
+ case O_QUEST:
+ if (OP(*(s-opnd)) != OQUEST_)
+ fprintf(d, "<%ld>", (long)opnd);
+ fprintf(d, "?)");
+ break;
+ case OLPAREN:
+ fprintf(d, "((<%ld>", (long)opnd);
+ break;
+ case ORPAREN:
+ fprintf(d, "<%ld>))", (long)opnd);
+ break;
+ case OCH_:
+ fprintf(d, "<");
+ if (OP(*(s+opnd)) != OOR2)
+ fprintf(d, "<%ld>", (long)opnd);
+ break;
+ case OOR1:
+ if (OP(*(s-opnd)) != OOR1 && OP(*(s-opnd)) != OCH_)
+ fprintf(d, "<%ld>", (long)opnd);
+ fprintf(d, "|");
+ break;
+ case OOR2:
+ fprintf(d, "|");
+ if (OP(*(s+opnd)) != OOR2 && OP(*(s+opnd)) != O_CH)
+ fprintf(d, "<%ld>", (long)opnd);
+ break;
+ case O_CH:
+ if (OP(*(s-opnd)) != OOR1)
+ fprintf(d, "<%ld>", (long)opnd);
+ fprintf(d, ">");
+ break;
+ default:
+#ifdef __FreeBSD__
+ fprintf(d, "!%ld(%ld)!", OP(*s), opnd);
+#else
+ fprintf(d, "!%d(%d)!", OP(*s), opnd);
+#endif
+ break;
+ }
+ if (!done)
+ GAP();
+ }
+}
+
+/*
+ * regchar - make a character printable
+ */
+static char * /* -> representation */
+regchar(int ch)
+{
+ static char buf[10];
+
+ if (isprint(ch) || ch == ' ')
+ sprintf(buf, "%c", ch);
+ else
+ sprintf(buf, "\\%o", ch);
+ return(buf);
+}
diff --git a/contrib/netbsd-tests/lib/libc/regex/main.c b/contrib/netbsd-tests/lib/libc/regex/main.c
new file mode 100644
index 000000000000..eac4e2d9b51e
--- /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 000000000000..2a26b50693bd
--- /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 000000000000..0670e514e7e1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/t_exhaust.c
@@ -0,0 +1,224 @@
+/* $NetBSD: t_exhaust.c,v 1.7 2011/11/16 18:37:31 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_exhaust.c,v 1.7 2011/11/16 18:37:31 christos Exp $");
+
+#include <stdio.h>
+#include <regex.h>
+#include <string.h>
+#include <stdlib.h>
+#include <err.h>
+#include <atf-c.h>
+#ifdef __FreeBSD__
+#include <sys/resource.h>
+#endif
+
+#ifndef REGEX_MAXSIZE
+#define REGEX_MAXSIZE 9999
+#endif
+
+static char *
+mkstr(const char *str, size_t len)
+{
+ size_t slen = strlen(str);
+ char *p = malloc(slen * len + 1);
+ ATF_REQUIRE(p != NULL);
+ for (size_t i = 0; i < len; i++)
+ strcpy(&p[i * slen], str);
+ return p;
+}
+
+static char *
+concat(const char *d, const char *s)
+{
+ size_t dlen = strlen(d);
+ size_t slen = strlen(s);
+ char *p = malloc(dlen + slen + 1);
+
+ ATF_REQUIRE(p != NULL);
+ strcpy(p, d);
+ strcpy(p + dlen, s);
+ return p;
+}
+
+static char *
+p0(size_t len)
+{
+ char *d, *s1, *s2;
+ s1 = mkstr("\\(", len);
+ s2 = concat(s1, ")");
+ free(s1);
+ d = concat("(", s2);
+ free(s2);
+ return d;
+}
+
+static char *
+p1(size_t len)
+{
+ char *d, *s1, *s2, *s3;
+ s1 = mkstr("\\(", 60);
+ s2 = mkstr("(.*)", len);
+ s3 = concat(s1, s2);
+ free(s2);
+ free(s1);
+ s1 = concat(s3, ")");
+ free(s3);
+ d = concat("(", s1);
+ free(s1);
+ return d;
+}
+
+static char *
+ps(const char *m, const char *s, size_t len)
+{
+ char *d, *s1, *s2, *s3;
+ s1 = mkstr(m, len);
+ s2 = mkstr(s, len);
+ s3 = concat(s1, s2);
+ free(s2);
+ free(s1);
+ d = concat("(.?)", s3);
+ free(s3);
+ return d;
+}
+
+static char *
+p2(size_t len)
+{
+ return ps("((.*){0,255}", ")", len);
+}
+
+static char *
+p3(size_t len)
+{
+ return ps("(.\\{0,}", ")", len);
+}
+
+static char *
+p4(size_t len)
+{
+ return ps("((.*){1,255}", ")", len);
+}
+
+static char *
+p5(size_t len)
+{
+ return ps("(", "){1,100}", len);
+}
+
+static char *
+p6(size_t len)
+{
+ char *d, *s1, *s2;
+ s1 = mkstr("(?:(.*)|", len);
+ s2 = concat(s1, "(.*)");
+ free(s1);
+ s1 = mkstr(")", len);
+ d = concat(s2, s1);
+ free(s1);
+ free(s2);
+ return d;
+}
+
+static const struct {
+ char *(*pattern)(size_t);
+ int type;
+} tests[] = {
+ { p0, REG_EXTENDED },
+ { p1, REG_EXTENDED },
+ { p2, REG_EXTENDED },
+ { p3, REG_EXTENDED },
+ { p4, REG_EXTENDED },
+ { p5, REG_EXTENDED },
+ { p6, REG_BASIC },
+};
+
+ATF_TC(regcomp_too_big);
+
+ATF_TC_HEAD(regcomp_too_big, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Check that large patterns don't"
+ " crash, but return a proper error code");
+ // libtre needs it.
+ atf_tc_set_md_var(tc, "timeout", "600");
+#ifdef __FreeBSD__
+ atf_tc_set_md_var(tc, "require.memory", "64M");
+#else
+ atf_tc_set_md_var(tc, "require.memory", "120M");
+#endif
+}
+
+ATF_TC_BODY(regcomp_too_big, tc)
+{
+ regex_t re;
+#ifdef __FreeBSD__
+ struct rlimit limit;
+#endif
+ int e;
+
+#ifdef __FreeBSD__
+ limit.rlim_cur = limit.rlim_max = 64 * 1024 * 1024;
+ ATF_REQUIRE(setrlimit(RLIMIT_VMEM, &limit) != -1);
+#endif
+ for (size_t i = 0; i < __arraycount(tests); i++) {
+ char *d = (*tests[i].pattern)(REGEX_MAXSIZE);
+ e = regcomp(&re, d, tests[i].type);
+ if (e) {
+ char ebuf[1024];
+ (void)regerror(e, &re, ebuf, sizeof(ebuf));
+ ATF_REQUIRE_MSG(e == REG_ESPACE,
+ "regcomp returned %d (%s) for pattern %zu [%s]", e, ebuf,
+ i, d);
+ free(d);
+ continue;
+ }
+ free(d);
+ (void)regexec(&re, "aaaaaaaaaaa", 0, NULL, 0);
+ regfree(&re);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, regcomp_too_big);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/regex/t_regex.sh b/contrib/netbsd-tests/lib/libc/regex/t_regex.sh
new file mode 100755
index 000000000000..bef3ac926959
--- /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 000000000000..0ca44b47577e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/regex/t_regex_att.c
@@ -0,0 +1,639 @@
+/* $NetBSD: t_regex_att.c,v 1.1 2012/08/24 20:24:40 jmmv Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_regex_att.c,v 1.1 2012/08/24 20:24:40 jmmv Exp $");
+
+#include <sys/param.h>
+
+#include <stdio.h>
+#include <regex.h>
+#include <string.h>
+#include <stdlib.h>
+#include <vis.h>
+#include <ctype.h>
+#include <atf-c.h>
+#ifdef __FreeBSD__
+#include <libutil.h>
+#endif
+
+static const char sep[] = "\r\n\t";
+static const char delim[3] = "\\\\\0";
+
+
+static void
+fail(const char *pattern, const char *input, size_t lineno) {
+ fprintf(stderr,
+ "skipping failed test at line %zu (pattern=%s, input=%s)\n",
+ lineno, pattern, input);
+}
+
+static int
+bug(const char *pattern, const char *input, size_t lineno) {
+ static const struct {
+ const char *p;
+ const char *i;
+ } b[] = {
+#if defined(REGEX_SPENCER)
+ /*
+ * The default libc implementation by Henry Spencer
+ */
+ { "a[-]?c", "ac" }, // basic.dat
+ { "(a*)*", "a" }, // categorization.dat
+ { "(aba|a*b)*", "ababa" }, // categorization.dat
+ { "\\(a\\(b\\)*\\)*\\2", "abab" }, // categorization.dat
+ { "(a*)*", "aaaaaa" }, // nullsubexpression.dat
+ { "(a*)*", "aaaaaax" }, // nullsubexpression.dat
+ { "(a*)+", "a" }, // nullsubexpression.dat
+ { "(a*)+", "aaaaaa" }, // nullsubexpression.dat
+ { "(a*)+", "aaaaaax" }, // nullsubexpression.dat
+ { "([a]*)*", "a" }, // nullsubexpression.dat
+ { "([a]*)*", "aaaaaa" }, // nullsubexpression.dat
+ { "([a]*)*", "aaaaaax" }, // nullsubexpression.dat
+ { "([a]*)+", "a" }, // nullsubexpression.dat
+ { "([a]*)+", "aaaaaa" }, // nullsubexpression.dat
+ { "([a]*)+", "aaaaaax" }, // nullsubexpression.dat
+ { "([^b]*)*", "a" }, // nullsubexpression.dat
+ { "([^b]*)*", "aaaaaa" }, // nullsubexpression.dat
+ { "([^b]*)*", "aaaaaab" }, // nullsubexpression.dat
+ { "([ab]*)*", "a" }, // nullsubexpression.dat
+ { "([ab]*)*", "aaaaaa" }, // nullsubexpression.dat
+ { "([ab]*)*", "ababab" }, // nullsubexpression.dat
+ { "([ab]*)*", "bababa" }, // nullsubexpression.dat
+ { "([ab]*)*", "b" }, // nullsubexpression.dat
+ { "([ab]*)*", "bbbbbb" }, // nullsubexpression.dat
+ { "([ab]*)*", "aaaabcde" }, // nullsubexpression.dat
+ { "([^a]*)*", "b" }, // nullsubexpression.dat
+ { "([^a]*)*", "bbbbbb" }, // nullsubexpression.dat
+ { "([^ab]*)*", "ccccxx" }, // nullsubexpression.dat
+ { "\\(a*\\)*\\(x\\)", "ax" }, // nullsubexpression.dat
+ { "\\(a*\\)*\\(x\\)", "axa" }, // nullsubexpression.dat
+ { "\\(a*\\)*\\(x\\)\\(\\1\\)", "x" }, // nullsubexpression.dat
+/* crash! */ { "\\(a*\\)*\\(x\\)\\(\\1\\)", "ax" }, // nullsubexpression.dat
+/* crash! */ { "\\(a*\\)*\\(x\\)\\(\\1\\)\\(x\\)", "axxa" }, // ""
+ { "(a*)*(x)", "ax" }, // nullsubexpression.dat
+ { "(a*)*(x)", "axa" }, // nullsubexpression.dat
+ { "(a*)+(x)", "ax" }, // nullsubexpression.dat
+ { "(a*)+(x)", "axa" }, // nullsubexpression.dat
+ { "((a|ab)(c|bcd))(d*)", "abcd" }, // forcedassoc.dat
+ { "((a|ab)(bcd|c))(d*)", "abcd" }, // forcedassoc.dat
+ { "((ab|a)(c|bcd))(d*)", "abcd" }, // forcedassoc.dat
+ { "((ab|a)(bcd|c))(d*)", "abcd" }, // forcedassoc.dat
+ { "((a*)(b|abc))(c*)", "abc" }, // forcedassoc.dat
+ { "((a*)(abc|b))(c*)", "abc" }, // forcedassoc.dat
+ { "((..)|(.)){2}", "aaa" }, // repetition.dat
+ { "((..)|(.)){3}", "aaa" }, // repetition.dat
+ { "((..)|(.)){3}", "aaaa" }, // repetition.dat
+ { "((..)|(.)){3}", "aaaaa" }, // repetition.dat
+ { "X(.?){0,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){1,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){2,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){3,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){4,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){5,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){6,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){7,}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){0,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){1,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){2,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){3,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){4,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){5,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){6,8}Y", "X1234567Y" }, // repetition.dat
+ { "X(.?){7,8}Y", "X1234567Y" }, // repetition.dat
+ { "(a|ab|c|bcd){0,}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){1,}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){2,}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){3,}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){1,10}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){2,10}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd){3,10}(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd)*(d*)", "ababcd" }, // repetition.dat
+ { "(a|ab|c|bcd)+(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){0,}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){1,}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){2,}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){3,}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){1,10}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){2,10}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd){3,10}(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd)*(d*)", "ababcd" }, // repetition.dat
+ { "(ab|a|c|bcd)+(d*)", "ababcd" }, // repetition.dat
+#elif defined(REGEX_TRE)
+ { "a[-]?c", "ac" }, // basic.dat
+ { "a\\(b\\)*\\1", "a" }, // categorization.dat
+ { "a\\(b\\)*\\1", "abab" }, // categorization.dat
+ { "\\(a\\(b\\)*\\)*\\2", "abab" }, // categorization.dat
+ { "\\(a*\\)*\\(x\\)\\(\\1\\)", "ax" }, // categorization.dat
+ { "\\(a*\\)*\\(x\\)\\(\\1\\)\\(x\\)", "axxa" }, // ""
+ { "((..)|(.))*", "aa" }, // repetition.dat
+ { "((..)|(.))*", "aaa" }, // repetition.dat
+ { "((..)|(.))*", "aaaaa" }, // repetition.dat
+ { "X(.?){7,}Y", "X1234567Y" }, // repetition.dat
+#else
+ { "", "" }
+#endif
+ };
+
+ for (size_t i = 0; i < __arraycount(b); i++) {
+ if (strcmp(pattern, b[i].p) == 0 &&
+ strcmp(input, b[i].i) == 0) {
+ fail(pattern, input, lineno);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+#ifdef REGEX_SPENCER
+#define HAVE_BRACES 1
+#define HAVE_MINIMAL 0
+#endif
+#ifndef HAVE_BRACES
+#define HAVE_BRACES 1
+#endif
+#ifndef HAVE_MINIMAL
+#define HAVE_MINIMAL 1
+#endif
+
+static int
+optional(const char *s)
+{
+ static const struct{
+ const char *n;
+ int v;
+ } nv[]= {
+ { "[[<element>]] not supported", HAVE_BRACES },
+ { "no *? +? mimimal match ops", HAVE_MINIMAL },
+ };
+
+ for (size_t i = 0; i < __arraycount(nv); i++)
+ if (strcmp(nv[i].n, s) == 0) {
+ if (nv[i].v)
+ return 0;
+ fprintf(stderr, "skipping unsupported [%s] tests\n", s);
+ return 1;
+ }
+
+ ATF_REQUIRE_MSG(0, "Unknown feature: %s", s);
+ return 0;
+}
+
+static int
+unsupported(const char *s)
+{
+ static const char *we[] = {
+#if defined(REGEX_SPENCER)
+ "ASSOCIATIVITY=left", // have right associativity
+ "SUBEXPRESSION=precedence", // have grouping subexpression
+ "REPEAT_LONGEST=last", // have first repeat longest
+ "BUG=alternation-order", // don't have it
+ "BUG=first-match", // don't have it
+ "BUG=nomatch-match", // don't have it
+ "BUG=repeat-any", // don't have it
+ "BUG=range-null", // don't have it
+ "BUG=repeat-null-unknown", // don't have it
+ "BUG=repeat-null", // don't have it
+ "BUG=repeat-artifact", // don't have it
+ "BUG=subexpression-first", // don't have it
+#elif defined(REGEX_TRE)
+ "ASSOCIATIVITY=right", // have left associativity
+ "SUBEXPRESSION=grouping", // have precedence subexpression
+ "REPEAT_LONGEST=first", // have last repeat longest
+ "LENGTH=first", // have last length
+ "BUG=alternation-order", // don't have it
+ "BUG=first-match", // don't have it
+ "BUG=range-null", // don't have it
+ "BUG=repeat-null", // don't have it
+ "BUG=repeat-artifact", // don't have it
+ "BUG=subexpression-first", // don't have it
+ "BUG=repeat-short", // don't have it
+#endif
+ };
+
+ if (s == NULL)
+ return 0;
+
+ while (*s == '#' || isspace((unsigned char)*s))
+ s++;
+
+ for (size_t i = 0; i < __arraycount(we); i++)
+ if (strcmp(we[i], s) == 0)
+ return 1;
+ return 0;
+}
+
+static void
+geterror(const char *s, int *comp, int *exec)
+{
+ static const struct {
+ const char *n;
+ int v;
+ int ce;
+ } nv[] = {
+#define COMP 1
+#define EXEC 2
+ { "OK", 0, COMP|EXEC },
+#define _DO(a, b) { # a, REG_ ## a, b },
+ _DO(NOMATCH, EXEC)
+ _DO(BADPAT, COMP)
+ _DO(ECOLLATE, COMP)
+ _DO(ECTYPE, COMP)
+ _DO(EESCAPE, COMP)
+ _DO(ESUBREG, COMP)
+ _DO(EBRACK, COMP)
+ _DO(EPAREN, COMP)
+ _DO(EBRACE, COMP)
+ _DO(BADBR, COMP)
+ _DO(ERANGE, COMP)
+ _DO(ESPACE, EXEC)
+ _DO(BADRPT, COMP)
+ _DO(EMPTY, COMP)
+ _DO(ASSERT, COMP)
+ _DO(INVARG, COMP)
+ _DO(ENOSYS, COMP)
+#undef _DO
+ };
+ *comp = 0;
+ *exec = 0;
+ for (size_t i = 0; i < __arraycount(nv); i++)
+ if (strcmp(s, nv[i].n) == 0) {
+ if (nv[i].ce & COMP)
+ *comp = nv[i].v;
+ if (nv[i].ce & EXEC)
+ *exec = nv[i].v;
+ return;
+ }
+ ATF_REQUIRE_MSG(0, "Unknown error %s", s);
+ return;
+}
+
+static int
+getflags(char *s)
+{
+ int flags = 0;
+
+ for (;; s++)
+ switch (*s) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ *s = '\0';
+ break;
+ case '\0':
+ return flags;
+ case 'B':
+ case 'E':
+ case 'F':
+ case 'L':
+ break;
+ case 'i':
+ flags |= REG_ICASE;
+ *s = '\0';
+ break;
+ case '$':
+ *s = '\0';
+ break;
+ case 'n':
+ *s = '\0';
+ break;
+ default:
+ ATF_REQUIRE_MSG(0, "Unknown char %c", *s);
+ break;
+ }
+}
+
+static size_t
+getmatches(const char *s)
+{
+ size_t i;
+ char *q;
+ for (i = 0; (q = strchr(s, '(')) != NULL; i++, s = q + 1)
+ continue;
+ ATF_REQUIRE_MSG(i != 0, "No parentheses found");
+ return i;
+}
+
+static void
+checkcomment(const char *s, size_t lineno)
+{
+ if (s && strstr(s, "BUG") != NULL)
+ fprintf(stderr, "Expected %s at line %zu\n", s, lineno);
+}
+
+static void
+checkmatches(const char *matches, size_t nm, const regmatch_t *pm,
+ size_t lineno)
+{
+ if (nm == 0)
+ return;
+
+ char *res;
+ size_t len = strlen(matches) + 1, off = 0;
+
+ ATF_REQUIRE((res = strdup(matches)) != NULL);
+ for (size_t i = 0; i < nm; i++) {
+ int l;
+ if (pm[i].rm_so == -1 && pm[i].rm_eo == -1)
+ l = snprintf(res + off, len - off, "(?,?)");
+ else
+ l = snprintf(res + off, len - off, "(%lld,%lld)",
+ (long long)pm[i].rm_so, (long long)pm[i].rm_eo);
+ ATF_REQUIRE_MSG((size_t) l < len - off, "String too long %s"
+ " cur=%d, max=%zu", res, l, len - off);
+ off += l;
+ }
+#ifdef __FreeBSD__
+ ATF_CHECK_STREQ_MSG(res, matches, " at line %zu", lineno);
+#else
+ ATF_REQUIRE_STREQ_MSG(res, matches, " at line %zu", lineno);
+#endif
+ free(res);
+}
+
+static void
+att_test(const struct atf_tc *tc, const char *data_name)
+{
+ regex_t re;
+ char *line, *lastpattern = NULL, data_path[MAXPATHLEN];
+ size_t len, lineno = 0;
+ int skipping = 0;
+ FILE *input_file;
+
+ snprintf(data_path, sizeof(data_path), "%s/data/%s.dat",
+ atf_tc_get_config_var(tc, "srcdir"), data_name);
+
+ input_file = fopen(data_path, "r");
+ if (input_file == NULL)
+ atf_tc_fail("Failed to open input file %s", data_path);
+
+ for (; (line = fparseln(input_file, &len, &lineno, delim, 0))
+ != NULL; free(line)) {
+ char *name, *pattern, *input, *matches, *comment;
+ regmatch_t *pm;
+ size_t nm;
+#ifdef DEBUG
+ fprintf(stderr, "[%s]\n", line);
+#endif
+ if ((name = strtok(line, sep)) == NULL)
+ continue;
+
+ /*
+ * We check these early so that we skip the lines quickly
+ * in order to do more strict testing on the other arguments
+ * The same characters are also tested in the switch below
+ */
+ if (*name == '}') {
+ skipping = 0;
+ continue;
+ }
+ if (skipping)
+ continue;
+ if (*name == ';' || *name == '#' || strcmp(name, "NOTE") == 0)
+ continue;
+ if (*name == ':') {
+ /* Skip ":HA#???:" prefix */
+ while (*++name && *name != ':')
+ continue;
+ if (*name)
+ name++;
+ }
+
+ ATF_REQUIRE_MSG((pattern = strtok(NULL, sep)) != NULL,
+ "Missing pattern at line %zu", lineno);
+ ATF_REQUIRE_MSG((input = strtok(NULL, sep)) != NULL,
+ "Missing input at line %zu", lineno);
+
+ if (strchr(name, '$')) {
+ ATF_REQUIRE(strunvis(pattern, pattern) != -1);
+ ATF_REQUIRE(strunvis(input, input) != -1);
+ }
+
+
+ if (strcmp(input, "NULL") == 0)
+ *input = '\0';
+
+ if (strcmp(pattern, "SAME") == 0) {
+ ATF_REQUIRE(lastpattern != NULL);
+ pattern = lastpattern;
+ } else {
+ free(lastpattern);
+ ATF_REQUIRE((lastpattern = strdup(pattern)) != NULL);
+ }
+
+ ATF_REQUIRE_MSG((matches = strtok(NULL, sep)) != NULL,
+ "Missing matches at line %zu", lineno);
+
+ comment = strtok(NULL, sep);
+ switch (*name) {
+ case '{': /* Begin optional implementation */
+ if (optional(comment)) {
+ skipping++;
+ continue;
+ }
+ name++; /* We have it, so ignore */
+ break;
+ case '}': /* End optional implementation */
+ skipping = 0;
+ continue;
+ case '?': /* Optional */
+ case '|': /* Alternative */
+ if (unsupported(comment))
+ continue;
+ name++; /* We have it, so ignore */
+ break;
+ case '#': /* Comment */
+ case ';': /* Skip */
+ continue;
+ default:
+ break;
+ }
+
+ /* XXX: Our bug */
+ if (bug(pattern, input, lineno))
+ continue;
+
+ int comp, exec;
+ if (*matches != '(') {
+ geterror(matches, &comp, &exec);
+ pm = NULL;
+ nm = 0;
+ } else {
+ comp = exec = 0;
+ nm = getmatches(matches);
+ ATF_REQUIRE((pm = calloc(nm, sizeof(*pm))) != NULL);
+ }
+
+
+
+ int iflags = getflags(name);
+ for (; *name; name++) {
+ int flags;
+ switch (*name) {
+ case 'B':
+ flags = REG_BASIC;
+ break;
+ case 'E':
+ flags = REG_EXTENDED;
+ break;
+ case 'L':
+ flags = REG_NOSPEC;
+ break;
+ default:
+ ATF_REQUIRE_MSG(0, "Bad name %c", *name);
+ continue;
+ }
+ int c = regcomp(&re, pattern, flags | iflags);
+ ATF_REQUIRE_MSG(c == comp,
+ "regcomp returned %d for pattern %s at line %zu",
+ c, pattern, lineno);
+ if (c)
+ continue;
+ int e = regexec(&re, input, nm, pm, 0);
+ ATF_REQUIRE_MSG(e == exec, "Expected error %d,"
+ " got %d at line %zu", exec, e, lineno);
+ checkmatches(matches, nm, pm, lineno);
+ checkcomment(comment, lineno);
+ regfree(&re);
+ }
+ free(pm);
+ }
+
+ fclose(input_file);
+}
+
+ATF_TC(basic);
+ATF_TC_HEAD(basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests basic functionality");
+}
+ATF_TC_BODY(basic, tc)
+{
+ att_test(tc, "basic");
+}
+
+ATF_TC(categorization);
+ATF_TC_HEAD(categorization, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests implementation categorization");
+}
+ATF_TC_BODY(categorization, tc)
+{
+ att_test(tc, "categorization");
+}
+
+ATF_TC(nullsubexpr);
+ATF_TC_HEAD(nullsubexpr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests (...)*");
+}
+ATF_TC_BODY(nullsubexpr, tc)
+{
+ att_test(tc, "nullsubexpr");
+}
+
+ATF_TC(leftassoc);
+ATF_TC_HEAD(leftassoc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests left-associative "
+ "implementations");
+}
+ATF_TC_BODY(leftassoc, tc)
+{
+#if SKIP_LEFTASSOC
+ /* jmmv: I converted the original shell-based tests to C and they
+ * disabled this test in a very unconventional way without giving
+ * any explation. Mark as broken here, but I don't know why. */
+ atf_tc_expect_fail("Reason for breakage unknown");
+#endif
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("The expected and matched groups are mismatched on FreeBSD");
+#endif
+ att_test(tc, "leftassoc");
+}
+
+ATF_TC(rightassoc);
+ATF_TC_HEAD(rightassoc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests right-associative "
+ "implementations");
+}
+ATF_TC_BODY(rightassoc, tc)
+{
+#if SKIP_RIGHTASSOC
+ /* jmmv: I converted the original shell-based tests to C and they
+ * disabled this test in a very unconventional way without giving
+ * any explation. Mark as broken here, but I don't know why. */
+ atf_tc_expect_fail("Reason for breakage unknown");
+#endif
+ att_test(tc, "rightassoc");
+}
+
+ATF_TC(forcedassoc);
+ATF_TC_HEAD(forcedassoc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests subexpression grouping to "
+ "force association");
+}
+ATF_TC_BODY(forcedassoc, tc)
+{
+ att_test(tc, "forcedassoc");
+}
+
+ATF_TC(repetition);
+ATF_TC_HEAD(repetition, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Tests implicit vs. explicit "
+ "repetition");
+}
+ATF_TC_BODY(repetition, tc)
+{
+ att_test(tc, "repetition");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, basic);
+ ATF_TP_ADD_TC(tp, categorization);
+ ATF_TP_ADD_TC(tp, nullsubexpr);
+ ATF_TP_ADD_TC(tp, leftassoc);
+ ATF_TP_ADD_TC(tp, rightassoc);
+ ATF_TP_ADD_TC(tp, forcedassoc);
+ ATF_TP_ADD_TC(tp, repetition);
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/regex/test_regex.h b/contrib/netbsd-tests/lib/libc/regex/test_regex.h
new file mode 100644
index 000000000000..1d9f59da8ab7
--- /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 000000000000..cbddfcc90ca5
--- /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 000000000000..67bc8c7a602e
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/rpc/t_rpc.c
@@ -0,0 +1,161 @@
+/* $NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_rpc.c,v 1.3 2013/02/28 15:56:53 christos Exp $");
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <rpc/rpc.h>
+#include <stdlib.h>
+#include <err.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <unistd.h>
+
+
+#ifndef TEST
+#include <atf-c.h>
+
+#define ERRX(ev, msg, ...) ATF_REQUIRE_MSG(0, msg, __VA_ARGS__)
+
+#define SKIPX(ev, msg, ...) do { \
+ atf_tc_skip(msg, __VA_ARGS__); \
+ return; \
+} while(/*CONSTCOND*/0)
+
+#else
+#define ERRX(ev, msg, ...) errx(ev, msg, __VA_ARGS__)
+#define SKIPX(ev, msg, ...) errx(ev, msg, __VA_ARGS__)
+#endif
+
+
+#define RPCBPROC_NULL 0
+
+static int
+reply(caddr_t replyp, struct netbuf * raddrp, struct netconfig * nconf)
+{
+ char host[NI_MAXHOST];
+ struct sockaddr *sock = raddrp->buf;
+ int error;
+
+
+ error = getnameinfo(sock, sock->sa_len, host, sizeof(host), NULL, 0, 0);
+ if (error)
+ warnx("Cannot resolve address (%s)", gai_strerror(error));
+ else
+ printf("response from: %s\n", host);
+ return 0;
+}
+
+#ifdef __FreeBSD__
+#define __rpc_control rpc_control
+#endif
+
+extern bool __rpc_control(int, void *);
+
+static void
+onehost(const char *host, const char *transp)
+{
+ CLIENT *clnt;
+ struct netbuf addr;
+ struct timeval tv;
+
+ /*
+ * Magic!
+ */
+ tv.tv_sec = 0;
+ tv.tv_usec = 500000;
+#define CLCR_SET_RPCB_TIMEOUT 2
+ __rpc_control(CLCR_SET_RPCB_TIMEOUT, &tv);
+
+ if ((clnt = clnt_create(host, RPCBPROG, RPCBVERS, transp)) == NULL)
+ SKIPX(EXIT_FAILURE, "clnt_create (%s)", clnt_spcreateerror(""));
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ if (clnt_call(clnt, RPCBPROC_NULL, xdr_void, NULL, xdr_void, NULL, tv)
+ != RPC_SUCCESS)
+ ERRX(EXIT_FAILURE, "clnt_call (%s)", clnt_sperror(clnt, ""));
+ clnt_control(clnt, CLGET_SVC_ADDR, (char *) &addr);
+ reply(NULL, &addr, NULL);
+}
+
+#ifdef TEST
+static void
+allhosts(void)
+{
+ enum clnt_stat clnt_stat;
+
+ clnt_stat = rpc_broadcast(RPCBPROG, RPCBVERS, RPCBPROC_NULL,
+ (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void,
+ NULL, (resultproc_t)reply, transp);
+ if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT)
+ ERRX(EXIT_FAILURE, "%s", clnt_sperrno(clnt_stat));
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+ const char *transp = "udp";
+
+
+ while ((ch = getopt(argc, argv, "ut")) != -1)
+ switch (ch) {
+ case 't':
+ transp = "tcp";
+ break;
+ case 'u':
+ transp = "udp";
+ break;
+ default:
+ fprintf(stderr, "Usage: %s -[t|u] [<hostname>...]\n",
+ getprogname());
+ return EXIT_FAILURE;
+ }
+
+ if (argc == optind)
+ allhosts();
+ else
+ for (; optind < argc; optind++)
+ onehost(argv[optind], transp);
+
+ return EXIT_SUCCESS;
+}
+
+#else
+
+ATF_TC(get_svc_addr_tcp);
+ATF_TC_HEAD(get_svc_addr_tcp, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for tcp");
+
+}
+
+ATF_TC_BODY(get_svc_addr_tcp, tc)
+{
+ onehost("localhost", "tcp");
+
+}
+
+ATF_TC(get_svc_addr_udp);
+ATF_TC_HEAD(get_svc_addr_udp, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks CLGET_SVC_ADDR for udp");
+}
+
+ATF_TC_BODY(get_svc_addr_udp, tc)
+{
+ onehost("localhost", "udp");
+
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, get_svc_addr_udp);
+ ATF_TP_ADD_TC(tp, get_svc_addr_tcp);
+
+ return atf_no_error();
+}
+
+#endif
diff --git a/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c b/contrib/netbsd-tests/lib/libc/rpc/t_xdr.c
new file mode 100644
index 000000000000..2a68eb44d74c
--- /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 000000000000..4d2a93bab004
--- /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 000000000000..4437c927214e
--- /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 000000000000..ad9376a338c6
--- /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 000000000000..68e3a6f0b1e5
--- /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 000000000000..8c601b0a8c5c
--- /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 000000000000..1950f738e711
--- /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 000000000000..0ebfd2972815
--- /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 000000000000..c5ab607090a7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_memset.c
@@ -0,0 +1,49 @@
+/* $NetBSD: h_memset.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_memset.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ size_t len = atoi(argv[1]);
+ (void)memset(b, 0, len);
+#ifdef __FreeBSD__
+ return b[0]; /* keeps optimizer from zapping the call to memset() */
+#else
+ return 0;
+#endif
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_raw.c b/contrib/netbsd-tests/lib/libc/ssp/h_raw.c
new file mode 100644
index 000000000000..a2324814716d
--- /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 000000000000..1197b6cece08
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_read.c
@@ -0,0 +1,65 @@
+/* $NetBSD: h_read.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_read.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#ifdef __FreeBSD__
+#include <fcntl.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[MAXPATHLEN];
+ int fd, n;
+ size_t len = atoi(argv[1]);
+
+ fd = open("/dev/zero", O_RDONLY);
+ if ((n = read(fd, b, len)) == -1)
+ abort();
+ (void)printf("%s\n", b);
+ return (0);
+}
+#else
+int
+main(int argc, char *argv[])
+{
+ char b[MAXPATHLEN];
+ size_t len = atoi(argv[1]);
+
+ (void)printf("%s\n", b);
+ return 0;
+}
+#endif
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c
new file mode 100644
index 000000000000..7e8bff6de888
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_readlink.c
@@ -0,0 +1,66 @@
+/* $NetBSD: h_readlink.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_readlink.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#ifdef __FreeBSD__
+#include <err.h>
+#include <string.h>
+#endif
+
+int
+main(int argc, char *argv[])
+{
+#ifdef __FreeBSD__
+ char b[512], *sl;
+ int n;
+ size_t len = atoi(argv[1]);
+ sl = malloc(len);
+ memset(sl, 'a', len);
+ sl[len - 1] = 0;
+ unlink("symlink");
+ if (symlink(sl, "symlink") == -1)
+ err(1, "symlink()");
+ n = readlink("symlink", b, len);
+ unlink("symlink");
+#else
+ char b[MAXPATHLEN];
+ size_t len = atoi(argv[1]);
+ (void)readlink("/", b, len);
+#endif
+ (void)printf("%s\n", b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c
new file mode 100644
index 000000000000..75767887f5d7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/h_snprintf.c
@@ -0,0 +1,51 @@
+/* $NetBSD: h_snprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $ */
+
+/*
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_snprintf.c,v 1.1 2010/12/27 02:04:19 pgoyette Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main(int argc, char *argv[])
+{
+ char b[10];
+ size_t len = atoi(argv[1]);
+#ifdef __FreeBSD__
+ char c[] = "01234567890123456789";
+ c[len] = 0;
+ (void)snprintf(b, len, "%s", c);
+#else
+ (void)snprintf(b, len, "%s", "0123456789");
+#endif
+ (void)printf("%s\n", b);
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c b/contrib/netbsd-tests/lib/libc/ssp/h_sprintf.c
new file mode 100644
index 000000000000..0f6d0cbc1b53
--- /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 000000000000..c8dfbb7a3c1b
--- /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 000000000000..c03d2a8fb905
--- /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 000000000000..687acf78909e
--- /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 000000000000..2a7f1f51e469
--- /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 000000000000..0d66c7b9b2b8
--- /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 000000000000..fddf67b602b5
--- /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 000000000000..0f6af85911b2
--- /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 000000000000..c7fc780a1c1a
--- /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 000000000000..04adc6779553
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/ssp/t_ssp.sh
@@ -0,0 +1,459 @@
+# $NetBSD: t_ssp.sh,v 1.7 2014/04/06 19:28:59 christos Exp $
+#
+# Copyright (c) 2008 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+h_pass()
+{
+ echo "Executing command [ $2$1 ]"
+ eval $2 atf_check -s exit:0 -o ignore -e ignore $1
+}
+
+h_fail()
+{
+ echo "Executing command [ $2$1 ]"
+ # Begin FreeBSD
+ if true; then
+ eval $2 atf_check -s signal -o ignore -e ignore $1
+ else
+ # End FreeBSD
+ eval $2 atf_check -s signal:6 -o ignore -e ignore $1
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case sprintf
+sprintf_head()
+{
+ atf_set "descr" "Checks sprintf(3)"
+}
+sprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_sprintf"
+
+ h_pass "$prog ok"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 0123456789ab"
+ else
+ # End FreeBSD
+ h_fail "$prog 0123456789"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case vsprintf
+vsprintf_head()
+{
+ atf_set "descr" "Checks vsprintf(3)"
+}
+vsprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_vsprintf"
+
+ h_pass "$prog ok"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 0123456789ab"
+ else
+ # End FreeBSD
+ h_fail "$prog 0123456789"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case snprintf
+snprintf_head()
+{
+ atf_set "descr" "Checks snprintf(3)"
+}
+snprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_snprintf"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case vsnprintf
+vsnprintf_head()
+{
+ atf_set "descr" "Checks vsnprintf(3)"
+}
+vsnprintf_body()
+{
+ prog="$(atf_get_srcdir)/h_vsnprintf"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case gets
+gets_head()
+{
+ atf_set "descr" "Checks gets(3)"
+}
+gets_body()
+{
+ prog="$(atf_get_srcdir)/h_gets"
+
+ h_pass "$prog" "echo ok |"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog" "echo 0123456789ab |"
+ else
+ # End FreeBSD
+ h_fail "$prog" "echo 0123456789 |"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case fgets
+fgets_head()
+{
+ atf_set "descr" "Checks fgets(3)"
+}
+fgets_body()
+{
+ prog="$(atf_get_srcdir)/h_fgets"
+
+ h_pass "$prog 10" "echo ok |"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13" "echo 0123456789abc |"
+ else
+ # End FreeBSD
+ h_fail "$prog 11" "echo busted |"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case memcpy
+memcpy_head()
+{
+ atf_set "descr" "Checks memcpy(3)"
+}
+memcpy_body()
+{
+ prog="$(atf_get_srcdir)/h_memcpy"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case memmove
+memmove_head()
+{
+ atf_set "descr" "Checks memmove(3)"
+}
+memmove_body()
+{
+ prog="$(atf_get_srcdir)/h_memmove"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case memset
+memset_head()
+{
+ atf_set "descr" "Checks memset(3)"
+}
+memset_body()
+{
+ prog="$(atf_get_srcdir)/h_memset"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case strcpy
+strcpy_head()
+{
+ atf_set "descr" "Checks strcpy(3)"
+}
+strcpy_body()
+{
+ prog="$(atf_get_srcdir)/h_strcpy"
+
+ h_pass "$prog 0123456"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 0123456789ab"
+ else
+ # End FreeBSD
+ h_fail "$prog 0123456789"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case stpcpy
+stpcpy_head()
+{
+ atf_set "descr" "Checks stpcpy(3)"
+}
+stpcpy_body()
+{
+ prog="$(atf_get_srcdir)/h_stpcpy"
+
+ h_pass "$prog 0123456"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 0123456789ab"
+ else
+ # End FreeBSD
+ h_fail "$prog 0123456789"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case strcat
+strcat_head()
+{
+ atf_set "descr" "Checks strcat(3)"
+}
+strcat_body()
+{
+ prog="$(atf_get_srcdir)/h_strcat"
+
+ h_pass "$prog 0123456"
+ h_fail "$prog 0123456789ABCDEF"
+}
+
+atf_test_case strncpy
+strncpy_head()
+{
+ atf_set "descr" "Checks strncpy(3)"
+}
+strncpy_body()
+{
+ prog="$(atf_get_srcdir)/h_strncpy"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case stpncpy
+stpncpy_head()
+{
+ atf_set "descr" "Checks stpncpy(3)"
+}
+stpncpy_body()
+{
+ prog="$(atf_get_srcdir)/h_stpncpy"
+
+ h_pass "$prog 10"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 13"
+ else
+ # End FreeBSD
+ h_fail "$prog 11"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case strncat
+strncat_head()
+{
+ atf_set "descr" "Checks strncat(3)"
+}
+strncat_body()
+{
+ prog="$(atf_get_srcdir)/h_strncat"
+
+ # Begin FreeBSD
+ h_pass "$prog 8"
+ if true; then
+ h_fail "$prog 11"
+ else
+ # End FreeBSD
+ h_fail "$prog 9"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case raw
+raw_head()
+{
+ atf_set "descr" "Checks raw array overflow"
+}
+raw_body()
+{
+ prog="$(atf_get_srcdir)/h_raw"
+
+ h_pass "$prog 9"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 12"
+ else
+ # End FreeBSD
+ h_fail "$prog 10"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case read
+read_head()
+{
+ atf_set "descr" "Checks read(2)"
+}
+read_body()
+{
+ prog="$(atf_get_srcdir)/h_read"
+
+ h_pass "$prog 1024" "echo foo |"
+ # Begin FreeBSD
+ if true; then
+ h_fail "$prog 1027" "echo bar |"
+ else
+ # End FreeBSD
+ h_fail "$prog 1025" "echo bar |"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case readlink
+readlink_head()
+{
+ atf_set "descr" "Checks readlink(2)"
+}
+readlink_body()
+{
+ prog="$(atf_get_srcdir)/h_readlink"
+
+ # Begin FreeBSD
+ if true; then
+ h_pass "$prog 512"
+ h_fail "$prog 523"
+ else
+ # End FreeBSD
+ h_pass "$prog 1024"
+ h_fail "$prog 1025"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_test_case getcwd
+getcwd_head()
+{
+ atf_set "descr" "Checks getcwd(3)"
+}
+getcwd_body()
+{
+ prog="$(atf_get_srcdir)/h_getcwd"
+
+ h_pass "$prog 1024"
+ # Begin FreeBSD
+ if false; then
+ # End FreeBSD
+ h_fail "$prog 1025"
+ # Begin FreeBSD
+ fi
+ # End FreeBSD
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case sprintf
+ atf_add_test_case vsprintf
+ atf_add_test_case snprintf
+ atf_add_test_case vsnprintf
+ atf_add_test_case gets
+ atf_add_test_case fgets
+ atf_add_test_case memcpy
+ atf_add_test_case memmove
+ atf_add_test_case memset
+ atf_add_test_case stpcpy
+ atf_add_test_case stpncpy
+ atf_add_test_case strcat
+ atf_add_test_case strcpy
+ atf_add_test_case strncat
+ atf_add_test_case strncpy
+ atf_add_test_case raw
+ atf_add_test_case read
+ atf_add_test_case readlink
+ atf_add_test_case getcwd
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c b/contrib/netbsd-tests/lib/libc/stdio/t_clearerr.c
new file mode 100644
index 000000000000..251804e31702
--- /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 000000000000..70498c3c57dc
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_fflush.c
@@ -0,0 +1,175 @@
+/* $NetBSD: t_fflush.c,v 1.1 2011/09/11 05:15:55 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_fflush.c,v 1.1 2011/09/11 05:15:55 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static const char *path = "fflush";
+
+ATF_TC_WITH_CLEANUP(fflush_err);
+ATF_TC_HEAD(fflush_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from fflush(3)");
+}
+
+ATF_TC_BODY(fflush_err, tc)
+{
+ FILE *f;
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("the EOF invariant fails on FreeBSD; this is new");
+#endif
+
+ f = fopen(path, "w");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fflush(NULL) == 0);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "r");
+ ATF_REQUIRE(f != NULL);
+
+ /*
+ * In NetBSD the call should fail if the supplied
+ * parameteris not an open stream or the stream is
+ * not open for writing.
+ */
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fflush(f) == EOF);
+
+ ATF_REQUIRE(fclose(f) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fflush(f) == EOF);
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(fflush_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fflush_seek);
+ATF_TC_HEAD(fflush_seek, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test file offsets with fflush(3)");
+}
+
+ATF_TC_BODY(fflush_seek, tc)
+{
+ char buf[12];
+ int fd = -1;
+ FILE *f;
+
+ /*
+ * IEEE Std 1003.1-2008:
+ *
+ * "For a stream open for reading, if the file
+ * is not already at EOF, and the file is one
+ * capable of seeking, the file offset of the
+ * underlying open file description shall be
+ * adjusted so that the next operation on the
+ * open file description deals with the byte
+ * after the last one read from or written to
+ * the stream being flushed."
+ */
+ f = fopen(path, "w");
+ ATF_REQUIRE(f != NULL);
+
+ ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "r+");
+ ATF_REQUIRE(f != NULL);
+
+ fd = fileno(f);
+ ATF_REQUIRE(fd != -1);
+
+ ATF_REQUIRE(fread(buf, 1, 3, f) == 3);
+ ATF_REQUIRE(fflush(f) == 0);
+ ATF_REQUIRE(fseek(f, 0, SEEK_CUR) == 0);
+
+ /*
+ * Verify that the offsets are right and that
+ * a read operation resumes at the correct location.
+ */
+ ATF_REQUIRE(ftell(f) == 3);
+ ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == 3);
+ ATF_REQUIRE(fgetc(f) == 'b');
+
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(fflush_seek, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fpurge_err);
+ATF_TC_HEAD(fpurge_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from fpurge(3)");
+}
+
+ATF_TC_BODY(fpurge_err, tc)
+{
+ FILE *f;
+
+ f = fopen(path, "w");
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fpurge(f) == EOF);
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(fpurge_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fflush_err);
+ ATF_TP_ADD_TC(tp, fflush_seek);
+ ATF_TP_ADD_TC(tp, fpurge_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c b/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c
new file mode 100644
index 000000000000..31b76d040c26
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_fmemopen.c
@@ -0,0 +1,1181 @@
+/* $NetBSD: t_fmemopen.c,v 1.4 2013/10/19 17:45:00 christos Exp $ */
+
+/*-
+ * Copyright (c)2010 Takehiko NOZAKI,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#if defined(__FreeBSD__) || defined(__NetBSD__)
+#include <atf-c.h>
+#else
+#if defined(__linux__)
+#define _GNU_SOURCE
+#include <features.h>
+#endif
+#include <assert.h>
+#include <stdio.h>
+#define ATF_TC(arg0) static void arg0##_head(void)
+#define ATF_TC_HEAD(arg0, arg1) static void arg0##_head()
+#define atf_tc_set_md_var(arg0, arg1, ...) do { \
+ printf(__VA_ARGS__); \
+ puts(""); \
+} while (/*CONSTCOND*/0)
+#define ATF_TC_BODY(arg0, arg1) static void arg0##_body()
+#define ATF_CHECK(arg0) assert(arg0)
+#define ATF_TP_ADD_TCS(arg0) int main(void)
+#define ATF_TP_ADD_TC(arg0, arg1) arg1##_head(); arg1##_body()
+#define atf_no_error() 0
+#endif
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+const char *mode_rwa[] = {
+ "r", "rb", "r+", "rb+", "r+b",
+ "w", "wb", "w+", "wb+", "w+b",
+ "a", "ab", "a+", "ab+", "a+b",
+ NULL
+};
+
+const char *mode_r[] = { "r", "rb", "r+", "rb+", "r+b", NULL };
+const char *mode_w[] = { "w", "wb", "w+", "wb+", "w+b", NULL };
+const char *mode_a[] = { "a", "ab", "a+", "ab+", "a+b", NULL };
+
+struct testcase {
+ const char *s;
+ off_t n;
+} testcases[] = {
+#define TESTSTR(s) { s, sizeof(s)-1 }
+ TESTSTR("\0he quick brown fox jumps over the lazy dog"),
+ TESTSTR("T\0e quick brown fox jumps over the lazy dog"),
+ TESTSTR("Th\0 quick brown fox jumps over the lazy dog"),
+ TESTSTR("The\0quick brown fox jumps over the lazy dog"),
+ TESTSTR("The \0uick brown fox jumps over the lazy dog"),
+ TESTSTR("The q\0ick brown fox jumps over the lazy dog"),
+ TESTSTR("The qu\0ck brown fox jumps over the lazy dog"),
+ TESTSTR("The qui\0k brown fox jumps over the lazy dog"),
+ TESTSTR("The quic\0 brown fox jumps over the lazy dog"),
+ TESTSTR("The quick\0brown fox jumps over the lazy dog"),
+ TESTSTR("The quick \0rown fox jumps over the lazy dog"),
+ TESTSTR("The quick b\0own fox jumps over the lazy dog"),
+ TESTSTR("The quick br\0wn fox jumps over the lazy dog"),
+ TESTSTR("The quick bro\0n fox jumps over the lazy dog"),
+ TESTSTR("The quick brow\0 fox jumps over the lazy dog"),
+ TESTSTR("The quick brown\0fox jumps over the lazy dog"),
+ TESTSTR("The quick brown \0ox jumps over the lazy dog"),
+ TESTSTR("The quick brown f\0x jumps over the lazy dog"),
+ TESTSTR("The quick brown fo\0 jumps over the lazy dog"),
+ TESTSTR("The quick brown fox\0jumps over the lazy dog"),
+ TESTSTR("The quick brown fox \0umps over the lazy dog"),
+ TESTSTR("The quick brown fox j\0mps over the lazy dog"),
+ TESTSTR("The quick brown fox ju\0ps over the lazy dog"),
+ TESTSTR("The quick brown fox jum\0s over the lazy dog"),
+ TESTSTR("The quick brown fox jump\0 over the lazy dog"),
+ TESTSTR("The quick brown fox jumps\0over the lazy dog"),
+ TESTSTR("The quick brown fox jumps \0ver the lazy dog"),
+ TESTSTR("The quick brown fox jumps o\0er the lazy dog"),
+ TESTSTR("The quick brown fox jumps ov\0r the lazy dog"),
+ TESTSTR("The quick brown fox jumps ove\0 the lazy dog"),
+ TESTSTR("The quick brown fox jumps over\0the lazy dog"),
+ TESTSTR("The quick brown fox jumps over \0he lazy dog"),
+ TESTSTR("The quick brown fox jumps over t\0e lazy dog"),
+ TESTSTR("The quick brown fox jumps over th\0 lazy dog"),
+ TESTSTR("The quick brown fox jumps over the\0lazy dog"),
+ TESTSTR("The quick brown fox jumps over the \0azy dog"),
+ TESTSTR("The quick brown fox jumps over the l\0zy dog"),
+ TESTSTR("The quick brown fox jumps over the la\0y dog"),
+ TESTSTR("The quick brown fox jumps over the laz\0 dog"),
+ TESTSTR("The quick brown fox jumps over the lazy\0dog"),
+ TESTSTR("The quick brown fox jumps over the lazy \0og"),
+ TESTSTR("The quick brown fox jumps over the lazy d\0g"),
+ TESTSTR("The quick brown fox jumps over the lazy do\0"),
+ TESTSTR("The quick brown fox jumps over the lazy dog"),
+ { NULL, 0 },
+};
+
+ATF_TC(test00);
+ATF_TC_HEAD(test00, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test00");
+}
+ATF_TC_BODY(test00, tc)
+{
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (p = &mode_rwa[0]; *p != NULL; ++p) {
+ fp = fmemopen(&buf[0], sizeof(buf), *p);
+/*
+ * Upon successful completion, fmemopen() shall return a pointer to the
+ * object controlling the stream.
+ */
+ ATF_CHECK(fp != NULL);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+}
+
+ATF_TC(test01);
+ATF_TC_HEAD(test01, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test01");
+}
+ATF_TC_BODY(test01, tc)
+{
+ const char **p;
+ const char *mode[] = {
+ "r+", "rb+", "r+b",
+ "w+", "wb+", "w+b",
+ "a+", "ab+", "a+b",
+ NULL
+ };
+ FILE *fp;
+
+ for (p = &mode[0]; *p != NULL; ++p) {
+/*
+ * If a null pointer is specified as the buf argument, fmemopen() shall
+ * allocate size bytes of memory as if by a call to malloc().
+ */
+ fp = fmemopen(NULL, BUFSIZ, *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * If buf is a null pointer, the initial position shall always be set
+ * to the beginning of the buffer.
+ */
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+}
+
+ATF_TC(test02);
+ATF_TC_HEAD(test02, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test02");
+}
+ATF_TC_BODY(test02, tc)
+{
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (p = &mode_r[0]; *p != NULL; ++p) {
+
+ memset(&buf[0], 0x1, sizeof(buf));
+ fp = fmemopen(&buf[0], sizeof(buf), *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * This position is initially set to either the beginning of the buffer
+ * (for r and w modes)
+ */
+ ATF_CHECK((unsigned char)buf[0] == 0x1);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+/*
+ * The stream also maintains the size of the current buffer contents.
+ * For modes r and r+ the size is set to the value given by the size argument.
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+}
+
+ATF_TC(test03);
+ATF_TC_HEAD(test03, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test03");
+}
+ATF_TC_BODY(test03, tc)
+{
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (p = &mode_w[0]; *p != NULL; ++p) {
+
+ memset(&buf[0], 0x1, sizeof(buf));
+ fp = fmemopen(&buf[0], sizeof(buf), *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * This position is initially set to either the beginning of the buffer
+ * (for r and w modes)
+ */
+ ATF_CHECK(buf[0] == '\0');
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+/*
+ * For modes w and w+ the initial size is zero
+ */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+}
+
+ATF_TC(test04);
+ATF_TC_HEAD(test04, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test04");
+}
+ATF_TC_BODY(test04, tc)
+{
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+/*
+ * or to the first null byte in the buffer (for a modes)
+ */
+ for (p = &mode_a[0]; *p != NULL; ++p) {
+
+ memset(&buf[0], 0x1, sizeof(buf));
+ fp = fmemopen(&buf[0], sizeof(buf), *p);
+ ATF_CHECK(fp != NULL);
+
+ ATF_CHECK((unsigned char)buf[0] == 0x1);
+
+/* If no null byte is found in append mode,
+ * the initial position is set to one byte after the end of the buffer.
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
+#endif
+
+/*
+ * and for modes a and a+ the initial size is either the position of the
+ * first null byte in the buffer or the value of the size argument
+ * if no null byte is found.
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)sizeof(buf));
+#endif
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+}
+
+ATF_TC(test05);
+ATF_TC_HEAD(test05, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test05");
+}
+ATF_TC_BODY(test05, tc)
+{
+ const char **p;
+ FILE *fp;
+ char buf[BUFSIZ];
+
+ for (p = &mode_rwa[0]; *p != NULL; ++p) {
+/*
+ * Otherwise, a null pointer shall be returned, and errno shall be set
+ * to indicate the error.
+ */
+ errno = 0;
+ fp = fmemopen(NULL, (size_t)0, *p);
+ ATF_CHECK(fp == NULL);
+ ATF_CHECK(errno == EINVAL);
+
+ errno = 0;
+ fp = fmemopen((void *)&buf[0], 0, *p);
+ ATF_CHECK(fp == NULL);
+ ATF_CHECK(errno == EINVAL);
+ }
+}
+
+ATF_TC(test06);
+ATF_TC_HEAD(test06, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test06");
+}
+ATF_TC_BODY(test06, tc)
+{
+ const char **p;
+ const char *mode[] = { "", " ", "???", NULL };
+ FILE *fp;
+
+ for (p = &mode[0]; *p != NULL; ++p) {
+/*
+ * The value of the mode argument is not valid.
+ */
+ fp = fmemopen(NULL, 1, *p);
+ ATF_CHECK(fp == NULL);
+ ATF_CHECK(errno == EINVAL);
+ }
+}
+
+ATF_TC(test07);
+ATF_TC_HEAD(test07, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test07");
+}
+ATF_TC_BODY(test07, tc)
+{
+#if !defined(__GLIBC__)
+ const char **p;
+ const char *mode[] = {
+ "r", "rb",
+ "w", "wb",
+ "a", "ab",
+ NULL
+ };
+ FILE *fp;
+
+ for (p = &mode[0]; *p != NULL; ++p) {
+/*
+ * Because this feature is only useful when the stream is opened for updating
+ * (because there is no way to get a pointer to the buffer) the fmemopen()
+ * call may fail if the mode argument does not include a '+' .
+ */
+ errno = 0;
+ fp = fmemopen(NULL, 1, *p);
+ ATF_CHECK(fp == NULL);
+ ATF_CHECK(errno == EINVAL);
+ }
+#endif
+}
+
+ATF_TC(test08);
+ATF_TC_HEAD(test08, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test08");
+}
+ATF_TC_BODY(test08, tc)
+{
+#if !defined(__GLIBC__)
+ const char **p;
+ const char *mode[] = {
+ "r+", "rb+", "r+b",
+ "w+", "wb+", "w+b",
+ "a+", "ab+", "a+b",
+ NULL
+ };
+ FILE *fp;
+
+ for (p = &mode[0]; *p != NULL; ++p) {
+/*
+ * The buf argument is a null pointer and the allocation of a buffer of
+ * length size has failed.
+ */
+ fp = fmemopen(NULL, SIZE_MAX, *p);
+ ATF_CHECK(fp == NULL);
+ ATF_CHECK(errno == ENOMEM);
+ }
+#endif
+}
+
+/*
+ * test09 - test14:
+ * An attempt to seek a memory buffer stream to a negative position or to a
+ * position larger than the buffer size given in the size argument shall fail.
+ */
+
+ATF_TC(test09);
+ATF_TC_HEAD(test09, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test09");
+}
+ATF_TC_BODY(test09, tc)
+{
+ struct testcase *t;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+ off_t i;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rwa[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * test fmemopen_seek(SEEK_SET)
+ */
+ /* zero */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_SET) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* positive */
+ for (i = (off_t)1; i <= (off_t)t->n; ++i) {
+ ATF_CHECK(fseeko(fp, i, SEEK_SET) == 0);
+ ATF_CHECK(ftello(fp) == i);
+ }
+ /* positive + OOB */
+ ATF_CHECK(fseeko(fp, t->n + 1, SEEK_SET) == -1);
+ ATF_CHECK(ftello(fp) == t->n);
+
+ /* negative + OOB */
+ ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_SET) == -1);
+ ATF_CHECK(ftello(fp) == t->n);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+const char *mode_rw[] = {
+ "r", "rb", "r+", "rb+", "r+b",
+ "w", "wb", "w+", "wb+", "w+b",
+ NULL
+};
+
+ATF_TC(test10);
+ATF_TC_HEAD(test10, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test10");
+}
+ATF_TC_BODY(test10, tc)
+{
+ struct testcase *t;
+ off_t i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rw[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * test fmemopen_seek(SEEK_CUR)
+ */
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* zero */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* negative & OOB */
+ ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* positive */
+ for (i = 0; i < (off_t)t->n; ++i) {
+ ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0);
+ ATF_CHECK(ftello(fp) == i + 1);
+ }
+
+ /* positive & OOB */
+ ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test11);
+ATF_TC_HEAD(test11, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test11");
+}
+ATF_TC_BODY(test11, tc)
+{
+ struct testcase *t;
+ off_t len, rest, i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ /* test fmemopen_seek(SEEK_CUR) */
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = (off_t)strnlen(t->s, t->n);
+ rest = (off_t)t->n - len;
+ for (p = &mode_a[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_seek(SEEK_CUR)
+ */
+#if defined(__GLIBC__)
+ if (i < (off_t)t->n) {
+#endif
+ /* zero */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_CUR) == 0);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* posive */
+ for (i = (off_t)1; i <= rest; ++i) {
+ ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == 0);
+ ATF_CHECK(ftello(fp) == len + i);
+ }
+
+ /* positive + OOB */
+ ATF_CHECK(fseeko(fp, (off_t)1, SEEK_CUR) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+
+ /* negative */
+ for (i = (off_t)1; i <= (off_t)t->n; ++i) {
+ ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)t->n - i);
+ }
+
+ /* negative + OOB */
+ ATF_CHECK(fseeko(fp, (off_t)-1, SEEK_CUR) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+#if defined(__GLIBC__)
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+#ifndef __FreeBSD__
+ATF_TC(test12);
+ATF_TC_HEAD(test12, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test12");
+}
+ATF_TC_BODY(test12, tc)
+{
+ struct testcase *t;
+ off_t len, rest, i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ /* test fmemopen_seek(SEEK_END) */
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = (off_t)strnlen(t->s, t->n);
+ rest = t->n - len;
+ for (p = &mode_r[0]; *p != NULL; ++p) {
+
+ memcpy(buf, t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+
+/*
+ * test fmemopen_seek(SEEK_END)
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* zero */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* positive + OOB */
+ ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* negative + OOB */
+ ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* positive */
+ for (i = 1; i <= rest; ++i) {
+ ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len + i);
+ }
+
+ /* negative */
+ for (i = 1; i < len; ++i) {
+ ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len - i);
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+#endif
+
+ATF_TC(test13);
+ATF_TC_HEAD(test13, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test13");
+}
+ATF_TC_BODY(test13, tc)
+{
+ struct testcase *t;
+#ifndef __FreeBSD__
+ off_t i;
+#endif
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ /* test fmemopen_seek(SEEK_END) */
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_w[0]; *p != NULL; ++p) {
+
+ memcpy(buf, t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_seek(SEEK_END)
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(ftello(fp) == (off_t)0);
+ ATF_CHECK(buf[0] == '\0');
+
+ /* zero */
+ ATF_CHECK(fseeko(fp, (off_t)0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* positive + OOB */
+ ATF_CHECK(fseeko(fp, (off_t)t->n + 1, SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+
+ /* negative + OOB */
+ ATF_CHECK(fseeko(fp, -1, SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == (off_t)0);
+#endif
+
+#ifndef __FreeBSD__
+ /* positive */
+ for (i = 1; i <= t->n; ++i) {
+ ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == i);
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test14);
+ATF_TC_HEAD(test14, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test14");
+}
+ATF_TC_BODY(test14, tc)
+{
+ struct testcase *t;
+ off_t len, rest, i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ /* test fmemopen_seek(SEEK_END) */
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = (off_t)strnlen(t->s, t->n);
+ rest = (off_t)t->n - len;
+ for (p = &mode_a[0]; *p != NULL; ++p) {
+
+ memcpy(buf, t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_seek(SEEK_END)
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(ftello(fp) == len);
+
+ /* zero */
+ ATF_CHECK(fseeko(fp, 0, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* positive + OOB */
+ ATF_CHECK(fseeko(fp, rest + 1, SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == len);
+
+ /* negative + OOB */
+ ATF_CHECK(fseeko(fp, -(len + 1), SEEK_END) == -1);
+ ATF_CHECK(ftello(fp) == len);
+
+#ifndef __FreeBSD__
+ /* positive */
+ for (i = 1; i <= rest; ++i) {
+ ATF_CHECK(fseeko(fp, i, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len + i);
+ }
+#endif
+
+ /* negative */
+ for (i = 1; i < len; ++i) {
+ ATF_CHECK(fseeko(fp, -i, SEEK_END) == 0);
+ ATF_CHECK(ftello(fp) == len - i);
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+const char *mode_rw1[] = {
+ "r", "rb", "r+", "rb+", "r+b",
+ "w+", "wb+",
+ NULL
+};
+
+#ifndef __FreeBSD__
+
+/* test15 - 18:
+ * When a stream open for writing is flushed or closed, a null byte is written
+ * at the current position or at the end of the buffer, depending on the size
+ * of the contents.
+ */
+
+ATF_TC(test15);
+ATF_TC_HEAD(test15, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test15");
+}
+ATF_TC_BODY(test15, tc)
+{
+ struct testcase *t;
+ const char **p;
+ char buf0[BUFSIZ];
+ FILE *fp;
+ int i;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rw1[0]; *p != NULL; ++p) {
+
+ memcpy(&buf0[0], t->s, t->n);
+ fp = fmemopen(&buf0[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_read + fgetc(3)
+ */
+ for (i = 0; i < t->n; ++i) {
+ ATF_CHECK(ftello(fp) == (off_t)i);
+ ATF_CHECK(fgetc(fp) == buf0[i]);
+ ATF_CHECK(feof(fp) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)i + 1);
+ }
+ ATF_CHECK(fgetc(fp) == EOF);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test16);
+ATF_TC_HEAD(test16, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test16");
+}
+ATF_TC_BODY(test16, tc)
+{
+ struct testcase *t;
+ const char **p;
+ char buf0[BUFSIZ], buf1[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rw1[0]; *p != NULL; ++p) {
+
+ memcpy(&buf0[0], t->s, t->n);
+ buf1[t->n] = 0x1;
+ fp = fmemopen(&buf0[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_read + fread(4)
+ */
+ ATF_CHECK(ftello(fp) == (off_t)0);
+ ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp) == (size_t)t->n);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(memcmp(&buf0[0], &buf1[0], t->n) == 0);
+ ATF_CHECK((unsigned char)buf1[t->n] == 0x1);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+const char *mode_a1[] = { "a+", "ab+", NULL };
+
+ATF_TC(test17);
+ATF_TC_HEAD(test17, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test17");
+}
+ATF_TC_BODY(test17, tc)
+{
+ struct testcase *t;
+ size_t len;
+ int i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = strnlen(t->s, t->n);
+ for (p = &mode_a1[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_read + fgetc(3)
+ */
+#if defined(__GLIBC__)
+ if (i < t->n) {
+#endif
+ for (i = len; i < t->n; ++i) {
+ ATF_CHECK(ftello(fp) == (off_t)i);
+ ATF_CHECK(fgetc(fp) == buf[i]);
+ ATF_CHECK(feof(fp) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)i + 1);
+ }
+ ATF_CHECK(fgetc(fp) == EOF);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ rewind(fp);
+ for (i = 0; i < t->n; ++i) {
+ ATF_CHECK(ftello(fp) == (off_t)i);
+ ATF_CHECK(fgetc(fp) == buf[i]);
+ ATF_CHECK(feof(fp) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)i + 1);
+ }
+ ATF_CHECK(fgetc(fp) == EOF);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+#if defined(__GLIBC__)
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test18);
+ATF_TC_HEAD(test18, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test18");
+}
+ATF_TC_BODY(test18, tc)
+{
+ struct testcase *t;
+ size_t len;
+ const char **p;
+ char buf0[BUFSIZ], buf1[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = strnlen(t->s, t->n);
+ for (p = &mode_a1[0]; *p != NULL; ++p) {
+
+ memcpy(&buf0[0], t->s, t->n);
+ buf1[t->n - len] = 0x1;
+ fp = fmemopen(&buf0[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+/*
+ * test fmemopen_read + fread(3)
+ */
+#if defined(__GLIBC__)
+ if (i < t->n) {
+#endif
+ ATF_CHECK(ftello(fp) == (off_t)len);
+ ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp)
+ == t->n - len);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(!memcmp(&buf0[len], &buf1[0], t->n - len));
+ ATF_CHECK((unsigned char)buf1[t->n - len] == 0x1);
+ rewind(fp);
+ buf1[t->n] = 0x1;
+ ATF_CHECK(ftello(fp) == (off_t)0);
+ ATF_CHECK(fread(&buf1[0], 1, sizeof(buf1), fp)
+ == (size_t)t->n);
+ ATF_CHECK(feof(fp) != 0);
+ ATF_CHECK(!memcmp(&buf0[0], &buf1[0], t->n));
+ ATF_CHECK((unsigned char)buf1[t->n] == 0x1);
+#if defined(__GLIBC__)
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+/*
+ * test19 - test22:
+ * If a stream open for update is flushed or closed and the last write has
+ * advanced the current buffer size, a null byte is written at the end of the
+ * buffer if it fits.
+ */
+
+const char *mode_rw2[] = {
+ "r+", "rb+", "r+b",
+ "w", "wb", "w+", "wb+", "w+b",
+ NULL
+};
+
+ATF_TC(test19);
+ATF_TC_HEAD(test19, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test19");
+}
+ATF_TC_BODY(test19, tc)
+{
+ struct testcase *t;
+ int i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rw2[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ buf[t->n] = 0x1;
+ fp = fmemopen(&buf[0], t->n + 1, *p);
+ ATF_CHECK(fp != NULL);
+ setbuf(fp, NULL);
+/*
+ * test fmemopen_write + fputc(3)
+ */
+ for (i = 0; i < t->n; ++i) {
+ ATF_CHECK(ftello(fp) == (off_t)i);
+ ATF_CHECK(fputc(t->s[i], fp) == t->s[i]);
+ ATF_CHECK(buf[i] == t->s[i]);
+ ATF_CHECK(ftello(fp) == (off_t)i + 1);
+ ATF_CHECK(buf[i] == t->s[i]);
+#if !defined(__GLIBC__)
+ ATF_CHECK(buf[i + 1] == '\0');
+#endif
+ }
+
+/* don't accept non nul character at end of buffer */
+ ATF_CHECK(fputc(0x1, fp) == EOF);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ ATF_CHECK(feof(fp) == 0);
+
+/* accept nul character at end of buffer */
+ ATF_CHECK(fputc('\0', fp) == '\0');
+ ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
+ ATF_CHECK(feof(fp) == 0);
+
+/* reach EOF */
+ ATF_CHECK(fputc('\0', fp) == EOF);
+ ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
+
+ /* compare */
+ ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0);
+ ATF_CHECK(buf[t->n] == '\0');
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test20);
+ATF_TC_HEAD(test20, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test20");
+}
+ATF_TC_BODY(test20, tc)
+{
+ struct testcase *t;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ for (p = &mode_rw2[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t->s, t->n);
+ buf[t->n] = 0x1;
+ fp = fmemopen(&buf[0], t->n + 1, *p);
+ ATF_CHECK(fp != NULL);
+ setbuf(fp, NULL);
+ ATF_CHECK(fwrite(t->s, 1, t->n, fp) == (size_t)t->n);
+/*
+ * test fmemopen_write + fwrite(3)
+ */
+#if !defined(__GLIBC__)
+ ATF_CHECK(buf[t->n] == '\0');
+
+/* don't accept non nul character at end of buffer */
+ ATF_CHECK(fwrite("\x1", 1, 1, fp) == 0);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ ATF_CHECK(feof(fp) == 0);
+#endif
+
+/* accept nul character at end of buffer */
+ ATF_CHECK(fwrite("\x0", 1, 1, fp) == 1);
+ ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
+ ATF_CHECK(feof(fp) == 0);
+
+/* reach EOF */
+ ATF_CHECK(fputc('\0', fp) == EOF);
+ ATF_CHECK(ftello(fp) == (off_t)t->n + 1);
+
+/* compare */
+ ATF_CHECK(memcmp(&buf[0], t->s, t->n) == 0);
+ ATF_CHECK(buf[t->n] == '\0');
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test21);
+ATF_TC_HEAD(test21, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test21");
+}
+ATF_TC_BODY(test21, tc)
+{
+ struct testcase *t;
+ int len, i;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t = &testcases[0]; t->s != NULL; ++t) {
+ len = strnlen(t->s, t->n);
+ for (p = &mode_a[0]; *p != NULL; ++p) {
+ memcpy(&buf[0], t->s, t->n);
+ fp = fmemopen(&buf[0], t->n, *p);
+ ATF_CHECK(fp != NULL);
+ setbuf(fp, NULL);
+/*
+ * test fmemopen_write + fputc(3)
+ */
+ if (len < t->n) {
+ for (i = len; i < t->n - 1; ++i) {
+ ATF_CHECK(ftello(fp) == (off_t)i);
+ ATF_CHECK(fputc(t->s[i - len], fp)
+ == t->s[i - len]);
+ ATF_CHECK(buf[i] == t->s[i - len]);
+ ATF_CHECK(ftello(fp) == (off_t)i + 1);
+#if !defined(__GLIBC__)
+ ATF_CHECK(buf[i + 1] == '\0');
+#endif
+ }
+
+/* don't accept non nul character at end of buffer */
+ ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
+ ATF_CHECK(fputc(0x1, fp) == EOF);
+ ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
+
+/* accept nul character at end of buffer */
+ ATF_CHECK(ftello(fp) == (off_t)t->n - 1);
+ ATF_CHECK(fputc('\0', fp) == '\0');
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ }
+
+/* reach EOF */
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+ ATF_CHECK(fputc('\0', fp) == EOF);
+ ATF_CHECK(ftello(fp) == (off_t)t->n);
+
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+}
+
+ATF_TC(test22);
+ATF_TC_HEAD(test22, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "test22");
+}
+ATF_TC_BODY(test22, tc)
+{
+ struct testcase *t0, *t1;
+ size_t len0, len1, nleft;
+ const char **p;
+ char buf[BUFSIZ];
+ FILE *fp;
+
+ for (t0 = &testcases[0]; t0->s != NULL; ++t0) {
+ len0 = strnlen(t0->s, t0->n);
+ for (t1 = &testcases[0]; t1->s != NULL; ++t1) {
+ len1 = strnlen(t1->s, t1->n);
+ for (p = &mode_a[0]; *p != NULL; ++p) {
+
+ memcpy(&buf[0], t0->s, t0->n);
+ fp = fmemopen(&buf[0], t0->n, *p);
+ ATF_CHECK(fp != NULL);
+ setbuf(fp, NULL);
+/*
+ * test fmemopen_write + fwrite(3)
+ */
+ nleft = t0->n - len0;
+#if !defined(__GLIBC__)
+ if (nleft == 0 || len1 == nleft - 1) {
+ ATF_CHECK(fwrite(t1->s, 1, t1->n, fp)
+ == nleft);
+ ATF_CHECK(ftell(fp) == t1->n);
+ } else {
+ ATF_CHECK(fwrite(t1->s, 1, t1->n, fp)
+ == nleft - 1);
+ ATF_CHECK(ftell(fp) == t1->n - 1);
+ }
+#endif
+ ATF_CHECK(fclose(fp) == 0);
+ }
+ }
+ }
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, test00);
+ ATF_TP_ADD_TC(tp, test01);
+ ATF_TP_ADD_TC(tp, test02);
+ ATF_TP_ADD_TC(tp, test03);
+ ATF_TP_ADD_TC(tp, test04);
+ ATF_TP_ADD_TC(tp, test05);
+ ATF_TP_ADD_TC(tp, test06);
+ ATF_TP_ADD_TC(tp, test07);
+ ATF_TP_ADD_TC(tp, test08);
+ ATF_TP_ADD_TC(tp, test09);
+ ATF_TP_ADD_TC(tp, test10);
+ ATF_TP_ADD_TC(tp, test11);
+#ifndef __FreeBSD__
+ ATF_TP_ADD_TC(tp, test12);
+#endif
+ ATF_TP_ADD_TC(tp, test13);
+ ATF_TP_ADD_TC(tp, test14);
+#ifndef __FreeBSD__
+ ATF_TP_ADD_TC(tp, test15);
+ ATF_TP_ADD_TC(tp, test16);
+ ATF_TP_ADD_TC(tp, test17);
+ ATF_TP_ADD_TC(tp, test18);
+ ATF_TP_ADD_TC(tp, test19);
+ ATF_TP_ADD_TC(tp, test20);
+ ATF_TP_ADD_TC(tp, test21);
+ ATF_TP_ADD_TC(tp, test22);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c b/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c
new file mode 100644
index 000000000000..d9e2dd6a54f2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_fopen.c
@@ -0,0 +1,444 @@
+/* $NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_fopen.c,v 1.3 2011/09/14 14:34:37 martin Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char *path = "fopen";
+
+ATF_TC_WITH_CLEANUP(fdopen_close);
+ATF_TC_HEAD(fdopen_close, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "See that descriptors are closed");
+}
+
+ATF_TC_BODY(fdopen_close, tc)
+{
+ FILE *f;
+ int fd;
+
+ /*
+ * Check that the file descriptor
+ * used to fdopen(3) a stream is
+ * closed once the stream is closed.
+ */
+ fd = open(path, O_RDWR | O_CREAT);
+
+ ATF_REQUIRE(fd >= 0);
+
+ f = fdopen(fd, "w+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(close(fd) == -1);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(fdopen_close, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fdopen_err);
+ATF_TC_HEAD(fdopen_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from fdopen(3)");
+}
+
+ATF_TC_BODY(fdopen_err, tc)
+{
+ int fd;
+
+ fd = open(path, O_RDONLY | O_CREAT);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "w") == NULL);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, fdopen(fd, "a") == NULL);
+
+ ATF_REQUIRE(close(fd) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fdopen(fd, "r") == NULL);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fdopen(-1, "w+") == NULL);
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(fdopen_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fdopen_seek);
+ATF_TC_HEAD(fdopen_seek, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test stream position with fdopen(3)");
+}
+
+ATF_TC_BODY(fdopen_seek, tc)
+{
+ FILE *f;
+ int fd;
+
+ /*
+ * Verify that the file position associated
+ * with the stream corresponds with the offset
+ * set earlier for the file descriptor.
+ */
+ fd = open(path, O_RDWR | O_CREAT);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(write(fd, "garbage", 7) == 7);
+ ATF_REQUIRE(lseek(fd, 3, SEEK_SET) == 3);
+
+ f = fdopen(fd, "r+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(ftell(f) == 3);
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(fdopen_seek, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fopen_err);
+ATF_TC_HEAD(fopen_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from fopen(3)");
+}
+
+ATF_TC_BODY(fopen_err, tc)
+{
+ static const char *mode[] = {
+ "x", "xr", "xr", "+r+", "R", "W+", " aXX", "Xr", " r+", "" };
+
+ char buf[PATH_MAX + 1];
+ size_t i;
+ FILE *f;
+
+ f = fopen(path, "w+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ /*
+ * Note that also "invalid" characters
+ * may follow the mode-string whenever
+ * the first character is valid.
+ */
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ errno = 0;
+ f = fopen(path, mode[i]);
+
+ if (f == NULL && errno == EINVAL)
+ continue;
+
+ if (f != NULL)
+ (void)fclose(f);
+
+ atf_tc_fail_nonfatal("opened file as '%s'", mode[i]);
+ }
+
+ (void)unlink(path);
+ (void)memset(buf, 'x', sizeof(buf));
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EISDIR, fopen("/usr/bin", "w") == NULL);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, fopen("/a/b/c/d/e/f", "r") == NULL);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, fopen(buf, "r+") == NULL);
+}
+
+ATF_TC_CLEANUP(fopen_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fopen_append);
+ATF_TC_HEAD(fopen_append, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that append-mode works");
+}
+
+ATF_TC_BODY(fopen_append, tc)
+{
+ char buf[15];
+ FILE *f;
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ f = fopen(path, "w+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "a");
+
+ ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "r");
+
+ ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14);
+ ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0);
+
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(fopen_append, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(fopen_mode);
+ATF_TC_HEAD(fopen_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test fopen(3) modes");
+}
+
+ATF_TC_BODY(fopen_mode, tc)
+{
+ size_t i;
+ FILE *f;
+
+ static const char *mode[] = {
+ "r", "r+", "w", "w+", "a", "a+",
+ "rb", "r+b", "wb", "w+b", "ab", "a+b"
+ "re", "r+e", "we", "w+e", "ae", "a+e"
+ "rf", "r+f", "wf", "w+f", "af", "a+f"
+ };
+
+ f = fopen(path, "w+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ /*
+ * Verify that various modes work.
+ */
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ f = fopen(path, mode[i]);
+
+ if (f != NULL) {
+ ATF_REQUIRE(fclose(f) == 0);
+ continue;
+ }
+
+ atf_tc_fail_nonfatal("failed to open file as %s", mode[i]);
+ }
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(fopen_mode, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(fopen_perm);
+ATF_TC_HEAD(fopen_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with fopen(3)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(fopen_perm, tc)
+{
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "a+") == NULL);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EACCES, fopen("/bin/ls", "w+") == NULL);
+}
+
+ATF_TC(fopen_regular);
+ATF_TC_HEAD(fopen_regular, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test fopen(3) with 'f' mode");
+}
+
+ATF_TC_BODY(fopen_regular, tc)
+{
+ static const char *mode[] = { "rf", "r+f", "wf", "w+f", "af", "a+f" };
+ static const char *devs[] = { _PATH_DEVNULL };
+
+ size_t i, j;
+ FILE *f;
+
+ for (i = 0; i < __arraycount(devs); i++) {
+
+ for (j = 0; j < __arraycount(mode); j++) {
+
+ errno = 0;
+ f = fopen(devs[i], mode[j]);
+
+ if (f == NULL && errno == EFTYPE)
+ continue;
+
+ if (f != NULL)
+ (void)fclose(f);
+
+ atf_tc_fail_nonfatal("opened %s as %s",
+ devs[i], mode[j]);
+ }
+ }
+}
+
+ATF_TC_WITH_CLEANUP(fopen_seek);
+ATF_TC_HEAD(fopen_seek, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test initial stream position");
+}
+
+ATF_TC_BODY(fopen_seek, tc)
+{
+ FILE *f;
+
+ f = fopen(path, "w+");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ /*
+ * The position of the stream should be
+ * at the start, except for append-mode.
+ */
+ f = fopen(path, "r");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(ftello(f) == 0);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "a");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(ftello(f) == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(fopen_seek, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(freopen_std);
+ATF_TC_HEAD(freopen_std, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of freopen(3)");
+}
+
+ATF_TC_BODY(freopen_std, tc)
+{
+ FILE *std[2] = { stdin, stdout };
+ char buf[15];
+ size_t i;
+ FILE *f;
+
+ /*
+ * Associate a standard stream with a custom stream.
+ * Then write to the standard stream and verify that
+ * the result now appears in the custom stream.
+ */
+ for (i = 0; i < __arraycount(std); i++) {
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ f = fopen(path, "w+");
+ ATF_REQUIRE(f != NULL);
+
+ f = freopen(path, "w+", std[i]);
+ ATF_REQUIRE(f != NULL);
+
+ ATF_REQUIRE(fwrite("garbage", 1, 7, f) == 7);
+ ATF_REQUIRE(fprintf(std[i], "garbage") == 7);
+ ATF_REQUIRE(fclose(f) == 0);
+
+ f = fopen(path, "r");
+
+ ATF_REQUIRE(f != NULL);
+ ATF_REQUIRE(fread(buf, 1, sizeof(buf), f) == 14);
+ ATF_REQUIRE(strncmp(buf, "garbagegarbage", 14) == 0);
+
+ ATF_REQUIRE(fclose(f) == 0);
+ }
+
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(freopen_std, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fdopen_close);
+ ATF_TP_ADD_TC(tp, fdopen_err);
+ ATF_TP_ADD_TC(tp, fdopen_seek);
+ ATF_TP_ADD_TC(tp, fopen_append);
+ ATF_TP_ADD_TC(tp, fopen_err);
+ ATF_TP_ADD_TC(tp, fopen_mode);
+ ATF_TP_ADD_TC(tp, fopen_perm);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, fopen_regular);
+#endif
+ ATF_TP_ADD_TC(tp, fopen_seek);
+ ATF_TP_ADD_TC(tp, freopen_std);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c b/contrib/netbsd-tests/lib/libc/stdio/t_fputc.c
new file mode 100644
index 000000000000..ed7c0dc355a0
--- /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 000000000000..e423060e065b
--- /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 000000000000..699498c09fcc
--- /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 000000000000..5ef58f2fc627
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c
@@ -0,0 +1,204 @@
+/* $NetBSD: t_printf.c,v 1.8 2012/04/11 16:21:42 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <atf-c.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+
+#ifndef __NetBSD__
+#include <signal.h>
+#endif
+
+ATF_TC(snprintf_c99);
+ATF_TC_HEAD(snprintf_c99, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Test printf(3) C99 conformance (PR lib/22019)");
+}
+
+ATF_TC_BODY(snprintf_c99, tc)
+{
+ char s[4];
+
+ (void)memset(s, '\0', sizeof(s));
+ (void)snprintf(s, sizeof(s), "%#.o", 0);
+ (void)printf("printf = %#.o\n", 0);
+ (void)fprintf(stderr, "snprintf = %s", s);
+
+ ATF_REQUIRE(strlen(s) == 1);
+ ATF_REQUIRE(s[0] == '0');
+}
+
+ATF_TC(snprintf_dotzero);
+ATF_TC_HEAD(snprintf_dotzero, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "PR lib/32951: %%.0f formats (0.0,0.5] to \"0.\"");
+}
+
+ATF_TC_BODY(snprintf_dotzero, tc)
+{
+ char s[4];
+
+ ATF_CHECK(snprintf(s, sizeof(s), "%.0f", 0.1) == 1);
+ ATF_REQUIRE_STREQ(s, "0");
+}
+
+ATF_TC(snprintf_posarg);
+ATF_TC_HEAD(snprintf_posarg, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "test for positional arguments");
+}
+
+ATF_TC_BODY(snprintf_posarg, tc)
+{
+ char s[16];
+
+ ATF_CHECK(snprintf(s, sizeof(s), "%1$d", -23) == 3);
+ ATF_REQUIRE_STREQ(s, "-23");
+}
+
+ATF_TC(snprintf_posarg_width);
+ATF_TC_HEAD(snprintf_posarg_width, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "test for positional arguments with "
+ "field width");
+}
+
+ATF_TC_BODY(snprintf_posarg_width, tc)
+{
+ char s[16];
+
+ ATF_CHECK(snprintf(s, sizeof(s), "%1$*2$d", -23, 4) == 4);
+ ATF_REQUIRE_STREQ(s, " -23");
+}
+
+ATF_TC(snprintf_posarg_error);
+ATF_TC_HEAD(snprintf_posarg_error, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "test for positional arguments out "
+ "of bounds");
+}
+
+ATF_TC_BODY(snprintf_posarg_error, tc)
+{
+ char s[16], fmt[32];
+
+#ifndef __NetBSD__
+ atf_tc_expect_signal(SIGSEGV,
+ "some non-NetBSD platforms including FreeBSD don't validate "
+ "negative size; testcase blows up with SIGSEGV");
+#endif
+
+ snprintf(fmt, sizeof(fmt), "%%%zu$d", SIZE_MAX / sizeof(size_t));
+
+ ATF_CHECK(snprintf(s, sizeof(s), fmt, -23) == -1);
+}
+
+ATF_TC(snprintf_float);
+ATF_TC_HEAD(snprintf_float, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "test that floating conversions don't"
+ " leak memory");
+}
+
+ATF_TC_BODY(snprintf_float, tc)
+{
+ union {
+ double d;
+ uint64_t bits;
+ } u;
+ uint32_t ul, uh;
+ time_t now;
+ char buf[1000];
+ struct rlimit rl;
+
+ rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024;
+ ATF_CHECK(setrlimit(RLIMIT_AS, &rl) != -1);
+ rl.rlim_cur = rl.rlim_max = 1 * 1024 * 1024;
+ ATF_CHECK(setrlimit(RLIMIT_DATA, &rl) != -1);
+
+ time(&now);
+ srand(now);
+ for (size_t i = 0; i < 10000; i++) {
+ ul = rand();
+ uh = rand();
+ u.bits = (uint64_t)uh << 32 | ul;
+ ATF_CHECK(snprintf(buf, sizeof buf, " %.2f", u.d) != -1);
+ }
+}
+
+ATF_TC(sprintf_zeropad);
+ATF_TC_HEAD(sprintf_zeropad, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test output format zero padding (PR lib/44113)");
+}
+
+ATF_TC_BODY(sprintf_zeropad, tc)
+{
+ char str[1024];
+
+ ATF_CHECK(sprintf(str, "%010f", 0.0) == 10);
+ ATF_REQUIRE_STREQ(str, "000.000000");
+
+ /* ieeefp */
+#ifndef __vax__
+ /* printf(3) should ignore zero padding for nan/inf */
+ ATF_CHECK(sprintf(str, "%010f", NAN) == 10);
+ ATF_REQUIRE_STREQ(str, " nan");
+ ATF_CHECK(sprintf(str, "%010f", INFINITY) == 10);
+ ATF_REQUIRE_STREQ(str, " inf");
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, snprintf_c99);
+ ATF_TP_ADD_TC(tp, snprintf_dotzero);
+ ATF_TP_ADD_TC(tp, snprintf_posarg);
+ ATF_TP_ADD_TC(tp, snprintf_posarg_width);
+ ATF_TP_ADD_TC(tp, snprintf_posarg_error);
+ ATF_TP_ADD_TC(tp, snprintf_float);
+ ATF_TP_ADD_TC(tp, sprintf_zeropad);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c b/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c
new file mode 100644
index 000000000000..194cd171c9ab
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_scanf.c
@@ -0,0 +1,85 @@
+/* $NetBSD: t_scanf.c,v 1.3 2012/03/18 07:00:51 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+#define NUM -0x1234
+#define STRNUM ___STRING(NUM)
+
+ATF_TC(sscanf_neghex);
+ATF_TC_HEAD(sscanf_neghex, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "PR lib/21691: %%i and %%x fail with negative hex numbers");
+}
+
+ATF_TC_BODY(sscanf_neghex, tc)
+{
+ int i;
+
+ sscanf(STRNUM, "%i", &i);
+ ATF_REQUIRE(i == NUM);
+
+ sscanf(STRNUM, "%x", &i);
+ ATF_REQUIRE(i == NUM);
+}
+
+ATF_TC(sscanf_whitespace);
+ATF_TC_HEAD(sscanf_whitespace, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "verify sscanf skips all whitespace");
+}
+
+ATF_TC_BODY(sscanf_whitespace, tc)
+{
+ const char str[] = "\f\n\r\t\v%z";
+ char c;
+
+#ifndef __NetBSD__
+ atf_tc_expect_fail("fails on FreeBSD and some variants of Linux");
+#endif
+
+ /* set of "white space" symbols from isspace(3) */
+ c = 0;
+ (void)sscanf(str, "%%%c", &c);
+ ATF_REQUIRE(c == 'z');
+}
+
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sscanf_neghex);
+ ATF_TP_ADD_TC(tp, sscanf_whitespace);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c
new file mode 100644
index 000000000000..c0641dbc6bf7
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/h_atexit.c
@@ -0,0 +1,212 @@
+/* $NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code was contributed to The NetBSD Foundation by Jason R. Thorpe.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2011\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: h_atexit.c,v 1.1 2011/01/12 19:44:08 pgoyette Exp $");
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+extern int __cxa_atexit(void (*func)(void *), void *, void *);
+extern void __cxa_finalize(void *);
+
+#ifdef __FreeBSD__
+/*
+ * On shared object unload, in __cxa_finalize, call and clear all installed
+ * atexit and __cxa_atexit handlers that are either installed by unloaded
+ * dso, or points to the functions provided by the dso.
+ *
+ * The reason of the change is to ensure that there is no lingering pointers
+ * to the unloaded code after the dlclose(3). It is known reason for infinite
+ * stream of the crash reports for many programs which use loadable modules
+ * and fail to properly clean on module unload. Examples are apache, php,
+ * perl etc.
+ *
+ * You pass the &dso_handle_1 and &dso_handle_2, which points inside the
+ * main binary, to the registration function. The code from r211706,
+ * correctly detects that they are for the main binary, and on the first
+ * call to __cxa_finalize(), which also pass pointer to main binary, all
+ * registered functions from the main binary are executed.
+ */
+
+static void *dso_handle_1 = (void *)1;
+static void *dso_handle_2 = (void *)2;
+static void *dso_handle_3 = (void *)3;
+#else
+static int dso_handle_1;
+static int dso_handle_2;
+static int dso_handle_3;
+#endif
+
+static int arg_1;
+static int arg_2;
+static int arg_3;
+
+static int exiting_state;
+
+#define ASSERT(expr) \
+do { \
+ if ((expr) == 0) { \
+ write(STDERR_FILENO, __func__, strlen(__func__)); \
+ write(STDERR_FILENO, ": ", 2); \
+ write(STDERR_FILENO, __STRING(expr), \
+ strlen(__STRING(expr))); \
+ write(STDERR_FILENO, "\n", 1); \
+ my_abort(); \
+ } \
+} while (/*CONSTCOND*/0)
+
+#define SUCCESS() \
+do { \
+ write(STDOUT_FILENO, __func__, strlen(__func__)); \
+ write(STDOUT_FILENO, "\n", 1); \
+} while (/*CONSTCOND*/0)
+
+static void
+my_abort(void)
+{
+
+ kill(getpid(), SIGABRT);
+ /* NOTREACHED */
+}
+
+static void
+cxa_handler_5(void *arg)
+{
+ static int cxa_handler_5_called;
+
+ ASSERT(arg == (void *)&arg_1);
+ ASSERT(cxa_handler_5_called == 0);
+ ASSERT(exiting_state == 5);
+
+ exiting_state--;
+ cxa_handler_5_called = 1;
+ SUCCESS();
+}
+
+static void
+cxa_handler_4(void *arg)
+{
+ static int cxa_handler_4_called;
+
+ ASSERT(arg == (void *)&arg_1);
+ ASSERT(cxa_handler_4_called == 0);
+ ASSERT(exiting_state == 4);
+
+ exiting_state--;
+ cxa_handler_4_called = 1;
+ SUCCESS();
+}
+
+static void
+cxa_handler_3(void *arg)
+{
+ static int cxa_handler_3_called;
+
+ ASSERT(arg == (void *)&arg_2);
+ ASSERT(cxa_handler_3_called == 0);
+ ASSERT(exiting_state == 3);
+
+ exiting_state--;
+ cxa_handler_3_called = 1;
+ SUCCESS();
+}
+
+static void
+cxa_handler_2(void *arg)
+{
+ static int cxa_handler_2_called;
+
+ ASSERT(arg == (void *)&arg_3);
+ ASSERT(cxa_handler_2_called == 0);
+ ASSERT(exiting_state == 2);
+
+ exiting_state--;
+ cxa_handler_2_called = 1;
+ SUCCESS();
+}
+
+static void
+normal_handler_1(void)
+{
+ static int normal_handler_1_called;
+
+ ASSERT(normal_handler_1_called == 0);
+ ASSERT(exiting_state == 1);
+
+ exiting_state--;
+ normal_handler_1_called = 1;
+ SUCCESS();
+}
+
+static void
+normal_handler_0(void)
+{
+ static int normal_handler_0_called;
+
+ ASSERT(normal_handler_0_called == 0);
+ ASSERT(exiting_state == 0);
+
+ normal_handler_0_called = 1;
+ SUCCESS();
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ exiting_state = 5;
+
+ ASSERT(0 == atexit(normal_handler_0));
+ ASSERT(0 == atexit(normal_handler_1));
+#ifdef __FreeBSD__
+ ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, dso_handle_2));
+ ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, dso_handle_3));
+
+ __cxa_finalize(dso_handle_1);
+ __cxa_finalize(dso_handle_2);
+#else
+ ASSERT(0 == __cxa_atexit(cxa_handler_4, &arg_1, &dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_5, &arg_1, &dso_handle_1));
+ ASSERT(0 == __cxa_atexit(cxa_handler_3, &arg_2, &dso_handle_2));
+ ASSERT(0 == __cxa_atexit(cxa_handler_2, &arg_3, &dso_handle_3));
+
+ __cxa_finalize(&dso_handle_1);
+ __cxa_finalize(&dso_handle_2);
+#endif
+ exit(0);
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c
new file mode 100644
index 000000000000..ec2b9bbf3d52
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt.c
@@ -0,0 +1,130 @@
+/* $NetBSD: h_getopt.c,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2002 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#ifdef __FreeBSD__
+#include <libutil.h>
+#endif
+
+#define WS "\t\n "
+#define debug 0
+
+int
+main(int argc, char *argv[])
+{
+ size_t len, lineno = 0;
+ char *line, *ptr, *optstring = NULL, *result = NULL;
+ char buf[1024];
+ char *args[100];
+ char arg[100];
+ int nargs = -1;
+ int c;
+
+ while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) {
+ if (strncmp(line, "load:", 5) == 0) {
+ if (optstring)
+ free(optstring);
+ optstring = strtok(&line[6], WS);
+ if (optstring == NULL)
+ errx(1, "missing optstring at line %ld",
+ (unsigned long)lineno);
+ optstring = strdup(optstring);
+ if (debug)
+ fprintf(stderr, "optstring = %s\n", optstring);
+ } else if (strncmp(line, "args:", 5) == 0) {
+ for (; nargs >= 0; nargs--) {
+ if (args[nargs] != NULL)
+ free(args[nargs]);
+ }
+ args[nargs = 0] = strtok(&line[6], WS);
+ if (args[nargs] == NULL)
+ errx(1, "missing args at line %ld",
+ (unsigned long)lineno);
+
+ args[nargs] = strdup(args[nargs]);
+ while ((args[++nargs] = strtok(NULL, WS)) != NULL)
+ args[nargs] = strdup(args[nargs]);
+ if (debug) {
+ int i = 0;
+ for (i = 0; i < nargs; i++)
+ fprintf(stderr, "argv[%d] = %s\n", i,
+ args[i]);
+ }
+ } else if (strncmp(line, "result:", 7) == 0) {
+ buf[0] = '\0';
+ optind = optreset = 1;
+ if (result)
+ free(result);
+ result = strtok(&line[8], WS);
+ if (result == NULL)
+ errx(1, "missing result at line %ld",
+ (unsigned long)lineno);
+ result = strdup(result);
+ if (nargs == -1)
+ errx(1, "result: without args:");
+ if (debug)
+ fprintf(stderr, "result = %s\n", result);
+ while ((c = getopt(nargs, args, optstring)) != -1) {
+ if (c == ':')
+ err(1, "`:' found as argument char");
+ if ((ptr = strchr(optstring, c)) == NULL) {
+ snprintf(arg, sizeof(arg), "!%c,", c);
+ strcat(buf, arg);
+ continue;
+ }
+ if (ptr[1] != ':')
+ snprintf(arg, sizeof(arg), "%c,", c);
+ else
+ snprintf(arg, sizeof(arg), "%c=%s,",
+ c, optarg);
+ strcat(buf, arg);
+ }
+ len = strlen(buf);
+ if (len > 0) {
+ buf[len - 1] = '|';
+ buf[len] = '\0';
+ } else {
+ buf[0] = '|';
+ buf[1] = '\0';
+ }
+ snprintf(arg, sizeof(arg), "%d", nargs - optind);
+ strcat(buf, arg);
+ if (strcmp(buf, result) != 0)
+ errx(1, "`%s' != `%s'", buf, result);
+ }
+ free(line);
+ }
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c
new file mode 100644
index 000000000000..2293e2cc9576
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/h_getopt_long.c
@@ -0,0 +1,242 @@
+/* $NetBSD: h_getopt_long.c,v 1.1 2011/01/01 23:56:49 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ctype.h>
+#include <err.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef __FreeBSD__
+#include <libutil.h>
+#endif
+
+#define SKIPWS(p) while (isspace((int)(*p))) p++
+#define WS "\t\n "
+
+int
+main(int argc, char *argv[])
+{
+ size_t len, lineno = 0;
+ char *line, *eptr, *longopt, *ptr, *optstring = NULL, *result = NULL;
+ char buf[1024];
+ char *args[128];
+ char arg[256];
+ int nargs = -1;
+ int c;
+ int nlongopts = 0;
+ int maxnlongopts = 0;
+ int *longopt_flags = NULL;
+ struct option *longopts = NULL;
+
+ while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) {
+ if (strncmp(line, "optstring:", 10) == 0) {
+ if (optstring)
+ free(optstring);
+ optstring = strtok(&line[11], WS);
+ if (optstring == NULL)
+ errx(1, "missing optstring at line %ld",
+ (unsigned long)lineno);
+ optstring = strdup(optstring);
+ } else if (strncmp(line, "longopts:", 9) == 0) {
+ if (longopts) {
+ int i;
+ for (i = 0; i < nlongopts; i++)
+ if (longopts[i].name != NULL)
+ free(__UNCONST(longopts[i].name));
+ free(longopts);
+ }
+ if (longopt_flags)
+ free(longopt_flags);
+ nlongopts = 0;
+ ptr = strtok(&line[10], WS);
+ if (ptr == NULL)
+ errx(1, "missing longopts at line %ld",
+ (unsigned long)lineno);
+ maxnlongopts = strtoul(ptr, &eptr, 10);
+ if (*eptr != '\0')
+ warnx("garbage in longopts at line %ld",
+ (unsigned long)lineno);
+ maxnlongopts++; /* space for trailer */
+ longopts =
+ (struct option *)calloc(sizeof(struct option),
+ maxnlongopts);
+ if (longopts == NULL)
+ err(1, "calloc");
+ longopt_flags = (int *)calloc(sizeof(int), maxnlongopts);
+ if (longopt_flags == NULL)
+ err(1, "calloc");
+ } else if (strncmp(line, "longopt:", 8) == 0) {
+ if (longopts == NULL)
+ errx(1, "longopt: without longopts at line %ld",
+ (unsigned long)lineno);
+ if (nlongopts >= maxnlongopts)
+ errx(1, "longopt: too many options at line %ld",
+ (unsigned long)lineno);
+ /* name */
+ ptr = &line[9];
+ SKIPWS(ptr);
+ longopt = strsep(&ptr, ",");
+ if (longopt == NULL)
+ errx(1, "missing longopt at line %ld",
+ (unsigned long)lineno);
+ longopts[nlongopts].name = strdup(longopt);
+ /* has_arg */
+ SKIPWS(ptr);
+ longopt = strsep(&ptr, ",");
+ if (*longopt != '\0') {
+ if (strncmp(longopt, "0", 1) == 0 ||
+ strncmp(longopt, "no_argument", 2) == 0)
+ longopts[nlongopts].has_arg = no_argument;
+ else if (strncmp(longopt, "1", 1) == 0 ||
+ strncmp(longopt, "required_argument", 8) == 0)
+ longopts[nlongopts].has_arg = required_argument;
+ else if (strncmp(longopt, "2", 1) == 0 ||
+ strncmp(longopt, "optional_argument", 8) == 0)
+ longopts[nlongopts].has_arg = optional_argument;
+ else
+ errx(1, "unknown has_arg %s at line %ld",
+ longopt, (unsigned long)lineno);
+ }
+ /* flag */
+ SKIPWS(ptr);
+ longopt = strsep(&ptr, ",");
+ if (*longopt != '\0' &&
+ strncmp(longopt, "NULL", 4) != 0)
+ longopts[nlongopts].flag = &longopt_flags[nlongopts];
+ /* val */
+ SKIPWS(ptr);
+ longopt = strsep(&ptr, ",");
+ if (*longopt == '\0')
+ errx(1, "missing val at line %ld",
+ (unsigned long)lineno);
+ if (*longopt != '\'') {
+ longopts[nlongopts].val =
+ (int)strtoul(longopt, &eptr, 10);
+ if (*eptr != '\0')
+ errx(1, "invalid val at line %ld",
+ (unsigned long)lineno);
+ } else
+ longopts[nlongopts].val = (int)longopt[1];
+ nlongopts++;
+ } else if (strncmp(line, "args:", 5) == 0) {
+ for (; nargs >= 0; nargs--) {
+ if (args[nargs] != NULL)
+ free(args[nargs]);
+ }
+ args[nargs = 0] = strtok(&line[6], WS);
+ if (args[nargs] == NULL)
+ errx(1, "Missing args");
+
+ args[nargs] = strdup(args[nargs]);
+ while ((args[++nargs] = strtok(NULL, WS)) != NULL)
+ args[nargs] = strdup(args[nargs]);
+ } else if (strncmp(line, "result:", 7) == 0) {
+ int li;
+ buf[0] = '\0';
+ optind = optreset = 1;
+ if (result)
+ free(result);
+ result = strtok(&line[8], WS);
+ if (result == NULL)
+ errx(1, "missing result at line %ld",
+ (unsigned long)lineno);
+ if (optstring == NULL)
+ errx(1, "result: without optstring");
+ if (longopts == NULL || nlongopts == 0)
+ errx(1, "result: without longopts");
+ result = strdup(result);
+ if (nargs == -1)
+ errx(1, "result: without args");
+ li = -2;
+ while ((c = getopt_long(nargs, args, optstring,
+ longopts, &li)) != -1) {
+ if (c == ':')
+ errx(1, "`:' found as argument char");
+ if (li == -2) {
+ ptr = strchr(optstring, c);
+ if (ptr == NULL) {
+ snprintf(arg, sizeof(arg),
+ "!%c,", c);
+ strcat(buf, arg);
+ continue;
+ }
+ if (ptr[1] != ':')
+ snprintf(arg, sizeof(arg),
+ "%c,", c);
+ else
+ snprintf(arg, sizeof(arg),
+ "%c=%s,", c, optarg);
+ } else {
+ switch (longopts[li].has_arg) {
+ case no_argument:
+ snprintf(arg, sizeof(arg), "-%s,",
+ longopts[li].name);
+ break;
+ case required_argument:
+ snprintf(arg, sizeof(arg),
+ "-%s=%s,",
+ longopts[li].name, optarg);
+ break;
+ case optional_argument:
+ snprintf(arg, sizeof(arg),
+ "-%s%s%s,",
+ longopts[li].name,
+ (optarg)? "=" : "",
+ (optarg)? optarg : "");
+ break;
+ default:
+ errx(1, "internal error");
+ }
+ }
+ strcat(buf, arg);
+ li = -2;
+ }
+ len = strlen(buf);
+ if (len > 0) {
+ buf[len - 1] = '|';
+ buf[len] = '\0';
+ } else {
+ buf[0] = '|';
+ buf[1] = '\0';
+ }
+ snprintf(arg, sizeof(arg), "%d", nargs - optind);
+ strcat(buf, arg);
+ if (strcmp(buf, result) != 0)
+ errx(1, "`%s' != `%s'", buf, result);
+ } else
+ errx(1, "unknown directive at line %ld",
+ (unsigned long)lineno);
+ free(line);
+ }
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c b/contrib/netbsd-tests/lib/libc/stdlib/t_abs.c
new file mode 100644
index 000000000000..282a125cf644
--- /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 000000000000..d11268bed091
--- /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 000000000000..3e0c35f73cdb
--- /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 000000000000..376f35732ac1
--- /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 000000000000..067cb519f386
--- /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 000000000000..5a8fa2822429
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv.c
@@ -0,0 +1,211 @@
+/* $NetBSD: t_getenv.c,v 1.2 2011/07/15 13:54:31 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_getenv.c,v 1.2 2011/07/15 13:54:31 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef __FreeBSD__
+#include <signal.h>
+#endif
+
+extern char **environ;
+
+ATF_TC(clearenv_basic);
+ATF_TC_HEAD(clearenv_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test user clearing environment directly");
+}
+
+ATF_TC_BODY(clearenv_basic, tc)
+{
+ char name[1024], value[1024];
+
+ for (size_t i = 0; i < 1024; i++) {
+ snprintf(name, sizeof(name), "crap%zu", i);
+ snprintf(value, sizeof(value), "%zu", i);
+ ATF_CHECK(setenv(name, value, 1) != -1);
+ }
+
+ *environ = NULL;
+
+ for (size_t i = 0; i < 1; i++) {
+ snprintf(name, sizeof(name), "crap%zu", i);
+ snprintf(value, sizeof(value), "%zu", i);
+ ATF_CHECK(setenv(name, value, 1) != -1);
+ }
+
+ ATF_CHECK_STREQ(getenv("crap0"), "0");
+ ATF_CHECK(getenv("crap1") == NULL);
+ ATF_CHECK(getenv("crap2") == NULL);
+}
+
+ATF_TC(getenv_basic);
+ATF_TC_HEAD(getenv_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test setenv(3), getenv(3)");
+}
+
+ATF_TC_BODY(getenv_basic, tc)
+{
+ ATF_CHECK(setenv("EVIL", "very=bad", 1) != -1);
+ ATF_CHECK_STREQ(getenv("EVIL"), "very=bad");
+ ATF_CHECK(getenv("EVIL=very") == NULL);
+ ATF_CHECK(unsetenv("EVIL") != -1);
+}
+
+ATF_TC(putenv_basic);
+ATF_TC_HEAD(putenv_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test putenv(3), getenv(3), unsetenv(3)");
+}
+
+
+ATF_TC_BODY(putenv_basic, tc)
+{
+ char string[1024];
+
+ snprintf(string, sizeof(string), "crap=true");
+ ATF_CHECK(putenv(string) != -1);
+ ATF_CHECK_STREQ(getenv("crap"), "true");
+ string[1] = 'l';
+ ATF_CHECK_STREQ(getenv("clap"), "true");
+ ATF_CHECK(getenv("crap") == NULL);
+ string[1] = 'r';
+ ATF_CHECK(unsetenv("crap") != -1);
+ ATF_CHECK(getenv("crap") == NULL);
+
+ ATF_CHECK_ERRNO(EINVAL, putenv(NULL) == -1);
+ ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("val")) == -1);
+ ATF_CHECK_ERRNO(EINVAL, putenv(__UNCONST("=val")) == -1);
+}
+
+ATF_TC(setenv_basic);
+ATF_TC_HEAD(setenv_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test setenv(3), getenv(3), unsetenv(3)");
+ atf_tc_set_md_var(tc, "timeout", "300");
+}
+
+ATF_TC_BODY(setenv_basic, tc)
+{
+ const size_t numvars = 8192;
+ size_t i, offset;
+ char name[1024];
+ char value[1024];
+
+ offset = lrand48();
+ for (i = 0; i < numvars; i++) {
+ (void)snprintf(name, sizeof(name), "var%zu",
+ (i * 7 + offset) % numvars);
+ (void)snprintf(value, sizeof(value), "value%ld", lrand48());
+ ATF_CHECK(setenv(name, value, 1) != -1);
+ ATF_CHECK(setenv(name, "foo", 0) != -1);
+ ATF_CHECK_STREQ(getenv(name), value);
+ }
+
+ offset = lrand48();
+ for (i = 0; i < numvars; i++) {
+ (void)snprintf(name, sizeof(name), "var%zu",
+ (i * 11 + offset) % numvars);
+ ATF_CHECK(unsetenv(name) != -1);
+ ATF_CHECK(getenv(name) == NULL);
+ ATF_CHECK(unsetenv(name) != -1);
+ }
+
+ ATF_CHECK_ERRNO(EINVAL, setenv(NULL, "val", 1) == -1);
+ ATF_CHECK_ERRNO(EINVAL, setenv("", "val", 1) == -1);
+ ATF_CHECK_ERRNO(EINVAL, setenv("v=r", "val", 1) == -1);
+#ifdef __FreeBSD__
+ /*
+ Both FreeBSD and OS/X does not validate the second
+ argument to setenv(3)
+ */
+ atf_tc_expect_signal(SIGSEGV, "FreeBSD does not validate the second "
+ "argument to setenv(3); see bin/189805");
+#endif
+
+ ATF_CHECK_ERRNO(EINVAL, setenv("var", NULL, 1) == -1);
+
+ ATF_CHECK(setenv("var", "=val", 1) == 0);
+ ATF_CHECK_STREQ(getenv("var"), "=val");
+}
+
+ATF_TC(setenv_mixed);
+ATF_TC_HEAD(setenv_mixed, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test mixing setenv(3), unsetenv(3) and putenv(3)");
+}
+
+ATF_TC_BODY(setenv_mixed, tc)
+{
+ char string[32];
+
+ (void)strcpy(string, "mixedcrap=putenv");
+
+ ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1);
+ ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv");
+ ATF_CHECK(putenv(string) != -1);
+ ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv");
+ ATF_CHECK(unsetenv("mixedcrap") != -1);
+ ATF_CHECK(getenv("mixedcrap") == NULL);
+
+ ATF_CHECK(putenv(string) != -1);
+ ATF_CHECK_STREQ(getenv("mixedcrap"), "putenv");
+ ATF_CHECK(setenv("mixedcrap", "setenv", 1) != -1);
+ ATF_CHECK_STREQ(getenv("mixedcrap"), "setenv");
+ ATF_CHECK(unsetenv("mixedcrap") != -1);
+ ATF_CHECK(getenv("mixedcrap") == NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, clearenv_basic);
+ ATF_TP_ADD_TC(tp, getenv_basic);
+ ATF_TP_ADD_TC(tp, putenv_basic);
+ ATF_TP_ADD_TC(tp, setenv_basic);
+ ATF_TP_ADD_TC(tp, setenv_mixed);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c b/contrib/netbsd-tests/lib/libc/stdlib/t_getenv_thread.c
new file mode 100644
index 000000000000..d935629339e8
--- /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 000000000000..cc10f6525432
--- /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 000000000000..d66596747f3a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_hsearch.c
@@ -0,0 +1,407 @@
+/* $NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2001 Christopher G. Demetriou
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the
+ * NetBSD Project. See http://www.NetBSD.org/ for
+ * information about NetBSD.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * <<Id: LICENSE,v 1.2 2000/06/14 15:57:33 cgd Exp>>
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_hsearch.c,v 1.4 2014/07/20 20:17:21 christos Exp $");
+
+#include <errno.h>
+#include <search.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <atf-c.h>
+
+#define REQUIRE_ERRNO(x) ATF_REQUIRE_MSG(x, "%s", strerror(errno))
+
+#ifdef __NetBSD__
+ATF_TC(hsearch_basic);
+ATF_TC_HEAD(hsearch_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching");
+}
+
+ATF_TC_BODY(hsearch_basic, tc)
+{
+ ENTRY e, *ep;
+ char ch[2];
+ int i;
+
+ REQUIRE_ERRNO(hcreate(16) != 0);
+
+ /* ch[1] should be constant from here on down. */
+ ch[1] = '\0';
+
+ /* Basic insertions. Check enough that there'll be collisions. */
+ for (i = 0; i < 26; i++) {
+ ch[0] = 'a' + i;
+ e.key = strdup(ch); /* ptr to provided key is kept! */
+ ATF_REQUIRE(e.key != NULL);
+ e.data = (void *)(intptr_t)i;
+
+ ep = hsearch(e, ENTER);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, ch);
+ ATF_REQUIRE_EQ((intptr_t)ep->data, i);
+ }
+
+ /* e.key should be constant from here on down. */
+ e.key = ch;
+
+ /* Basic lookups. */
+ for (i = 0; i < 26; i++) {
+ ch[0] = 'a' + i;
+
+ ep = hsearch(e, FIND);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, ch);
+ ATF_REQUIRE_EQ((intptr_t)ep->data, i);
+ }
+
+ hdestroy1(free, NULL);
+}
+#endif
+
+ATF_TC(hsearch_duplicate);
+ATF_TC_HEAD(hsearch_duplicate, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate "
+ "doesn't overwrite existing data");
+}
+
+ATF_TC_BODY(hsearch_duplicate, tc)
+{
+ ENTRY e, *ep;
+
+ REQUIRE_ERRNO(hcreate(16));
+
+ e.key = __UNCONST("a");
+ e.data = (void *)(intptr_t) 0;
+
+ ep = hsearch(e, ENTER);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ e.data = (void *)(intptr_t)12345;
+
+ ep = hsearch(e, ENTER);
+ ep = hsearch(e, FIND);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ hdestroy();
+}
+
+ATF_TC(hsearch_nonexistent);
+ATF_TC_HEAD(hsearch_nonexistent, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks searching for non-existent entry");
+}
+
+ATF_TC_BODY(hsearch_nonexistent, tc)
+{
+ ENTRY e, *ep;
+
+ REQUIRE_ERRNO(hcreate(16));
+
+ e.key = __UNCONST("A");
+ ep = hsearch(e, FIND);
+ ATF_REQUIRE_EQ(ep, NULL);
+
+ hdestroy();
+}
+
+ATF_TC(hsearch_two);
+ATF_TC_HEAD(hsearch_two, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that searching doesn't overwrite previous search results");
+}
+
+ATF_TC_BODY(hsearch_two, tc)
+{
+ ENTRY e, *ep, *ep2;
+
+ REQUIRE_ERRNO(hcreate(16));
+
+ e.key = __UNCONST("a");
+ e.data = (void*)(intptr_t)0;
+
+ ep = hsearch(e, ENTER);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ e.key = __UNCONST("b");
+ e.data = (void*)(intptr_t)1;
+
+ ep = hsearch(e, ENTER);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "b");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 1);
+
+ e.key = __UNCONST("a");
+ ep = hsearch(e, FIND);
+
+ e.key = __UNCONST("b");
+ ep2 = hsearch(e, FIND);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ ATF_REQUIRE(ep2 != NULL);
+ ATF_REQUIRE_STREQ(ep2->key, "b");
+ ATF_REQUIRE_EQ((intptr_t)ep2->data, 1);
+
+ hdestroy();
+}
+
+#ifdef __NetBSD__
+ATF_TC(hsearch_r_basic);
+ATF_TC_HEAD(hsearch_r_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks basic insertions and searching");
+}
+
+ATF_TC_BODY(hsearch_r_basic, tc)
+{
+ ENTRY e, *ep;
+ char ch[2];
+ int i;
+ struct hsearch_data t;
+
+ REQUIRE_ERRNO(hcreate_r(16, &t) != 0);
+
+ /* ch[1] should be constant from here on down. */
+ ch[1] = '\0';
+
+ /* Basic insertions. Check enough that there'll be collisions. */
+ for (i = 0; i < 26; i++) {
+ ch[0] = 'a' + i;
+ e.key = strdup(ch); /* ptr to provided key is kept! */
+ ATF_REQUIRE(e.key != NULL);
+ e.data = (void *)(intptr_t)i;
+
+ ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, ch);
+ ATF_REQUIRE_EQ((intptr_t)ep->data, i);
+ }
+
+ /* e.key should be constant from here on down. */
+ e.key = ch;
+
+ /* Basic lookups. */
+ for (i = 0; i < 26; i++) {
+ ch[0] = 'a' + i;
+
+ ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, ch);
+ ATF_REQUIRE_EQ((intptr_t)ep->data, i);
+ }
+
+ hdestroy1_r(&t, free, NULL);
+}
+#endif
+
+ATF_TC(hsearch_r_duplicate);
+ATF_TC_HEAD(hsearch_r_duplicate, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks that inserting duplicate "
+ "doesn't overwrite existing data");
+}
+
+ATF_TC_BODY(hsearch_r_duplicate, tc)
+{
+ ENTRY e, *ep;
+ struct hsearch_data t;
+
+ REQUIRE_ERRNO(hcreate_r(16, &t));
+
+ e.key = __UNCONST("a");
+ e.data = (void *)(intptr_t) 0;
+
+ ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ e.data = (void *)(intptr_t)12345;
+
+ ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
+ ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ hdestroy_r(&t);
+}
+
+ATF_TC(hsearch_r_nonexistent);
+ATF_TC_HEAD(hsearch_r_nonexistent, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks searching for non-existent entry");
+}
+
+ATF_TC_BODY(hsearch_r_nonexistent, tc)
+{
+ ENTRY e, *ep;
+ struct hsearch_data t;
+
+ REQUIRE_ERRNO(hcreate_r(16, &t));
+
+ e.key = __UNCONST("A");
+ ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
+ ATF_REQUIRE_EQ(ep, NULL);
+
+ hdestroy_r(&t);
+}
+
+ATF_TC(hsearch_r_two);
+ATF_TC_HEAD(hsearch_r_two, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that searching doesn't overwrite previous search results");
+}
+
+ATF_TC_BODY(hsearch_r_two, tc)
+{
+ ENTRY e, *ep, *ep2;
+ struct hsearch_data t;
+
+ REQUIRE_ERRNO(hcreate_r(16, &t));
+
+ e.key = __UNCONST("a");
+ e.data = (void*)(intptr_t)0;
+
+ ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ e.key = __UNCONST("b");
+ e.data = (void*)(intptr_t)1;
+
+ ATF_REQUIRE(hsearch_r(e, ENTER, &ep, &t) == 1);
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "b");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 1);
+
+ e.key = __UNCONST("a");
+ ATF_REQUIRE(hsearch_r(e, FIND, &ep, &t) == 1);
+
+ e.key = __UNCONST("b");
+ ATF_REQUIRE(hsearch_r(e, FIND, &ep2, &t) == 1);
+
+ ATF_REQUIRE(ep != NULL);
+ ATF_REQUIRE_STREQ(ep->key, "a");
+ ATF_REQUIRE_EQ((intptr_t)ep->data, 0);
+
+ ATF_REQUIRE(ep2 != NULL);
+ ATF_REQUIRE_STREQ(ep2->key, "b");
+ ATF_REQUIRE_EQ((intptr_t)ep2->data, 1);
+
+ hdestroy_r(&t);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, hsearch_basic);
+#endif
+ ATF_TP_ADD_TC(tp, hsearch_duplicate);
+ ATF_TP_ADD_TC(tp, hsearch_nonexistent);
+ ATF_TP_ADD_TC(tp, hsearch_two);
+
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, hsearch_r_basic);
+#endif
+ ATF_TP_ADD_TC(tp, hsearch_r_duplicate);
+ ATF_TP_ADD_TC(tp, hsearch_r_nonexistent);
+ ATF_TP_ADD_TC(tp, hsearch_r_two);
+
+ 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 000000000000..77d64435235d
--- /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 000000000000..47afb8493bed
--- /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 000000000000..9a6d21ebb647
--- /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 000000000000..8f0f899e2ee4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/stdlib/t_strtod.c
@@ -0,0 +1,342 @@
+/* $NetBSD: t_strtod.c,v 1.32 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Public domain, Otto Moerbeek <otto@drijf.net>, 2006. */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_strtod.c,v 1.32 2014/11/04 00:20:19 justin Exp $");
+
+#include <errno.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <atf-c.h>
+
+#if defined(__i386__) || defined(__amd64__) || defined(__sparc__)
+#include <fenv.h>
+#endif
+
+#if !defined(__vax__)
+static const char * const inf_strings[] =
+ { "Inf", "INF", "-Inf", "-INF", "Infinity", "+Infinity",
+ "INFINITY", "-INFINITY", "InFiNiTy", "+InFiNiTy" };
+const char *nan_string = "NaN(x)y";
+#endif
+
+#ifdef __FreeBSD__
+#define __HAVE_LONG_DOUBLE
+#endif
+
+ATF_TC(strtod_basic);
+ATF_TC_HEAD(strtod_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of strtod(3)");
+}
+
+ATF_TC_BODY(strtod_basic, tc)
+{
+ static const size_t n = 1024 * 1000;
+
+ for (size_t i = 1; i < n; i = i + 1024) {
+ char buf[512];
+ (void)snprintf(buf, sizeof(buf), "%zu.%zu", i, i + 1);
+
+ errno = 0;
+ double d = strtod(buf, NULL);
+
+ ATF_REQUIRE(d > 0.0);
+ ATF_REQUIRE(errno == 0);
+ }
+}
+
+ATF_TC(strtod_hex);
+ATF_TC_HEAD(strtod_hex, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtod(3) with hexadecimals");
+}
+
+#ifdef __vax__
+#define SMALL_NUM 1.0e-38
+#else
+#define SMALL_NUM 1.0e-40
+#endif
+
+ATF_TC_BODY(strtod_hex, tc)
+{
+ const char *str;
+ char *end;
+ volatile double d;
+
+ str = "-0x0";
+ d = strtod(str, &end); /* -0.0 */
+
+ ATF_REQUIRE(end == str + 4);
+ ATF_REQUIRE(signbit(d) != 0);
+ ATF_REQUIRE(fabs(d) < SMALL_NUM);
+
+ str = "-0x";
+ d = strtod(str, &end); /* -0.0 */
+
+ ATF_REQUIRE(end == str + 2);
+ ATF_REQUIRE(signbit(d) != 0);
+ ATF_REQUIRE(fabs(d) < SMALL_NUM);
+}
+
+ATF_TC(strtod_inf);
+ATF_TC_HEAD(strtod_inf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtod(3) with INF (PR lib/33262)");
+}
+
+ATF_TC_BODY(strtod_inf, tc)
+{
+#ifndef __vax__
+ for (size_t i = 0; i < __arraycount(inf_strings); i++) {
+ volatile double d = strtod(inf_strings[i], NULL);
+ ATF_REQUIRE(isinf(d) != 0);
+ }
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtof_inf);
+ATF_TC_HEAD(strtof_inf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtof(3) with INF (PR lib/33262)");
+}
+
+ATF_TC_BODY(strtof_inf, tc)
+{
+#ifndef __vax__
+ for (size_t i = 0; i < __arraycount(inf_strings); i++) {
+ volatile float f = strtof(inf_strings[i], NULL);
+ ATF_REQUIRE(isinf(f) != 0);
+ }
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtold_inf);
+ATF_TC_HEAD(strtold_inf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtold(3) with INF (PR lib/33262)");
+}
+
+ATF_TC_BODY(strtold_inf, tc)
+{
+#ifndef __vax__
+# ifdef __HAVE_LONG_DOUBLE
+
+ for (size_t i = 0; i < __arraycount(inf_strings); i++) {
+ volatile long double ld = strtold(inf_strings[i], NULL);
+ ATF_REQUIRE(isinf(ld) != 0);
+ }
+# else
+ atf_tc_skip("Requires long double support");
+# endif
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtod_nan);
+ATF_TC_HEAD(strtod_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtod(3) with NaN");
+}
+
+ATF_TC_BODY(strtod_nan, tc)
+{
+#ifndef __vax__
+ char *end;
+
+ volatile double d = strtod(nan_string, &end);
+ ATF_REQUIRE(isnan(d) != 0);
+ ATF_REQUIRE(strcmp(end, "y") == 0);
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtof_nan);
+ATF_TC_HEAD(strtof_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtof(3) with NaN");
+}
+
+ATF_TC_BODY(strtof_nan, tc)
+{
+#ifndef __vax__
+ char *end;
+
+ volatile float f = strtof(nan_string, &end);
+ ATF_REQUIRE(isnanf(f) != 0);
+ ATF_REQUIRE(strcmp(end, "y") == 0);
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtold_nan);
+ATF_TC_HEAD(strtold_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A strtold(3) with NaN (PR lib/45020)");
+}
+
+ATF_TC_BODY(strtold_nan, tc)
+{
+#ifndef __vax__
+# ifdef __HAVE_LONG_DOUBLE
+
+ char *end;
+
+ volatile long double ld = strtold(nan_string, &end);
+ ATF_REQUIRE(isnan(ld) != 0);
+#ifdef __FreeBSD__
+ ATF_REQUIRE(strcmp(end, "y") == 0);
+#else
+ ATF_REQUIRE(__isnanl(ld) != 0);
+#endif
+ ATF_REQUIRE(strcmp(end, "y") == 0);
+# else
+ atf_tc_skip("Requires long double support");
+# endif
+#else
+ atf_tc_skip("vax not supported");
+#endif
+}
+
+ATF_TC(strtod_round);
+ATF_TC_HEAD(strtod_round, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test rouding in strtod(3)");
+}
+
+ATF_TC_BODY(strtod_round, tc)
+{
+#if defined(__i386__) || defined(__amd64__) || defined(__sparc__)
+
+ /*
+ * Test that strtod(3) honors the current rounding mode.
+ * The used value is somewhere near 1 + DBL_EPSILON + FLT_EPSILON.
+ */
+ const char *val =
+ "1.00000011920928977282585492503130808472633361816406";
+
+ (void)fesetround(FE_UPWARD);
+
+ volatile double d1 = strtod(val, NULL);
+
+ (void)fesetround(FE_DOWNWARD);
+
+ volatile double d2 = strtod(val, NULL);
+
+ if (fabs(d1 - d2) > 0.0)
+ return;
+ else {
+ atf_tc_expect_fail("PR misc/44767");
+ atf_tc_fail("strtod(3) did not honor fesetround(3)");
+ }
+#else
+ atf_tc_skip("Requires one of i386, amd64 or sparc");
+#endif
+}
+
+ATF_TC(strtod_underflow);
+ATF_TC_HEAD(strtod_underflow, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test underflow in strtod(3)");
+}
+
+ATF_TC_BODY(strtod_underflow, tc)
+{
+
+ const char *tmp =
+ "0.0000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000000000000000000000000000000000000000000"
+ "000000000000000002";
+
+ errno = 0;
+ volatile double d = strtod(tmp, NULL);
+
+ if (d != 0 || errno != ERANGE)
+ atf_tc_fail("strtod(3) did not detect underflow");
+}
+
+/*
+ * Bug found by Geza Herman.
+ * See
+ * http://www.exploringbinary.com/a-bug-in-the-bigcomp-function-of-david-gays-strtod/
+ */
+ATF_TC(strtod_gherman_bug);
+ATF_TC_HEAD(strtod_gherman_bug, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test a bug found by Geza Herman");
+}
+
+ATF_TC_BODY(strtod_gherman_bug, tc)
+{
+
+ const char *str =
+ "1.8254370818746402660437411213933955878019332885742187";
+
+ errno = 0;
+ volatile double d = strtod(str, NULL);
+
+ ATF_CHECK(d == 0x1.d34fd8378ea83p+0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, strtod_basic);
+ ATF_TP_ADD_TC(tp, strtod_hex);
+ ATF_TP_ADD_TC(tp, strtod_inf);
+ ATF_TP_ADD_TC(tp, strtof_inf);
+ ATF_TP_ADD_TC(tp, strtold_inf);
+ ATF_TP_ADD_TC(tp, strtod_nan);
+ ATF_TP_ADD_TC(tp, strtof_nan);
+ ATF_TP_ADD_TC(tp, strtold_nan);
+ ATF_TP_ADD_TC(tp, strtod_round);
+ ATF_TP_ADD_TC(tp, strtod_underflow);
+ ATF_TP_ADD_TC(tp, strtod_gherman_bug);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c b/contrib/netbsd-tests/lib/libc/stdlib/t_strtol.c
new file mode 100644
index 000000000000..5a0c6d0e51ea
--- /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 000000000000..235005bc809f
--- /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 000000000000..5ec402297538
--- /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 000000000000..296f1f81e219
--- /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 000000000000..192a4e81f7ed
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_memcpy.c
@@ -0,0 +1,162 @@
+/* $NetBSD: t_memcpy.c,v 1.5 2013/03/17 02:23:31 christos Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <md5.h>
+
+#include <sys/types.h>
+
+#define ALIGNMENTS 16
+#define LENGTHS 4
+#define BLOCKTYPES 4
+
+MD5_CTX mc[1];
+
+typedef unsigned char testBlock_t[ALIGNMENTS * LENGTHS];
+
+testBlock_t bss1, bss2;
+
+unsigned char *start[BLOCKTYPES] = {
+ bss1, bss2
+};
+
+char result[100];
+#ifdef __NetBSD__
+const char goodResult[] = "7b405d24bc03195474c70ddae9e1f8fb";
+#else
+const char goodResult[] = "217b4fbe456916bf62a2f85df752e4ab";
+#endif
+
+static void
+runTest(unsigned char *b1, unsigned char *b2)
+{
+ int i, j, k, m;
+ size_t n;
+
+ for (i = 0; i < ALIGNMENTS; ++i) {
+ for (j = 0; j < ALIGNMENTS; ++j) {
+ k = sizeof(testBlock_t) - (i > j ? i : j);
+ for (m = 0; m < k; ++m) {
+ for (n = 0; n < sizeof(testBlock_t); ++n) {
+ b1[n] = (unsigned char)random();
+ b2[n] = (unsigned char)random();
+ }
+ memcpy(b1 + i, b2 + j, m);
+ MD5Update(mc, b1, sizeof(testBlock_t));
+ MD5Update(mc, b2, sizeof(testBlock_t));
+ }
+ }
+ }
+}
+
+ATF_TC(memcpy_basic);
+ATF_TC_HEAD(memcpy_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memcpy results");
+}
+
+ATF_TC_BODY(memcpy_basic, tc)
+{
+ int i, j;
+ testBlock_t auto1, auto2;
+
+ start[2] = auto1;
+ start[3] = auto2;
+
+#ifdef __NetBSD__
+ srandom(0L);
+#else
+ /*
+ * random() shall produce by default a sequence of numbers that can be
+ * duplicated by calling srandom() with 1 as the seed.
+ */
+ srandom(1);
+#endif
+ MD5Init(mc);
+ for (i = 0; i < BLOCKTYPES; ++i)
+ for (j = 0; j < BLOCKTYPES; ++j)
+ if (i != j)
+ runTest(start[i], start[j]);
+ MD5End(mc, result);
+ ATF_REQUIRE_EQ(strcmp(result, goodResult), 0);
+}
+
+ATF_TC(memccpy_simple);
+ATF_TC_HEAD(memccpy_simple, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memccpy(3) results");
+}
+
+ATF_TC_BODY(memccpy_simple, tc)
+{
+ char buf[100];
+ char c = ' ';
+
+ (void)memset(buf, c, sizeof(buf));
+
+ ATF_CHECK(memccpy(buf, "foo bar", c, sizeof(buf)) != NULL);
+ ATF_CHECK(buf[4] == c);
+
+ ATF_CHECK(memccpy(buf, "foo bar", '\0', sizeof(buf) - 1) != NULL);
+ ATF_CHECK(buf[8] == c);
+
+ ATF_CHECK(memccpy(buf, "foo bar", 'x', 7) == NULL);
+ ATF_CHECK(strncmp(buf, "foo bar", 7) == 0);
+
+ ATF_CHECK(memccpy(buf, "xxxxxxx", 'r', 7) == NULL);
+ ATF_CHECK(strncmp(buf, "xxxxxxx", 7) == 0);
+}
+
+ATF_TC(memcpy_return);
+ATF_TC_HEAD(memcpy_return, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test memcpy(3) return value");
+}
+
+ATF_TC_BODY(memcpy_return, tc)
+{
+ char *b = (char *)0x1;
+ char c[2];
+ ATF_REQUIRE_EQ(memcpy(b, b, 0), b);
+ ATF_REQUIRE_EQ(memcpy(c, "ab", sizeof(c)), c);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, memcpy_basic);
+ ATF_TP_ADD_TC(tp, memcpy_return);
+ ATF_TP_ADD_TC(tp, memccpy_simple);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_memmem.c b/contrib/netbsd-tests/lib/libc/string/t_memmem.c
new file mode 100644
index 000000000000..8734bc3a955d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_memmem.c
@@ -0,0 +1,105 @@
+/* $NetBSD: t_memmem.c,v 1.2 2011/07/07 08:27:36 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2005 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Perry E. Metzger of Metzger, Dowdeswell & Co. LLC.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+char p0[] = "";
+int lp0 = 0;
+char p1[] = "0123";
+int lp1 = 4;
+char p2[] = "456";
+int lp2 = 3;
+char p3[] = "789";
+int lp3 = 3;
+char p4[] = "abc";
+int lp4 = 3;
+char p5[] = "0";
+int lp5 = 1;
+char p6[] = "9";
+int lp6 = 1;
+char p7[] = "654";
+int lp7 = 3;
+
+char b0[] = "";
+int lb0 = 0;
+char b1[] = "0";
+int lb1 = 1;
+char b2[] = "0123456789";
+int lb2 = 10;
+
+#define expect(b) \
+ if (!(b)) { \
+ fprintf(stderr, "failed on line %d\n", __LINE__); \
+ atf_tc_fail("Check stderr for test id/line"); \
+ }
+
+ATF_TC(memmem_basic);
+ATF_TC_HEAD(memmem_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Test memmem results");
+}
+
+ATF_TC_BODY(memmem_basic, tc)
+{
+
+#if defined(__darwin__) || defined(__FreeBSD__)
+ expect(memmem(b2, lb2, p0, lp0) == NULL);
+ expect(memmem(b0, lb0, p0, lp0) == NULL);
+#else
+ expect(memmem(b2, lb2, p0, lp0) == b2);
+ expect(memmem(b0, lb0, p0, lp0) == b0);
+#endif
+ expect(memmem(b0, lb0, p1, lp1) == NULL);
+ expect(memmem(b1, lb1, p1, lp1) == NULL);
+
+ expect(memmem(b2, lb2, p1, lp1) == b2);
+ expect(memmem(b2, lb2, p2, lp2) == (b2 + 4));
+ expect(memmem(b2, lb2, p3, lp3) == (b2 + 7));
+
+ expect(memmem(b2, lb2, p5, lp5) == b2);
+ expect(memmem(b2, lb2, p6, lp6) == (b2 + 9));
+
+ expect(memmem(b2, lb2, p4, lp4) == NULL);
+ expect(memmem(b2, lb2, p7, lp7) == NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, memmem_basic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_memset.c b/contrib/netbsd-tests/lib/libc/string/t_memset.c
new file mode 100644
index 000000000000..c1fb3855e076
--- /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 000000000000..2bae52f6e89b
--- /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 000000000000..bd98691da6dc
--- /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 000000000000..958b186e9ceb
--- /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 000000000000..14e2e9ce935d
--- /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 000000000000..285371ec072f
--- /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 000000000000..d38cdb43939c
--- /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 000000000000..888a8261f8d5
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/string/t_strerror.c
@@ -0,0 +1,139 @@
+/* $NetBSD: t_strerror.c,v 1.3 2011/05/10 06:55:27 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_strerror.c,v 1.3 2011/05/10 06:55:27 jruoho Exp $");
+
+#include <atf-c.h>
+#include <errno.h>
+#include <limits.h>
+#include <locale.h>
+#include <string.h>
+
+#ifdef __FreeBSD__
+#include <stdio.h>
+#endif
+
+ATF_TC(strerror_basic);
+ATF_TC_HEAD(strerror_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of strerror(3)");
+}
+
+ATF_TC_BODY(strerror_basic, tc)
+{
+ int i;
+
+ for (i = 1; i < sys_nerr; i++)
+ ATF_REQUIRE(strstr(strerror(i), "Unknown error:") == NULL);
+
+ for (; i < sys_nerr + 10; i++)
+ ATF_REQUIRE(strstr(strerror(i), "Unknown error:") != NULL);
+}
+
+ATF_TC(strerror_err);
+ATF_TC_HEAD(strerror_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from strerror(3)");
+}
+
+ATF_TC_BODY(strerror_err, tc)
+{
+
+ errno = 0;
+
+ ATF_REQUIRE(strstr(strerror(INT_MAX), "Unknown error:") != NULL);
+ ATF_REQUIRE(errno == EINVAL);
+
+ errno = 0;
+
+ ATF_REQUIRE(strstr(strerror(INT_MIN), "Unknown error:") != NULL);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+ATF_TC(strerror_r_basic);
+ATF_TC_HEAD(strerror_r_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of strerror_r(3)");
+}
+
+ATF_TC_BODY(strerror_r_basic, tc)
+{
+ char buf[512];
+ int i;
+
+ for (i = 1; i < sys_nerr; i++) {
+ ATF_REQUIRE(strerror_r(i, buf, sizeof(buf)) == 0);
+ ATF_REQUIRE(strstr(buf, "Unknown error:") == NULL);
+ }
+
+ for (; i < sys_nerr + 10; i++) {
+ ATF_REQUIRE(strerror_r(i, buf, sizeof(buf)) == EINVAL);
+ ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL);
+ }
+}
+
+ATF_TC(strerror_r_err);
+ATF_TC_HEAD(strerror_r_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from strerror_r(3)");
+}
+
+ATF_TC_BODY(strerror_r_err, tc)
+{
+ char buf[512];
+ int rv;
+
+ rv = strerror_r(EPERM, buf, 1);
+ ATF_REQUIRE(rv == ERANGE);
+
+ rv = strerror_r(INT_MAX, buf, sizeof(buf));
+
+ ATF_REQUIRE(rv == EINVAL);
+ ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL);
+
+ rv = strerror_r(INT_MIN, buf, sizeof(buf));
+
+ ATF_REQUIRE(rv == EINVAL);
+ ATF_REQUIRE(strstr(buf, "Unknown error:") != NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ (void)setlocale(LC_ALL, "C");
+
+ ATF_TP_ADD_TC(tp, strerror_basic);
+ ATF_TP_ADD_TC(tp, strerror_err);
+ ATF_TP_ADD_TC(tp, strerror_r_basic);
+ ATF_TP_ADD_TC(tp, strerror_r_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/string/t_stresep.c b/contrib/netbsd-tests/lib/libc/string/t_stresep.c
new file mode 100644
index 000000000000..4678e55c0eeb
--- /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 000000000000..66158fd7113f
--- /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 000000000000..d0f2d9b5d0be
--- /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 000000000000..038daff953ae
--- /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 000000000000..6782181b079b
--- /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 000000000000..797397a79a15
--- /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 000000000000..0f2068a3d0cb
--- /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 000000000000..b8b399e7ee20
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_access.c
@@ -0,0 +1,214 @@
+/* $NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_access.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#ifdef __FreeBSD__
+#include <sys/stat.h>
+#endif
+
+static const char path[] = "access";
+static const int mode[4] = { R_OK, W_OK, X_OK, F_OK };
+
+ATF_TC_WITH_CLEANUP(access_access);
+ATF_TC_HEAD(access_access, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test access(2) for EACCES");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(access_access, tc)
+{
+ const int perm[3] = { 0200, 0400, 0000 };
+ size_t i;
+ int fd;
+
+ fd = open(path, O_RDONLY | O_CREAT);
+
+ if (fd < 0)
+ return;
+
+ for (i = 0; i < __arraycount(mode) - 1; i++) {
+
+ ATF_REQUIRE(fchmod(fd, perm[i]) == 0);
+
+ errno = 0;
+
+ ATF_REQUIRE(access(path, mode[i]) != 0);
+ ATF_REQUIRE(errno == EACCES);
+ }
+
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC_CLEANUP(access_access, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(access_fault);
+ATF_TC_HEAD(access_fault, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test access(2) for EFAULT");
+}
+
+ATF_TC_BODY(access_fault, tc)
+{
+ size_t i;
+
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ errno = 0;
+
+ ATF_REQUIRE(access(NULL, mode[i]) != 0);
+ ATF_REQUIRE(errno == EFAULT);
+
+ errno = 0;
+
+ ATF_REQUIRE(access((char *)-1, mode[i]) != 0);
+ ATF_REQUIRE(errno == EFAULT);
+ }
+}
+
+ATF_TC(access_inval);
+ATF_TC_HEAD(access_inval, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test access(2) for EINVAL");
+}
+
+ATF_TC_BODY(access_inval, tc)
+{
+
+ 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 000000000000..651dc10201f3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_chroot.c
@@ -0,0 +1,321 @@
+/* $NetBSD: t_chroot.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_chroot.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <sys/stat.h>
+#endif
+
+ATF_TC(chroot_basic);
+ATF_TC_HEAD(chroot_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of chroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(chroot_basic, tc)
+{
+ char buf[PATH_MAX];
+ int fd, sta;
+ pid_t pid;
+
+ (void)memset(buf, '\0', sizeof(buf));
+ (void)getcwd(buf, sizeof(buf));
+ (void)strlcat(buf, "/dir", sizeof(buf));
+
+ ATF_REQUIRE(mkdir(buf, 0500) == 0);
+ ATF_REQUIRE(chdir(buf) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (chroot(buf) != 0)
+ _exit(EXIT_FAILURE);
+
+ errno = 0;
+
+ if (chroot("/root") != -1)
+ _exit(EXIT_FAILURE);
+
+ if (errno != ENOENT)
+ _exit(EXIT_FAILURE);
+
+ fd = open("file", O_RDONLY | O_CREAT, 0600);
+
+ if (fd < 0)
+ _exit(EXIT_FAILURE);
+
+ if (close(fd) != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("chroot(2) failed");
+
+ (void)chdir("/");
+ (void)strlcat(buf, "/file", sizeof(buf));
+
+ fd = open(buf, O_RDONLY);
+
+ if (fd < 0)
+ atf_tc_fail("chroot(2) did not change the root directory");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(buf) == 0);
+}
+
+ATF_TC(chroot_err);
+ATF_TC_HEAD(chroot_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of chroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(chroot_err, tc)
+{
+ char buf[PATH_MAX + 1];
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, chroot(buf) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, chroot((void *)-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, chroot("/a/b/c/d/e/f/g/h/i/j") == -1);
+}
+
+ATF_TC(chroot_perm);
+ATF_TC_HEAD(chroot_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with chroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(chroot_perm, tc)
+{
+ static char buf[LINE_MAX];
+ pid_t pid;
+ int sta;
+
+ (void)memset(buf, '\0', sizeof(buf));
+ ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ errno = 0;
+
+ if (chroot(buf) != -1)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EPERM)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("chroot(2) succeeded as unprivileged user");
+}
+
+#ifdef __NetBSD__
+ATF_TC(fchroot_basic);
+ATF_TC_HEAD(fchroot_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of fchroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(fchroot_basic, tc)
+{
+ char buf[PATH_MAX];
+ int fd, sta;
+ pid_t pid;
+
+ (void)memset(buf, '\0', sizeof(buf));
+ (void)getcwd(buf, sizeof(buf));
+ (void)strlcat(buf, "/dir", sizeof(buf));
+
+ ATF_REQUIRE(mkdir(buf, 0500) == 0);
+ ATF_REQUIRE(chdir(buf) == 0);
+
+ fd = open(buf, O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (fchroot(fd) != 0)
+ _exit(EXIT_FAILURE);
+
+ if (close(fd) != 0)
+ _exit(EXIT_FAILURE);
+
+ fd = open("file", O_RDONLY | O_CREAT, 0600);
+
+ if (fd < 0)
+ _exit(EXIT_FAILURE);
+
+ if (close(fd) != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("fchroot(2) failed");
+
+ (void)chdir("/");
+ (void)strlcat(buf, "/file", sizeof(buf));
+
+ fd = open(buf, O_RDONLY);
+
+ if (fd < 0)
+ atf_tc_fail("fchroot(2) did not change the root directory");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(buf) == 0);
+}
+
+ATF_TC(fchroot_err);
+ATF_TC_HEAD(fchroot_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of fchroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(fchroot_err, tc)
+{
+ int fd;
+
+ fd = open("/etc/passwd", O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fchroot(-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOTDIR, fchroot(fd) == -1);
+
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC(fchroot_perm);
+ATF_TC_HEAD(fchroot_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with fchroot(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(fchroot_perm, tc)
+{
+ static char buf[LINE_MAX];
+ struct passwd *pw;
+ int fd, sta;
+ pid_t pid;
+
+ (void)memset(buf, '\0', sizeof(buf));
+ ATF_REQUIRE(getcwd(buf, sizeof(buf)) != NULL);
+
+ pw = getpwnam("nobody");
+ fd = open(buf, O_RDONLY);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(pw != NULL);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ (void)setuid(pw->pw_uid);
+
+ errno = 0;
+
+ if (fchroot(fd) != -1)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EPERM)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("fchroot(2) succeeded as unprivileged user");
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, chroot_basic);
+ ATF_TP_ADD_TC(tp, chroot_err);
+ ATF_TP_ADD_TC(tp, chroot_perm);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, fchroot_basic);
+ ATF_TP_ADD_TC(tp, fchroot_err);
+ ATF_TP_ADD_TC(tp, fchroot_perm);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c
new file mode 100644
index 000000000000..229c343c7a8b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_clock_gettime.c
@@ -0,0 +1,220 @@
+/* $NetBSD: t_clock_gettime.c,v 1.1 2011/10/15 06:42:16 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Frank Kardel.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 2006 Frank Kardel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_clock_gettime.c,v 1.1 2011/10/15 06:42:16 jruoho Exp $");
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#ifdef __NetBSD__
+#include <machine/int_limits.h>
+#endif
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef __NetBSD__
+#include "../../../h_macros.h"
+#else
+#include <limits.h>
+#include <stdint.h>
+#include "h_macros.h"
+#endif
+
+#define MINPOSDIFF 15000000 /* 15 ms for now */
+#define TIMEOUT 5
+
+#define TC_HARDWARE "kern.timecounter.hardware"
+#define TC_CHOICE "kern.timecounter.choice"
+
+static void
+check_timecounter(void)
+{
+ struct timespec tsa, tsb, tsl, res;
+ long long mindiff = INTMAX_MAX;
+ time_t endlimit;
+
+#define CL(x) \
+ do { \
+ if ((x) != -1) \
+ break; \
+ atf_tc_fail_nonfatal("%s: %s", #x, strerror(errno)); \
+ return; \
+ } while (0)
+
+ CL(clock_gettime(CLOCK_REALTIME, &tsa));
+ tsl = tsa;
+
+ CL(time(&endlimit));
+ endlimit += TIMEOUT + 1;
+
+ while ((time_t)tsa.tv_sec < endlimit) {
+ long long diff;
+
+ CL(clock_gettime(CLOCK_REALTIME, &tsb));
+ diff = 1000000000LL * (tsb.tv_sec - tsa.tv_sec)
+ + tsb.tv_nsec - tsa.tv_nsec;
+
+ if (diff > 0 && mindiff > diff)
+ mindiff = diff;
+
+ if (diff < 0 || diff > MINPOSDIFF) {
+ long long elapsed;
+ (void)printf("%stime TSA: 0x%jx.%08jx, TSB: 0x%jx.%08jx, "
+ "diff = %lld nsec, ", (diff < 0) ? "BAD " : "",
+ (uintmax_t)tsa.tv_sec, (uintmax_t)tsa.tv_nsec,
+ (uintmax_t)tsb.tv_sec, (uintmax_t)tsb.tv_nsec, diff);
+
+ elapsed = 1000000000LL * (tsb.tv_sec - tsl.tv_sec)
+ + tsb.tv_nsec - tsl.tv_nsec;
+
+
+ (void)printf("%lld nsec\n", elapsed);
+ tsl = tsb;
+
+ ATF_CHECK(diff >= 0);
+ if (diff < 0)
+ return;
+ }
+
+ tsa.tv_sec = tsb.tv_sec;
+ tsa.tv_nsec = tsb.tv_nsec;
+ }
+
+ if (clock_getres(CLOCK_REALTIME, &res) == 0) {
+ long long r = res.tv_sec * 1000000000 + res.tv_nsec;
+
+ (void)printf("Claimed resolution: %lld nsec (%f Hz) or "
+ "better\n", r, 1.0 / r * 1e9);
+ (void)printf("Observed minimum non zero delta: %lld "
+ "nsec\n", mindiff);
+ }
+
+#undef CL
+}
+
+ATF_TC(clock_gettime_real);
+ATF_TC_HEAD(clock_gettime_real, tc)
+{
+ atf_tc_set_md_var(tc, "require.user", "root");
+ atf_tc_set_md_var(tc, "descr",
+ "Checks the monotonicity of the CLOCK_REALTIME implementation");
+ atf_tc_set_md_var(tc, "timeout", "300");
+}
+
+ATF_TC_BODY(clock_gettime_real, tc)
+{
+ char name[128], cbuf[512], ctrbuf[10240];
+ size_t cbufsiz = sizeof(cbuf);
+ size_t ctrbufsiz = sizeof(ctrbuf);
+ const char *p;
+ char *save;
+ int quality, n;
+
+ if (sysctlbyname(TC_HARDWARE, cbuf, &cbufsiz, NULL, 0) != 0) {
+ (void)printf("\nChecking legacy time implementation "
+ "for %d seconds\n", TIMEOUT);
+ check_timecounter();
+ return;
+ /* NOTREACHED */
+ }
+ (void)printf("%s = %s\n", TC_HARDWARE, cbuf);
+ REQUIRE_LIBC(save = strdup(cbuf), NULL);
+
+ RL(sysctlbyname(TC_CHOICE, ctrbuf, &ctrbufsiz, NULL, 0));
+ (void)printf("%s = %s\n", TC_CHOICE, ctrbuf);
+
+ for (p = ctrbuf, n = 0; sscanf(p, "%127[^(](q=%d, f=%*u Hz)%*[ ]%n",
+ name, &quality, &n) == 2; p += n) {
+ struct timespec ts;
+ int ret;
+
+ if (quality < 0)
+ continue;
+
+ (void)printf("\nChecking %s for %d seconds\n", name, TIMEOUT);
+ CHECK_LIBC(ret = sysctlbyname(TC_HARDWARE, NULL, 0,
+ name, strlen(name)), -1);
+ if (ret == -1)
+ continue;
+
+ /* wait a bit to select new counter in clockinterrupt */
+ ts.tv_sec = 0;
+ ts.tv_nsec = 100000000;
+ (void)nanosleep(&ts, NULL);
+
+ check_timecounter();
+ }
+
+ RL(sysctlbyname(TC_HARDWARE, NULL, 0, save, strlen(save)));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, clock_gettime_real);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_clone.c b/contrib/netbsd-tests/lib/libc/sys/t_clone.c
new file mode 100644
index 000000000000..ea33f321ea0e
--- /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 000000000000..e49220649855
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_connect.c
@@ -0,0 +1,103 @@
+/* $NetBSD: t_connect.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $ */
+/*
+ * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include <atf-c.h>
+
+#ifdef __FreeBSD__
+#include <sys/socket.h>
+#endif
+
+ATF_TC(connect_low_port);
+ATF_TC_HEAD(connect_low_port, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that low-port allocation "
+ "works");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+ATF_TC_BODY(connect_low_port, tc)
+{
+ struct sockaddr_in sin, sinlist;
+ int sd, val, slist;
+ socklen_t slen;
+
+ slist = socket(AF_INET, SOCK_STREAM, 0);
+ sd = socket(AF_INET, SOCK_STREAM, 0);
+
+ /* bind listening socket */
+ memset(&sinlist, 0, sizeof(sinlist));
+ sinlist.sin_family = AF_INET;
+ sinlist.sin_port = htons(31522);
+ sinlist.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ ATF_REQUIRE_EQ(bind(slist,
+ (struct sockaddr *)&sinlist, sizeof(sinlist)), 0);
+ ATF_REQUIRE_EQ(listen(slist, 1), 0);
+
+ val = IP_PORTRANGE_LOW;
+ if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val,
+ sizeof(val)) == -1)
+ atf_tc_fail("setsockopt failed: %s", strerror(errno));
+
+ memset(&sin, 0, sizeof(sin));
+
+ sin.sin_port = htons(31522);
+ sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+ sin.sin_family = AF_INET;
+
+ if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
+ int serrno = errno;
+ atf_tc_fail("connect failed: %s%s",
+ strerror(serrno),
+ serrno != EACCES ? "" :
+ " (see http://mail-index.netbsd.org/"
+ "source-changes/2007/12/16/0011.html)");
+ }
+
+ slen = sizeof(sin);
+ ATF_REQUIRE_EQ(getsockname(sd, (struct sockaddr *)&sin, &slen), 0);
+ ATF_REQUIRE_EQ(slen, sizeof(sin));
+ ATF_REQUIRE(ntohs(sin.sin_port) <= IPPORT_RESERVEDMAX);
+
+ close(sd);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, connect_low_port);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_dup.c b/contrib/netbsd-tests/lib/libc/sys/t_dup.c
new file mode 100644
index 000000000000..d8125ab33531
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_dup.c
@@ -0,0 +1,405 @@
+/* $NetBSD: t_dup.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_dup.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $");
+
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sysexits.h>
+
+#ifdef __FreeBSD__
+#include <stdbool.h>
+#endif
+
+static char path[] = "dup";
+#ifdef __NetBSD__
+static void check_mode(bool, bool, bool);
+#endif
+
+static void
+check_mode(bool _dup, bool _dup2, bool _dup3)
+{
+ int mode[3] = { O_RDONLY, O_WRONLY, O_RDWR };
+ int perm[5] = { 0700, 0400, 0600, 0444, 0666 };
+ struct stat st, st1;
+ int fd, fd1, fd2;
+ size_t i, j;
+
+ /*
+ * Check that a duplicated descriptor
+ * retains the mode of the original file.
+ */
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ for (j = 0; j < __arraycount(perm); j++) {
+
+ fd1 = open(path, mode[i] | O_CREAT, perm[j]);
+ fd2 = open("/etc/passwd", O_RDONLY);
+
+ ATF_REQUIRE(fd1 >= 0);
+ ATF_REQUIRE(fd2 >= 0);
+
+ if (_dup != false)
+ fd = dup(fd1);
+ else if (_dup2 != false)
+ fd = dup2(fd1, fd2);
+ else if (_dup3 != false)
+ fd = dup3(fd1, fd2, O_CLOEXEC);
+ else {
+ fd = -1;
+ }
+
+ ATF_REQUIRE(fd >= 0);
+
+ (void)memset(&st, 0, sizeof(struct stat));
+ (void)memset(&st1, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(fstat(fd, &st) == 0);
+ ATF_REQUIRE(fstat(fd1, &st1) == 0);
+
+ if (st.st_mode != st1.st_mode)
+ atf_tc_fail("invalid mode");
+
+ (void)close(fd);
+ (void)close(fd1);
+ (void)close(fd2);
+ (void)unlink(path);
+ }
+ }
+}
+
+ATF_TC(dup2_basic);
+ATF_TC_HEAD(dup2_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)");
+}
+
+ATF_TC_BODY(dup2_basic, tc)
+{
+ int fd, fd1, fd2;
+
+ fd1 = open("/etc/passwd", O_RDONLY);
+ fd2 = open("/etc/passwd", O_RDONLY);
+
+ ATF_REQUIRE(fd1 >= 0);
+ ATF_REQUIRE(fd2 >= 0);
+
+ fd = dup2(fd1, fd2);
+ ATF_REQUIRE(fd >= 0);
+
+ if (fd != fd2)
+ atf_tc_fail("invalid descriptor");
+
+ (void)close(fd);
+ (void)close(fd1);
+
+ ATF_REQUIRE(close(fd2) != 0);
+}
+
+ATF_TC(dup2_err);
+ATF_TC_HEAD(dup2_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of dup2(2)");
+}
+
+ATF_TC_BODY(dup2_err, tc)
+{
+ int fd;
+
+ fd = open("/etc/passwd", O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup2(-1, -1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup2(fd, -1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup2(-1, fd) == -1);
+
+ /*
+ * Note that this should not fail with EINVAL.
+ */
+ ATF_REQUIRE(dup2(fd, fd) != -1);
+
+ (void)close(fd);
+}
+
+ATF_TC(dup2_max);
+ATF_TC_HEAD(dup2_max, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test dup2(2) against limits");
+}
+
+ATF_TC_BODY(dup2_max, tc)
+{
+ struct rlimit res;
+
+ (void)memset(&res, 0, sizeof(struct rlimit));
+ (void)getrlimit(RLIMIT_NOFILE, &res);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup2(STDERR_FILENO, res.rlim_cur + 1) == -1);
+}
+
+ATF_TC_WITH_CLEANUP(dup2_mode);
+ATF_TC_HEAD(dup2_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)");
+}
+
+ATF_TC_BODY(dup2_mode, tc)
+{
+ check_mode(false, true, false);
+}
+
+ATF_TC_CLEANUP(dup2_mode, tc)
+{
+ (void)unlink(path);
+}
+
+
+ATF_TC(dup3_err);
+ATF_TC_HEAD(dup3_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test error conditions of dup3(2) (PR lib/45148)");
+}
+
+ATF_TC_BODY(dup3_err, tc)
+{
+ int fd;
+
+ fd = open("/etc/passwd", O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+#if defined(__FreeBSD__) || defined(__linux__)
+ /*
+ * FreeBSD and linux return EINVAL, because...
+ *
+ * [EINVAL] The oldd argument is equal to the newd argument.
+ */
+ ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) == -1);
+#else
+ ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) != -1);
+#endif
+
+ errno = 0;
+#if defined(__FreeBSD__) || defined(__linux__)
+ ATF_REQUIRE_ERRNO(EINVAL, dup3(-1, -1, O_CLOEXEC) == -1);
+ ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1);
+#else
+ ATF_REQUIRE_ERRNO(EBADF, dup3(-1, -1, O_CLOEXEC) == -1);
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup3(-1, fd, O_CLOEXEC) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, dup3(fd, 1, O_NOFOLLOW) == -1);
+
+ (void)close(fd);
+}
+
+ATF_TC(dup3_max);
+ATF_TC_HEAD(dup3_max, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test dup3(2) against limits");
+}
+
+ATF_TC_BODY(dup3_max, tc)
+{
+ struct rlimit res;
+
+ (void)memset(&res, 0, sizeof(struct rlimit));
+ (void)getrlimit(RLIMIT_NOFILE, &res);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup3(STDERR_FILENO,
+ res.rlim_cur + 1, O_CLOEXEC) == -1);
+}
+
+ATF_TC_WITH_CLEANUP(dup3_mode);
+ATF_TC_HEAD(dup3_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of dup3(2)");
+}
+
+ATF_TC_BODY(dup3_mode, tc)
+{
+ check_mode(false, false, true);
+}
+
+ATF_TC_CLEANUP(dup3_mode, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(dup_err);
+ATF_TC_HEAD(dup_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of dup(2)");
+}
+
+ATF_TC_BODY(dup_err, tc)
+{
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup(-1) == -1);
+}
+
+ATF_TC_WITH_CLEANUP(dup_max);
+ATF_TC_HEAD(dup_max, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test dup(2) against limits");
+}
+
+ATF_TC_BODY(dup_max, tc)
+{
+ struct rlimit res;
+ int *buf, fd, sta;
+ size_t i, n;
+ pid_t pid;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * Open a temporary file until the
+ * maximum number of open files is
+ * reached. Ater that dup(2) family
+ * should fail with EMFILE.
+ */
+ (void)closefrom(0);
+ (void)memset(&res, 0, sizeof(struct rlimit));
+
+ n = 10;
+ res.rlim_cur = res.rlim_max = n;
+ if (setrlimit(RLIMIT_NOFILE, &res) != 0)
+ _exit(EX_OSERR);
+
+ buf = calloc(n, sizeof(int));
+
+ if (buf == NULL)
+ _exit(EX_OSERR);
+
+ buf[0] = mkstemp(path);
+
+ if (buf[0] < 0)
+ _exit(EX_OSERR);
+
+ for (i = 1; i < n; i++) {
+
+ buf[i] = open(path, O_RDONLY);
+
+ if (buf[i] < 0)
+ _exit(EX_OSERR);
+ }
+
+ errno = 0;
+ fd = dup(buf[0]);
+
+ if (fd != -1 || errno != EMFILE)
+ _exit(EX_DATAERR);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
+
+ if (WEXITSTATUS(sta) == EX_OSERR)
+ atf_tc_fail("system call error");
+
+ if (WEXITSTATUS(sta) == EX_DATAERR)
+ atf_tc_fail("dup(2) dupped more than RLIMIT_NOFILE");
+
+ atf_tc_fail("unknown error");
+ }
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(dup_max, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(dup_mode);
+ATF_TC_HEAD(dup_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of dup(2)");
+}
+
+ATF_TC_BODY(dup_mode, tc)
+{
+ check_mode(true, false, false);
+}
+
+ATF_TC_CLEANUP(dup_mode, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, dup2_basic);
+ ATF_TP_ADD_TC(tp, dup2_err);
+ ATF_TP_ADD_TC(tp, dup2_max);
+ ATF_TP_ADD_TC(tp, dup2_mode);
+ ATF_TP_ADD_TC(tp, dup3_err);
+ ATF_TP_ADD_TC(tp, dup3_max);
+ ATF_TP_ADD_TC(tp, dup3_mode);
+ ATF_TP_ADD_TC(tp, dup_err);
+ ATF_TP_ADD_TC(tp, dup_max);
+ ATF_TP_ADD_TC(tp, dup_mode);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_fsync.c b/contrib/netbsd-tests/lib/libc/sys/t_fsync.c
new file mode 100644
index 000000000000..e61ea7ef3aa6
--- /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 000000000000..ed43df57eb04
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getcontext.c
@@ -0,0 +1,143 @@
+/* $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 */
+
+#ifdef __FreeBSD__
+#ifdef __amd64__
+ atf_tc_expect_fail("setcontext in this testcase fails on "
+ "FreeBSD/amd64 with rc == -1/errno == EINVAL; see PR # 194828");
+#endif
+#endif
+
+ 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);
+
+#ifdef __FreeBSD__
+ if (calls == 0) {
+ int rc = setcontext(&uc[DEPTH-1]);
+ ATF_REQUIRE_EQ_MSG(rc, 0, "%d != 0; (errno = %d)", rc, errno);
+ }
+#else
+ if (calls == 0)
+ ATF_REQUIRE_EQ(setcontext(&uc[DEPTH-1]), 0);
+#endif
+}
+
+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 000000000000..7dedca445288
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getgroups.c
@@ -0,0 +1,174 @@
+/* $NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_getgroups.c,v 1.1 2011/07/07 06:57:53 jruoho Exp $");
+
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+ATF_TC(getgroups_err);
+ATF_TC_HEAD(getgroups_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors in getgroups(2)");
+}
+
+ATF_TC_BODY(getgroups_err, tc)
+{
+ gid_t gidset[NGROUPS_MAX];
+
+ errno = 0;
+
+ ATF_REQUIRE(getgroups(10, (gid_t *)-1) == -1);
+ ATF_REQUIRE(errno == EFAULT);
+
+ errno = 0;
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("Reported as kern/189941");
+#endif
+ ATF_REQUIRE(getgroups(-1, gidset) == -1);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+ATF_TC(getgroups_getgid);
+ATF_TC_HEAD(getgroups_getgid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test getgid(2) from getgroups(2)");
+}
+
+ATF_TC_BODY(getgroups_getgid, tc)
+{
+ gid_t gidset[NGROUPS_MAX];
+ gid_t gid = getgid();
+ int i, n;
+
+ /*
+ * Check that getgid(2) is found from
+ * the GIDs returned by getgroups(2).
+ */
+ n = getgroups(NGROUPS_MAX, gidset);
+
+ for (i = 0; i < n; i++) {
+
+ if (gidset[i] == gid)
+ return;
+ }
+
+ atf_tc_fail("getgid(2) not found from getgroups(2)");
+}
+
+ATF_TC(getgroups_setgid);
+ATF_TC_HEAD(getgroups_setgid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setgid(2) from getgroups(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(getgroups_setgid, tc)
+{
+ gid_t gidset[NGROUPS_MAX];
+ int i, n, rv, sta;
+ pid_t pid;
+
+ /*
+ * Check that we can setgid(2)
+ * to the returned group IDs.
+ */
+ n = getgroups(NGROUPS_MAX, gidset);
+ ATF_REQUIRE(n >= 0);
+
+ for (i = 0; i < n; i++) {
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ rv = setgid(gidset[i]);
+
+ if (rv != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("getgroups(2) is inconsistent");
+ }
+}
+
+ATF_TC(getgroups_zero);
+ATF_TC_HEAD(getgroups_zero, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test getgroups(2) with zero param");
+}
+
+ATF_TC_BODY(getgroups_zero, tc)
+{
+ const gid_t val = 123456789;
+ gid_t gidset[NGROUPS_MAX];
+ size_t i;
+
+ /*
+ * If the first parameter is zero, the number
+ * of groups should be returned but the supplied
+ * buffer should remain intact.
+ */
+ for (i = 0; i < __arraycount(gidset); i++)
+ gidset[i] = val;
+
+ ATF_REQUIRE(getgroups(0, gidset) >= 0);
+
+ for (i = 0; i < __arraycount(gidset); i++) {
+
+ if (gidset[i] != val)
+ atf_tc_fail("getgroups(2) modified the buffer");
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getgroups_err);
+ ATF_TP_ADD_TC(tp, getgroups_getgid);
+ ATF_TP_ADD_TC(tp, getgroups_setgid);
+ ATF_TP_ADD_TC(tp, getgroups_zero);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c b/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c
new file mode 100644
index 000000000000..0e4e7b6be333
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getitimer.c
@@ -0,0 +1,216 @@
+/* $NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_getitimer.c,v 1.2 2012/03/22 18:20:46 christos Exp $");
+
+#include <sys/time.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+
+static bool fail;
+static void sighandler(int);
+
+static void
+sighandler(int signo)
+{
+
+ if (signo == SIGALRM || signo == SIGVTALRM)
+ fail = false;
+}
+
+ATF_TC(getitimer_empty);
+ATF_TC_HEAD(getitimer_empty, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "getitimer(2) before setitimer(2)");
+}
+
+ATF_TC_BODY(getitimer_empty, tc)
+{
+ struct itimerval it;
+
+ /*
+ * Verify that the passed structure remains
+ * empty after calling getitimer(2) but before
+ * actually arming the timer with setitimer(2).
+ */
+ (void)memset(&it, 0, sizeof(struct itimerval));
+
+ ATF_REQUIRE(getitimer(ITIMER_REAL, &it) == 0);
+
+ if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0)
+ goto fail;
+
+ ATF_REQUIRE(getitimer(ITIMER_VIRTUAL, &it) == 0);
+
+ if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0)
+ goto fail;
+
+ ATF_REQUIRE(getitimer(ITIMER_PROF, &it) == 0);
+
+ if (it.it_value.tv_sec != 0 || it.it_value.tv_usec != 0)
+ goto fail;
+
+ return;
+
+fail:
+ atf_tc_fail("getitimer(2) modfied the timer before it was armed");
+}
+
+ATF_TC(getitimer_err);
+ATF_TC_HEAD(getitimer_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from getitimer(2)");
+}
+
+ATF_TC_BODY(getitimer_err, tc)
+{
+ struct itimerval it;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, getitimer(-1, &it) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, getitimer(INT_MAX, &it) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, getitimer(ITIMER_REAL, (void *)-1) == -1);
+}
+
+ATF_TC(setitimer_basic);
+ATF_TC_HEAD(setitimer_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of setitimer(2)");
+}
+
+ATF_TC_BODY(setitimer_basic, tc)
+{
+ struct itimerval it;
+
+ it.it_value.tv_sec = 0;
+ it.it_value.tv_usec = 100;
+
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_usec = 0;
+
+ fail = true;
+
+ ATF_REQUIRE(signal(SIGALRM, sighandler) != SIG_ERR);
+ ATF_REQUIRE(setitimer(ITIMER_REAL, &it, NULL) == 0);
+
+ /*
+ * Although the interaction between
+ * setitimer(2) and sleep(3) can be
+ * unspecified, it is assumed that one
+ * second suspension will be enough for
+ * the timer to fire.
+ */
+ (void)sleep(1);
+
+ if (fail != false)
+ atf_tc_fail("timer did not fire");
+}
+
+ATF_TC(setitimer_err);
+ATF_TC_HEAD(setitimer_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from setitimer(2)"
+ " (PR standards/44927)");
+}
+
+ATF_TC_BODY(setitimer_err, tc)
+{
+ struct itimerval it, ot;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, setitimer(-1, &it, &ot) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, setitimer(INT_MAX, &it, &ot) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, setitimer(ITIMER_REAL,(void*)-1, &ot) == -1);
+}
+
+ATF_TC(setitimer_old);
+ATF_TC_HEAD(setitimer_old, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test old values from setitimer(2)");
+}
+
+ATF_TC_BODY(setitimer_old, tc)
+{
+ struct itimerval it, ot;
+
+ /*
+ * Make two calls; the second one
+ * should store the old values.
+ */
+ it.it_value.tv_sec = 4;
+ it.it_value.tv_usec = 3;
+
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_usec = 0;
+
+ ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0);
+
+ it.it_value.tv_sec = 2;
+ it.it_value.tv_usec = 1;
+
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_usec = 0;
+
+ ATF_REQUIRE(setitimer(ITIMER_REAL, &it, &ot) == 0);
+
+#ifdef __FreeBSD__
+ if (ot.it_value.tv_sec == 4 && ot.it_value.tv_usec == 3)
+ atf_tc_fail("setitimer(2) did not return remaining time");
+#else
+ if (ot.it_value.tv_sec != 4 || ot.it_value.tv_usec != 3)
+ atf_tc_fail("setitimer(2) did not store old values");
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getitimer_empty);
+ ATF_TP_ADD_TC(tp, getitimer_err);
+ ATF_TP_ADD_TC(tp, setitimer_basic);
+ ATF_TP_ADD_TC(tp, setitimer_err);
+ ATF_TP_ADD_TC(tp, setitimer_old);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c b/contrib/netbsd-tests/lib/libc/sys/t_getlogin.c
new file mode 100644
index 000000000000..8c2b1990d7eb
--- /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 000000000000..b3ed3931a41f
--- /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 000000000000..85eeac6bee0c
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_getrusage.c
@@ -0,0 +1,210 @@
+/* $NetBSD: t_getrusage.c,v 1.3 2014/09/03 19:24:12 matt Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_getrusage.c,v 1.3 2014/09/03 19:24:12 matt Exp $");
+
+#include <sys/resource.h>
+#include <sys/time.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdint.h>
+#include <string.h>
+
+static void work(void);
+static void sighandler(int);
+
+static const size_t maxiter = 2000;
+
+static void
+#ifdef __FreeBSD__
+sighandler(int signo __unused)
+#else
+sighandler(int signo)
+#endif
+{
+ /* Nothing. */
+}
+
+static void
+work(void)
+{
+ size_t n = UINT16_MAX * 10;
+
+ while (n > 0) {
+#ifdef __or1k__
+ asm volatile("l.nop"); /* Do something. */
+#else
+ asm volatile("nop"); /* Do something. */
+#endif
+ n--;
+ }
+}
+
+ATF_TC(getrusage_err);
+ATF_TC_HEAD(getrusage_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions");
+}
+
+ATF_TC_BODY(getrusage_err, tc)
+{
+ struct rusage ru;
+
+ errno = 0;
+
+ ATF_REQUIRE(getrusage(INT_MAX, &ru) != 0);
+ ATF_REQUIRE(errno == EINVAL);
+
+ errno = 0;
+
+ ATF_REQUIRE(getrusage(RUSAGE_SELF, (void *)0) != 0);
+ ATF_REQUIRE(errno == EFAULT);
+}
+
+ATF_TC(getrusage_sig);
+ATF_TC_HEAD(getrusage_sig, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test signal count with getrusage(2)");
+}
+
+ATF_TC_BODY(getrusage_sig, tc)
+{
+ struct rusage ru;
+ const long n = 5;
+ int i;
+
+ /*
+ * Test that signals are recorded.
+ */
+ ATF_REQUIRE(signal(SIGUSR1, sighandler) != SIG_ERR);
+
+ for (i = 0; i < n; i++)
+ ATF_REQUIRE(raise(SIGUSR1) == 0);
+
+ (void)memset(&ru, 0, sizeof(struct rusage));
+ ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0);
+
+ if (n != ru.ru_nsignals)
+ atf_tc_fail("getrusage(2) did not record signals");
+}
+
+ATF_TC(getrusage_utime_back);
+ATF_TC_HEAD(getrusage_utime_back, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test bogus values from getrusage(2)");
+}
+
+ATF_TC_BODY(getrusage_utime_back, tc)
+{
+ struct rusage ru1, ru2;
+ size_t i;
+
+ /*
+ * Test that two consecutive calls are sane.
+ */
+#ifdef __NetBSD__
+ atf_tc_expect_fail("PR kern/30115");
+#endif
+
+ for (i = 0; i < maxiter; i++) {
+
+ (void)memset(&ru1, 0, sizeof(struct rusage));
+ (void)memset(&ru2, 0, sizeof(struct rusage));
+
+ work();
+
+ ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru1) == 0);
+
+ work();
+
+ ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru2) == 0);
+
+ if (timercmp(&ru2.ru_utime, &ru1.ru_utime, <) != 0)
+ atf_tc_fail("user time went backwards");
+ }
+
+#ifdef __NetBSD__
+ atf_tc_fail("anticipated error did not occur");
+#endif
+}
+
+ATF_TC(getrusage_utime_zero);
+ATF_TC_HEAD(getrusage_utime_zero, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test zero utime from getrusage(2)");
+}
+
+ATF_TC_BODY(getrusage_utime_zero, tc)
+{
+ struct rusage ru;
+ size_t i;
+
+#ifdef __FreeBSD__
+ atf_tc_skip("this testcase passes/fails sporadically on FreeBSD/i386 "
+ "@ r273153 (at least)");
+#endif
+
+ /*
+ * Test that getrusage(2) does not return
+ * zero user time for the calling process.
+ *
+ * See also (duplicate) PR port-amd64/41734.
+ */
+ atf_tc_expect_fail("PR kern/30115");
+
+ for (i = 0; i < maxiter; i++) {
+
+ work();
+
+ (void)memset(&ru, 0, sizeof(struct rusage));
+
+ ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0);
+
+ if (ru.ru_utime.tv_sec == 0 && ru.ru_utime.tv_usec == 0)
+ atf_tc_fail("zero user time from getrusage(2)");
+ }
+
+ atf_tc_fail("anticipated error did not occur");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, getrusage_err);
+ ATF_TP_ADD_TC(tp, getrusage_sig);
+ ATF_TP_ADD_TC(tp, getrusage_utime_back);
+ ATF_TP_ADD_TC(tp, getrusage_utime_zero);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_getsid.c b/contrib/netbsd-tests/lib/libc/sys/t_getsid.c
new file mode 100644
index 000000000000..76b54ab4fffd
--- /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 000000000000..1cf303b08e37
--- /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 000000000000..b76ba390de78
--- /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 000000000000..fe298c552825
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_kevent.c
@@ -0,0 +1,206 @@
+/* $NetBSD: t_kevent.c,v 1.6 2012/11/29 09:13:44 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundatiom
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_kevent.c,v 1.6 2012/11/29 09:13:44 martin Exp $");
+
+#include <sys/types.h>
+#include <sys/event.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <err.h>
+#ifdef __NetBSD__
+#include <sys/drvctlio.h>
+#endif
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#ifdef __FreeBSD__
+#define DRVCTLDEV "/nonexistent"
+#endif
+
+ATF_TC(kevent_zerotimer);
+ATF_TC_HEAD(kevent_zerotimer, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that kevent with a 0 timer "
+ "does not crash the system (PR lib/45618)");
+}
+
+ATF_TC_BODY(kevent_zerotimer, tc)
+{
+ struct kevent ev;
+ int kq;
+
+ ATF_REQUIRE((kq = kqueue()) != -1);
+ EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0);
+ ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) != -1);
+ ATF_REQUIRE(kevent(kq, NULL, 0, &ev, 1, NULL) == 1);
+}
+
+ATF_TC(kqueue_desc_passing);
+ATF_TC_HEAD(kqueue_desc_passing, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that passing a kqueue to "
+ "another process does not crash the kernel (PR 46463)");
+}
+
+ATF_TC_BODY(kqueue_desc_passing, tc)
+{
+ pid_t child;
+ int s[2], storage, status, kq;
+ struct cmsghdr *msg;
+ struct iovec iov;
+ struct msghdr m;
+ struct kevent ev;
+
+ ATF_REQUIRE((kq = kqueue()) != -1);
+
+ // atf_tc_skip("crashes kernel (PR 46463)");
+
+ ATF_REQUIRE(socketpair(AF_LOCAL, SOCK_STREAM, 0, s) != -1);
+ msg = malloc(CMSG_SPACE(sizeof(int)));
+ m.msg_iov = &iov;
+ m.msg_iovlen = 1;
+ m.msg_name = NULL;
+ m.msg_namelen = 0;
+ m.msg_control = msg;
+ m.msg_controllen = CMSG_SPACE(sizeof(int));
+
+ child = fork();
+ if (child == 0) {
+ close(s[0]);
+
+ iov.iov_base = &storage;
+ iov.iov_len = sizeof(int);
+ m.msg_iov = &iov;
+ m.msg_iovlen = 1;
+
+ if (recvmsg(s[1], &m, 0) == -1)
+ err(1, "child: could not recvmsg");
+
+#ifdef __FreeBSD__
+ bcopy(CMSG_DATA(msg), &kq, sizeof(kq));
+ printf("child (pid %d): received kq fd %d\n", getpid(), kq);
+ _exit(0);
+#else
+ kq = *(int *)CMSG_DATA(msg);
+ printf("child (pid %d): received kq fd %d\n", getpid(), kq);
+ exit(0);
+#endif
+ }
+
+ close(s[1]);
+
+ iov.iov_base = &storage;
+ iov.iov_len = sizeof(int);
+
+ msg->cmsg_level = SOL_SOCKET;
+ msg->cmsg_type = SCM_RIGHTS;
+ msg->cmsg_len = CMSG_LEN(sizeof(int));
+
+#ifdef __FreeBSD__
+ /*
+ * What is should have been
+ * bcopy(&s[0], CMSG_DATA(msg), sizeof(kq));
+ */
+ bcopy(&kq, CMSG_DATA(msg), sizeof(kq));
+#else
+ *(int *)CMSG_DATA(msg) = kq;
+#endif
+
+ EV_SET(&ev, 1, EVFILT_TIMER, EV_ADD|EV_ENABLE, 0, 1, 0);
+ ATF_CHECK(kevent(kq, &ev, 1, NULL, 0, NULL) != -1);
+
+ printf("parent (pid %d): sending kq fd %d\n", getpid(), kq);
+ if (sendmsg(s[0], &m, 0) == -1) {
+#ifdef __NetBSD__
+ ATF_REQUIRE_EQ_MSG(errno, EBADF, "errno is %d", errno);
+ atf_tc_skip("PR kern/46523");
+#endif
+#ifdef __FreeBSD__
+ ATF_REQUIRE_EQ_MSG(errno, EOPNOTSUPP, "errno is %d", errno);
+ close(s[0]);
+#endif
+ }
+
+ close(kq);
+
+ waitpid(child, &status, 0);
+ ATF_CHECK(WIFEXITED(status) && WEXITSTATUS(status)==0);
+}
+
+ATF_TC(kqueue_unsupported_fd);
+ATF_TC_HEAD(kqueue_unsupported_fd, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that watching an fd whose"
+ " type is not supported does not crash the kernel");
+}
+
+ATF_TC_BODY(kqueue_unsupported_fd, tc)
+{
+ /* mqueue and semaphore use fnullop_kqueue also */
+ int fd, kq;
+ struct kevent ev;
+
+ fd = open(DRVCTLDEV, O_RDONLY);
+ if (fd == -1 && errno == ENOENT)
+ atf_tc_skip("no " DRVCTLDEV " available for testing");
+ ATF_REQUIRE(fd != -1);
+ ATF_REQUIRE((kq = kqueue()) != -1);
+
+ EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
+ NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK|
+ NOTE_RENAME|NOTE_REVOKE, 0, 0);
+
+ ATF_REQUIRE(kevent(kq, &ev, 1, NULL, 0, NULL) == -1);
+ ATF_REQUIRE_ERRNO(EOPNOTSUPP, true);
+
+ (void)close(fd);
+}
+
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, kevent_zerotimer);
+ ATF_TP_ADD_TC(tp, kqueue_desc_passing);
+ ATF_TP_ADD_TC(tp, kqueue_unsupported_fd);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_kill.c b/contrib/netbsd-tests/lib/libc/sys/t_kill.c
new file mode 100644
index 000000000000..2f4286246ad2
--- /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 000000000000..b8dcacc994fe
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_link.c
@@ -0,0 +1,233 @@
+/* $NetBSD: t_link.c,v 1.2 2014/04/21 14:39:36 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_link.c,v 1.2 2014/04/21 14:39:36 martin Exp $");
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+static const char *getpath(void);
+static char path[] = "link";
+static const char *pathl;
+
+static const char *
+getpath(void)
+{
+ static char buf[LINE_MAX];
+
+ (void)memset(buf, '\0', sizeof(buf));
+
+ if (getcwd(buf, sizeof(buf)) == NULL)
+ return NULL;
+
+ (void)strlcat(buf, path, sizeof(buf));
+ (void)strlcat(buf, ".link", sizeof(buf));
+
+ return buf;
+}
+
+ATF_TC_WITH_CLEANUP(link_count);
+ATF_TC_HEAD(link_count, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "link(2) counts are incremented?");
+}
+
+ATF_TC_BODY(link_count, tc)
+{
+ struct stat sa, sb;
+ int fd;
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ pathl = getpath();
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(pathl != NULL);
+
+ ATF_REQUIRE(stat(path, &sa) == 0);
+ ATF_REQUIRE(link(path, pathl) == 0);
+ ATF_REQUIRE(stat(path, &sb) == 0);
+
+ if (sa.st_nlink != sb.st_nlink - 1)
+ atf_tc_fail("incorrect link(2) count");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+ ATF_REQUIRE(unlink(pathl) == 0);
+}
+
+ATF_TC_CLEANUP(link_count, tc)
+{
+ (void)unlink(path);
+ (void)unlink(pathl);
+}
+
+ATF_TC_WITH_CLEANUP(link_err);
+ATF_TC_HEAD(link_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of link(2)");
+}
+
+ATF_TC_BODY(link_err, tc)
+{
+ char buf[MAXPATHLEN + 1];
+ int fd;
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ pathl = getpath();
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(pathl != NULL);
+
+ errno = 0;
+ ATF_REQUIRE(link(path, pathl) == 0);
+ ATF_REQUIRE_ERRNO(EEXIST, link(path, pathl) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, link(buf, "xxx") == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, link(path, "/d/c/b/a") == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", path) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, link("/a/b/c/d", "/d/c/b/a") == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, link(path, (const char *)-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, link((const char *)-1, "xxx") == -1);
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+ ATF_REQUIRE(unlink(pathl) == 0);
+}
+
+ATF_TC_CLEANUP(link_err, tc)
+{
+ (void)unlink(path);
+ (void)unlink(pathl);
+}
+
+ATF_TC(link_perm);
+ATF_TC_HEAD(link_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with link(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(link_perm, tc)
+{
+ int rv;
+
+ errno = 0;
+ rv = link("/root", "/root.link");
+ ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM),
+ "link to a directory did not fail with EPERM or EACCESS; link() "
+ "returned %d, errno %d", rv, errno);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EACCES,
+ link("/root/.profile", "/root/.profile.link") == -1);
+}
+
+ATF_TC_WITH_CLEANUP(link_stat);
+ATF_TC_HEAD(link_stat, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check stat(2) of a linked file");
+}
+
+ATF_TC_BODY(link_stat, tc)
+{
+ struct stat sa, sb;
+ int fd;
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ pathl = getpath();
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(pathl != NULL);
+
+ ATF_REQUIRE(link(path, pathl) == 0);
+ ATF_REQUIRE(stat(path, &sa) == 0);
+ ATF_REQUIRE(lstat(pathl, &sb) == 0);
+
+ if (sa.st_uid != sb.st_uid)
+ atf_tc_fail("unequal UIDs");
+
+ if (sa.st_mode != sb.st_mode)
+ atf_tc_fail("unequal modes");
+
+ if (sa.st_ino != sb.st_ino)
+ atf_tc_fail("unequal inodes");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+ ATF_REQUIRE(unlink(pathl) == 0);
+}
+
+ATF_TC_CLEANUP(link_stat, tc)
+{
+ (void)unlink(path);
+ (void)unlink(pathl);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, link_count);
+ ATF_TP_ADD_TC(tp, link_err);
+ ATF_TP_ADD_TC(tp, link_perm);
+ ATF_TP_ADD_TC(tp, link_stat);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_listen.c b/contrib/netbsd-tests/lib/libc/sys/t_listen.c
new file mode 100644
index 000000000000..d7c7d9e02d4f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_listen.c
@@ -0,0 +1,138 @@
+/* $NetBSD: t_listen.c,v 1.4 2012/03/18 07:00:52 jruoho Exp $ */
+/*
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#ifdef __FreeBSD__
+#include <sys/socket.h>
+#endif
+
+static const char *path = "listen";
+
+ATF_TC_WITH_CLEANUP(listen_err);
+ATF_TC_HEAD(listen_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks errors from listen(2) (PR standards/46150)");
+}
+
+ATF_TC_BODY(listen_err, tc)
+{
+ static const size_t siz = sizeof(struct sockaddr_in);
+ struct sockaddr_in sina, sinb;
+ int fda, fdb, fdc;
+
+ (void)memset(&sina, 0, sizeof(struct sockaddr_in));
+ (void)memset(&sinb, 0, sizeof(struct sockaddr_in));
+
+ sina.sin_family = AF_INET;
+ sina.sin_port = htons(31522);
+ sina.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ sinb.sin_family = AF_INET;
+ sinb.sin_port = htons(31522);
+ sinb.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ fda = socket(AF_INET, SOCK_STREAM, 0);
+ fdb = socket(AF_INET, SOCK_STREAM, 0);
+ fdc = open("listen", O_RDWR | O_CREAT, 0600);
+
+ ATF_REQUIRE(fda >= 0 && fdb >= 0 && fdc >= 0);
+ ATF_REQUIRE_ERRNO(ENOTSOCK, listen(fdc, 1) == -1);
+
+ (void)close(fdc);
+ (void)unlink(path);
+
+ ATF_REQUIRE(bind(fda, (struct sockaddr *)&sina, siz) == 0);
+ ATF_REQUIRE(listen(fda, 1) == 0);
+
+ /*
+ * According to IEEE Std 1003.1-2008: if the socket is
+ * already connected, the call should fail with EINVAL.
+ */
+ ATF_REQUIRE(connect(fdb, (struct sockaddr *)&sinb, siz) == 0);
+ ATF_REQUIRE_ERRNO(EINVAL, listen(fdb, 1) == -1);
+
+ (void)close(fda);
+ (void)close(fdb);
+
+ ATF_REQUIRE_ERRNO(EBADF, connect(fdb,
+ (struct sockaddr *)&sinb, siz) == -1);
+}
+
+ATF_TC_CLEANUP(listen_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(listen_low_port);
+ATF_TC_HEAD(listen_low_port, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Does low-port allocation work?");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(listen_low_port, tc)
+{
+ int sd, val;
+
+ sd = socket(AF_INET, SOCK_STREAM, 0);
+
+ val = IP_PORTRANGE_LOW;
+ if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, &val,
+ sizeof(val)) == -1)
+ atf_tc_fail("setsockopt failed: %s", strerror(errno));
+
+ if (listen(sd, 5) == -1) {
+ int serrno = errno;
+ atf_tc_fail("listen failed: %s%s",
+ strerror(serrno),
+ serrno != EACCES ? "" :
+ " (see http://mail-index.netbsd.org/"
+ "source-changes/2007/12/16/0011.html)");
+ }
+
+ close(sd);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, listen_err);
+ ATF_TP_ADD_TC(tp, listen_low_port);
+
+ return 0;
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c b/contrib/netbsd-tests/lib/libc/sys/t_lwp_create.c
new file mode 100644
index 000000000000..02545fe14869
--- /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 000000000000..1b28f75f49f9
--- /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 000000000000..499493f380ad
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mincore.c
@@ -0,0 +1,336 @@
+/* $NetBSD: t_mincore.c,v 1.8 2012/06/08 07:18:58 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_mincore.c,v 1.8 2012/06/08 07:18:58 martin Exp $");
+
+#include <sys/mman.h>
+#include <sys/shm.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <kvm.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/resource.h>
+
+#ifdef __FreeBSD__
+#include <sys/stat.h>
+#endif
+
+static long page = 0;
+static const char path[] = "mincore";
+static size_t check_residency(void *, size_t);
+
+static size_t
+check_residency(void *addr, size_t npgs)
+{
+ size_t i, resident;
+ char *vec;
+
+ vec = malloc(npgs);
+
+ ATF_REQUIRE(vec != NULL);
+ ATF_REQUIRE(mincore(addr, npgs * page, vec) == 0);
+
+ for (i = resident = 0; i < npgs; i++) {
+
+ if (vec[i] != 0)
+ resident++;
+
+#if 0
+ (void)fprintf(stderr, "page 0x%p is %sresident\n",
+ (char *)addr + (i * page), vec[i] ? "" : "not ");
+#endif
+ }
+
+ free(vec);
+
+ return resident;
+}
+
+ATF_TC(mincore_err);
+ATF_TC_HEAD(mincore_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from mincore(2)");
+}
+
+ATF_TC_BODY(mincore_err, tc)
+{
+ char *map, *vec;
+
+ map = mmap(NULL, page, PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ vec = malloc(page);
+
+ ATF_REQUIRE(vec != NULL);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+#ifdef __NetBSD__
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, mincore(map, 0, vec) == -1);
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOMEM, mincore(0, page, vec) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, mincore(map, page, (void *)-1) == -1);
+
+ free(vec);
+ ATF_REQUIRE(munmap(map, page) == 0);
+}
+
+ATF_TC_WITH_CLEANUP(mincore_resid);
+ATF_TC_HEAD(mincore_resid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test page residency with mincore(2)");
+}
+
+ATF_TC_BODY(mincore_resid, tc)
+{
+ void *addr, *addr2, *addr3, *buf;
+ size_t npgs = 0, resident;
+ struct stat st;
+ int fd, rv;
+ struct rlimit rlim;
+
+ ATF_REQUIRE(getrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
+ rlim.rlim_cur = rlim.rlim_max;
+ ATF_REQUIRE(setrlimit(RLIMIT_MEMLOCK, &rlim) == 0);
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ fd = open(path, O_RDWR | O_CREAT, 0700);
+ buf = malloc(page * 5);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(buf != NULL);
+
+ rv = write(fd, buf, page * 5);
+ ATF_REQUIRE(rv >= 0);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(fstat(fd, &st) == 0);
+
+ addr = mmap(NULL, (size_t)st.st_size, PROT_READ,
+ MAP_FILE | MAP_SHARED, fd, (off_t) 0);
+
+ ATF_REQUIRE(addr != MAP_FAILED);
+
+ (void)close(fd);
+
+ npgs = st.st_size / page;
+
+ if (st.st_size % page != 0)
+ npgs++;
+
+ (void)check_residency(addr, npgs);
+
+ rv = mlock(addr, npgs * page);
+ if (rv == -1 && errno == EAGAIN)
+ atf_tc_skip("hit process resource limits");
+ ATF_REQUIRE(munmap(addr, st.st_size) == 0);
+
+ npgs = 128;
+
+#ifdef __FreeBSD__
+ addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, (off_t)0);
+#else
+ addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE | MAP_WIRED, -1, (off_t)0);
+#endif
+
+ if (addr == MAP_FAILED)
+ atf_tc_skip("could not mmap wired anonymous test area, system "
+ "might be low on memory");
+
+#ifdef __FreeBSD__
+ ATF_REQUIRE(mlock(addr, npgs * page) == 0);
+#endif
+ ATF_REQUIRE(check_residency(addr, npgs) == npgs);
+ ATF_REQUIRE(munmap(addr, npgs * page) == 0);
+
+ npgs = 128;
+
+ addr = mmap(NULL, npgs * page, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, (off_t)0);
+
+ ATF_REQUIRE(addr != MAP_FAILED);
+
+ /*
+ * Check that the in-core pages match the locked pages.
+ */
+ ATF_REQUIRE(check_residency(addr, npgs) == 0);
+
+ errno = 0;
+ if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0 && errno != ENOMEM)
+ atf_tc_fail("mlockall(2) failed");
+ if (errno == ENOMEM)
+ atf_tc_skip("mlockall() exceeded process resource limits");
+
+ resident = check_residency(addr, npgs);
+ if (resident < npgs)
+ atf_tc_fail("mlockall(MCL_FUTURE) succeeded, still only "
+ "%zu pages of the newly mapped %zu pages are resident",
+ resident, npgs);
+
+ addr2 = mmap(NULL, npgs * page, PROT_READ, MAP_ANON, -1, (off_t)0);
+ addr3 = mmap(NULL, npgs * page, PROT_NONE, MAP_ANON, -1, (off_t)0);
+
+ if (addr2 == MAP_FAILED || addr3 == MAP_FAILED)
+ atf_tc_skip("could not mmap more anonymous test pages with "
+ "mlockall(MCL_FUTURE) in effect, system "
+ "might be low on memory");
+
+ ATF_REQUIRE(check_residency(addr2, npgs) == npgs);
+ ATF_REQUIRE(check_residency(addr3, npgs) == 0);
+ ATF_REQUIRE(mprotect(addr3, npgs * page, PROT_READ) == 0);
+ ATF_REQUIRE(check_residency(addr, npgs) == npgs);
+ ATF_REQUIRE(check_residency(addr2, npgs) == npgs);
+
+ (void)munlockall();
+
+ ATF_REQUIRE(madvise(addr2, npgs * page, MADV_FREE) == 0);
+#ifdef __NetBSD__
+ ATF_REQUIRE(check_residency(addr2, npgs) == 0);
+#endif
+
+ (void)memset(addr, 0, npgs * page);
+
+ ATF_REQUIRE(madvise(addr, npgs * page, MADV_FREE) == 0);
+#ifdef __NetBSD__
+ ATF_REQUIRE(check_residency(addr, npgs) == 0);
+#endif
+
+ (void)munmap(addr, npgs * page);
+ (void)munmap(addr2, npgs * page);
+ (void)munmap(addr3, npgs * page);
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(mincore_resid, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(mincore_shmseg);
+ATF_TC_HEAD(mincore_shmseg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "residency of shared memory");
+}
+
+ATF_TC_BODY(mincore_shmseg, tc)
+{
+ size_t npgs = 128;
+ void *addr = NULL;
+ int shmid;
+
+ shmid = shmget(IPC_PRIVATE, npgs * page,
+ IPC_CREAT | S_IRUSR | S_IWUSR);
+
+ ATF_REQUIRE(shmid != -1);
+
+ addr = shmat(shmid, NULL, 0);
+
+ ATF_REQUIRE(addr != NULL);
+ ATF_REQUIRE(check_residency(addr, npgs) == 0);
+
+ (void)memset(addr, 0xff, npgs * page);
+
+ ATF_REQUIRE(check_residency(addr, npgs) == npgs);
+ ATF_REQUIRE(madvise(addr, npgs * page, MADV_FREE) == 0);
+
+ /*
+ * NOTE! Even though we have MADV_FREE'd the range,
+ * there is another reference (the kernel's) to the
+ * object which owns the pages. In this case, the
+ * kernel does not simply free the pages, as haphazardly
+ * freeing pages when there are still references to
+ * an object can cause data corruption (say, the other
+ * referencer doesn't expect the pages to be freed,
+ * and is surprised by the subsequent ZFOD).
+ *
+ * Because of this, we simply report the number of
+ * pages still resident, for information only.
+ */
+ npgs = check_residency(addr, npgs);
+
+ (void)fprintf(stderr, "%zu pages still resident\n", npgs);
+
+ ATF_REQUIRE(shmdt(addr) == 0);
+ ATF_REQUIRE(shmctl(shmid, IPC_RMID, NULL) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+ ATF_TP_ADD_TC(tp, mincore_err);
+ ATF_TP_ADD_TC(tp, mincore_resid);
+ ATF_TP_ADD_TC(tp, mincore_shmseg);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_minherit.c b/contrib/netbsd-tests/lib/libc/sys/t_minherit.c
new file mode 100644
index 000000000000..0bdf6bc0a0d8
--- /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 000000000000..d97a20b6c26c
--- /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 000000000000..56bc4c831fcb
--- /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 000000000000..1c5cd9b57618
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mknod.c
@@ -0,0 +1,202 @@
+/* $NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_mknod.c,v 1.2 2012/03/18 07:00:52 jruoho Exp $");
+
+#include <sys/stat.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <paths.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+static char path[] = "node";
+
+ATF_TC_WITH_CLEANUP(mknod_err);
+ATF_TC_HEAD(mknod_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test error conditions of mknod(2) (PR kern/45111)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(mknod_err, tc)
+{
+ char buf[PATH_MAX + 1];
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+#ifndef __FreeBSD__
+ /*
+ * As of FreeBSD 6.0 device nodes may be created in regular file systems but
+ * such nodes cannot be used to access devices. As a result an invalid dev
+ * argument is unchecked.
+ */
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, mknod(path, S_IFCHR, -1) == -1);
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, mknod(buf, S_IFCHR, 0) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, mknod((char *)-1, S_IFCHR, 0) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, mknod("/a/b/c/d/e/f/g", S_IFCHR, 0) == -1);
+}
+
+ATF_TC_CLEANUP(mknod_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mknod_exist);
+ATF_TC_HEAD(mknod_exist, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test EEXIST from mknod(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(mknod_exist, tc)
+{
+ int fd;
+
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd >= 0) {
+
+ (void)close(fd);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EEXIST,
+ mknod("/etc/passwd", S_IFCHR, 0) == -1);
+ }
+
+ ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EEXIST, mknod(path, S_IFCHR, 0) == -1);
+
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(mknod_exist, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mknod_perm);
+ATF_TC_HEAD(mknod_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions of mknod(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(mknod_perm, tc)
+{
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFCHR, 0) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EPERM, mknod(path, S_IFBLK, 0) == -1);
+}
+
+ATF_TC_CLEANUP(mknod_perm, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mknod_stat);
+ATF_TC_HEAD(mknod_stat, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of mknod(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(mknod_stat, tc)
+{
+ struct stat st;
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(mknod(path, S_IFCHR, 0) == 0);
+ ATF_REQUIRE(stat(path, &st) == 0);
+
+ if (S_ISCHR(st.st_mode) == 0)
+ atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFCHR)");
+
+ ATF_REQUIRE(unlink(path) == 0);
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(mknod(path, S_IFBLK, 0) == 0);
+ ATF_REQUIRE(stat(path, &st) == 0);
+
+ if (S_ISBLK(st.st_mode) == 0)
+ atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFBLK)");
+
+ ATF_REQUIRE(unlink(path) == 0);
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("mknod does not allow S_IFREG");
+#endif
+ ATF_REQUIRE(mknod(path, S_IFREG, 0) == 0);
+ ATF_REQUIRE(stat(path, &st) == 0);
+
+ if (S_ISREG(st.st_mode) == 0)
+ atf_tc_fail_nonfatal("invalid mode from mknod(2) (S_IFREG)");
+
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(mknod_stat, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, mknod_err);
+ ATF_TP_ADD_TC(tp, mknod_exist);
+ ATF_TP_ADD_TC(tp, mknod_perm);
+ ATF_TP_ADD_TC(tp, mknod_stat);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mlock.c b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c
new file mode 100644
index 000000000000..0397b5cdac6a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mlock.c
@@ -0,0 +1,286 @@
+/* $NetBSD: t_mlock.c,v 1.5 2014/02/26 20:49:26 martin Exp $ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_mlock.c,v 1.5 2014/02/26 20:49:26 martin Exp $");
+
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#endif
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <atf-c.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#define _KMEMUSER
+#include <machine/vmparam.h>
+#endif
+
+static long page = 0;
+
+ATF_TC(mlock_clip);
+ATF_TC_HEAD(mlock_clip, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test with mlock(2) that UVM only "
+ "clips if the clip address is within the entry (PR kern/44788)");
+}
+
+ATF_TC_BODY(mlock_clip, tc)
+{
+ void *buf;
+
+ buf = malloc(page);
+ ATF_REQUIRE(buf != NULL);
+
+ if (page < 1024)
+ atf_tc_skip("page size too small");
+
+ for (size_t i = page; i >= 1; i = i - 1024) {
+ (void)mlock(buf, page - i);
+ (void)munlock(buf, page - i);
+ }
+
+ free(buf);
+}
+
+ATF_TC(mlock_err);
+ATF_TC_HEAD(mlock_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test error conditions in mlock(2) and munlock(2)");
+}
+
+ATF_TC_BODY(mlock_err, tc)
+{
+#ifdef __NetBSD__
+ unsigned long vmin = 0;
+ size_t len = sizeof(vmin);
+#endif
+ void *invalid_ptr;
+ int null_errno = ENOMEM; /* error expected for NULL */
+
+#ifdef __FreeBSD__
+#ifdef VM_MIN_ADDRESS
+ if ((uintptr_t)VM_MIN_ADDRESS > 0)
+ null_errno = EINVAL; /* NULL is not inside user VM */
+#endif
+#else
+ if (sysctlbyname("vm.minaddress", &vmin, &len, NULL, 0) != 0)
+ atf_tc_fail("failed to read vm.minaddress");
+
+ if (vmin > 0)
+ null_errno = EINVAL; /* NULL is not inside user VM */
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(null_errno, mlock(NULL, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(null_errno, mlock((char *)0, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, mlock((char *)-1, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(null_errno, munlock(NULL, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(null_errno, munlock((char *)0, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, munlock((char *)-1, page) == -1);
+
+ /*
+ * Try to create a pointer to an unmapped page - first after current
+ * brk will likely do.
+ */
+ invalid_ptr = (void*)(((uintptr_t)sbrk(0)+page) & ~(page-1));
+ printf("testing with (hopefully) invalid pointer %p\n", invalid_ptr);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOMEM, mlock(invalid_ptr, page) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOMEM, munlock(invalid_ptr, page) == -1);
+}
+
+ATF_TC(mlock_limits);
+ATF_TC_HEAD(mlock_limits, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test system limits with mlock(2)");
+}
+
+ATF_TC_BODY(mlock_limits, tc)
+{
+ struct rlimit res;
+ void *buf;
+ pid_t pid;
+ int sta;
+
+ buf = malloc(page);
+ ATF_REQUIRE(buf != NULL);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ for (ssize_t i = page; i >= 2; i -= 100) {
+
+ res.rlim_cur = i - 1;
+ res.rlim_max = i - 1;
+
+ (void)fprintf(stderr, "trying to lock %zd bytes "
+ "with %zu byte limit\n", i, (size_t)res.rlim_cur);
+
+ if (setrlimit(RLIMIT_MEMLOCK, &res) != 0)
+ _exit(EXIT_FAILURE);
+
+ errno = 0;
+
+#ifdef __FreeBSD__
+ /*
+ * NetBSD doesn't conform to POSIX with ENOMEM requirement;
+ * FreeBSD does.
+ *
+ * See: NetBSD PR # kern/48962 for more details.
+ */
+ if (mlock(buf, i) != -1 || errno != ENOMEM) {
+#else
+ if (mlock(buf, i) != -1 || errno != EAGAIN) {
+#endif
+ (void)munlock(buf, i);
+ _exit(EXIT_FAILURE);
+ }
+ }
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("mlock(2) locked beyond system limits");
+
+ free(buf);
+}
+
+ATF_TC(mlock_mmap);
+ATF_TC_HEAD(mlock_mmap, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mlock(2)-mmap(2) interaction");
+}
+
+ATF_TC_BODY(mlock_mmap, tc)
+{
+#ifdef __NetBSD__
+ static const int flags = MAP_ANON | MAP_PRIVATE | MAP_WIRED;
+#else
+ static const int flags = MAP_ANON | MAP_PRIVATE;
+#endif
+ void *buf;
+
+ /*
+ * Make a wired RW mapping and check that mlock(2)
+ * does not fail for the (already locked) mapping.
+ */
+ buf = mmap(NULL, page, PROT_READ | PROT_WRITE, flags, -1, 0);
+
+ ATF_REQUIRE(buf != MAP_FAILED);
+#ifdef __FreeBSD__
+ /*
+ * The duplicate mlock call is added to ensure that the call works
+ * as described above without MAP_WIRED support.
+ */
+ ATF_REQUIRE(mlock(buf, page) == 0);
+#endif
+ ATF_REQUIRE(mlock(buf, page) == 0);
+ ATF_REQUIRE(munlock(buf, page) == 0);
+ ATF_REQUIRE(munmap(buf, page) == 0);
+ ATF_REQUIRE(munlock(buf, page) != 0);
+
+ /*
+ * But it should be impossible to mlock(2) a PROT_NONE mapping.
+ */
+ buf = mmap(NULL, page, PROT_NONE, flags, -1, 0);
+
+ ATF_REQUIRE(buf != MAP_FAILED);
+#ifdef __FreeBSD__
+ ATF_REQUIRE_ERRNO(ENOMEM, mlock(buf, page) != 0);
+#else
+ ATF_REQUIRE(mlock(buf, page) != 0);
+#endif
+ ATF_REQUIRE(munmap(buf, page) == 0);
+}
+
+ATF_TC(mlock_nested);
+ATF_TC_HEAD(mlock_nested, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that consecutive mlock(2) calls succeed");
+}
+
+ATF_TC_BODY(mlock_nested, tc)
+{
+ const size_t maxiter = 100;
+ void *buf;
+
+ buf = malloc(page);
+ ATF_REQUIRE(buf != NULL);
+
+ for (size_t i = 0; i < maxiter; i++)
+ ATF_REQUIRE(mlock(buf, page) == 0);
+
+ ATF_REQUIRE(munlock(buf, page) == 0);
+ free(buf);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+ ATF_TP_ADD_TC(tp, mlock_clip);
+ ATF_TP_ADD_TC(tp, mlock_err);
+ ATF_TP_ADD_TC(tp, mlock_limits);
+ ATF_TP_ADD_TC(tp, mlock_mmap);
+ ATF_TP_ADD_TC(tp, mlock_nested);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mmap.c b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c
new file mode 100644
index 000000000000..5d821ecad044
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mmap.c
@@ -0,0 +1,524 @@
+/* $NetBSD: t_mmap.c,v 1.7 2012/06/14 17:47:58 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*-
+ * Copyright (c)2004 YAMAMOTO Takashi,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_mmap.c,v 1.7 2012/06/14 17:47:58 bouyer Exp $");
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+#ifdef __NetBSD__
+#include <machine/disklabel.h>
+#endif
+
+#ifdef __FreeBSD__
+#include <sys/disklabel.h>
+#include <sys/stat.h>
+#include <stdint.h>
+#endif
+
+static long page = 0;
+static char path[] = "mmap";
+static void map_check(void *, int);
+static void map_sighandler(int);
+static void testloan(void *, void *, char, int);
+
+#define BUFSIZE (32 * 1024) /* enough size to trigger sosend_loan */
+
+static void
+map_check(void *map, int flag)
+{
+
+ if (flag != 0) {
+ ATF_REQUIRE(map == MAP_FAILED);
+ return;
+ }
+
+ ATF_REQUIRE(map != MAP_FAILED);
+ ATF_REQUIRE(munmap(map, page) == 0);
+}
+
+void
+testloan(void *vp, void *vp2, char pat, int docheck)
+{
+ char buf[BUFSIZE];
+ char backup[BUFSIZE];
+ ssize_t nwritten;
+ ssize_t nread;
+ int fds[2];
+ int val;
+
+ val = BUFSIZE;
+
+ if (docheck != 0)
+ (void)memcpy(backup, vp, BUFSIZE);
+
+ if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, fds) != 0)
+ atf_tc_fail("socketpair() failed");
+
+ val = BUFSIZE;
+
+ if (setsockopt(fds[1], SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) != 0)
+ atf_tc_fail("setsockopt() failed, SO_RCVBUF");
+
+ val = BUFSIZE;
+
+ if (setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) != 0)
+ atf_tc_fail("setsockopt() failed, SO_SNDBUF");
+
+ if (fcntl(fds[0], F_SETFL, O_NONBLOCK) != 0)
+ atf_tc_fail("fcntl() failed");
+
+ nwritten = write(fds[0], (char *)vp + page, BUFSIZE - page);
+
+ if (nwritten == -1)
+ atf_tc_fail("write() failed");
+
+ /* Break loan. */
+ (void)memset(vp2, pat, BUFSIZE);
+
+ nread = read(fds[1], buf + page, BUFSIZE - page);
+
+ if (nread == -1)
+ atf_tc_fail("read() failed");
+
+ if (nread != nwritten)
+ atf_tc_fail("too short read");
+
+ if (docheck != 0 && memcmp(backup, buf + page, nread) != 0)
+ atf_tc_fail("data mismatch");
+
+ ATF_REQUIRE(close(fds[0]) == 0);
+ ATF_REQUIRE(close(fds[1]) == 0);
+}
+
+static void
+map_sighandler(int signo)
+{
+ _exit(signo);
+}
+
+#ifdef __NetBSD__
+ATF_TC(mmap_block);
+ATF_TC_HEAD(mmap_block, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) with a block device");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(mmap_block, tc)
+{
+ static const int mib[] = { CTL_HW, HW_DISKNAMES };
+ static const unsigned int miblen = __arraycount(mib);
+ char *map, *dk, *drives, dev[PATH_MAX];
+ size_t len;
+ int fd = -1;
+
+ atf_tc_skip("The test case causes a panic (PR kern/38889, kern/46592)");
+
+ ATF_REQUIRE(sysctl(mib, miblen, NULL, &len, NULL, 0) == 0);
+ drives = malloc(len);
+ ATF_REQUIRE(drives != NULL);
+ ATF_REQUIRE(sysctl(mib, miblen, drives, &len, NULL, 0) == 0);
+ for (dk = strtok(drives, " "); dk != NULL; dk = strtok(NULL, " ")) {
+ sprintf(dev, _PATH_DEV "%s%c", dk, 'a'+RAW_PART);
+ fprintf(stderr, "trying: %s\n", dev);
+
+ if ((fd = open(dev, O_RDONLY)) >= 0) {
+ (void)fprintf(stderr, "using %s\n", dev);
+ break;
+ }
+ }
+ free(drives);
+
+ if (fd < 0)
+ atf_tc_skip("failed to find suitable block device");
+
+ map = mmap(NULL, 4096, PROT_READ, MAP_FILE, fd, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ (void)fprintf(stderr, "first byte %x\n", *map);
+ ATF_REQUIRE(close(fd) == 0);
+ (void)fprintf(stderr, "first byte %x\n", *map);
+
+ ATF_REQUIRE(munmap(map, 4096) == 0);
+}
+#endif
+
+ATF_TC(mmap_err);
+ATF_TC_HEAD(mmap_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of mmap(2)");
+}
+
+ATF_TC_BODY(mmap_err, tc)
+{
+ size_t addr = SIZE_MAX;
+ void *map;
+
+ errno = 0;
+ map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, -1, 0);
+
+ ATF_REQUIRE(map == MAP_FAILED);
+ ATF_REQUIRE(errno == EBADF);
+
+ errno = 0;
+ map = mmap(&addr, page, PROT_READ, MAP_FIXED|MAP_PRIVATE, -1, 0);
+
+ ATF_REQUIRE(map == MAP_FAILED);
+ ATF_REQUIRE(errno == EINVAL);
+
+ errno = 0;
+ map = mmap(NULL, page, PROT_READ, MAP_ANON|MAP_PRIVATE, INT_MAX, 0);
+
+ ATF_REQUIRE(map == MAP_FAILED);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+ATF_TC_WITH_CLEANUP(mmap_loan);
+ATF_TC_HEAD(mmap_loan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test uvm page loanout with mmap(2)");
+}
+
+ATF_TC_BODY(mmap_loan, tc)
+{
+ char buf[BUFSIZE];
+ char *vp, *vp2;
+ int fd;
+
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+ ATF_REQUIRE(fd >= 0);
+
+ (void)memset(buf, 'x', sizeof(buf));
+ (void)write(fd, buf, sizeof(buf));
+
+ vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_PRIVATE, fd, 0);
+
+ ATF_REQUIRE(vp != MAP_FAILED);
+
+ vp2 = vp;
+
+ testloan(vp, vp2, 'A', 0);
+ testloan(vp, vp2, 'B', 1);
+
+ ATF_REQUIRE(munmap(vp, BUFSIZE) == 0);
+
+ vp = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, fd, 0);
+
+ vp2 = mmap(NULL, BUFSIZE, PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, fd, 0);
+
+ ATF_REQUIRE(vp != MAP_FAILED);
+ ATF_REQUIRE(vp2 != MAP_FAILED);
+
+ testloan(vp, vp2, 'E', 1);
+
+ ATF_REQUIRE(munmap(vp, BUFSIZE) == 0);
+ ATF_REQUIRE(munmap(vp2, BUFSIZE) == 0);
+}
+
+ATF_TC_CLEANUP(mmap_loan, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mmap_prot_1);
+ATF_TC_HEAD(mmap_prot_1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #1");
+}
+
+ATF_TC_BODY(mmap_prot_1, tc)
+{
+ void *map;
+ int fd;
+
+ /*
+ * Open a file write-only and try to
+ * map it read-only. This should fail.
+ */
+ fd = open(path, O_WRONLY | O_CREAT, 0700);
+
+ if (fd < 0)
+ return;
+
+ ATF_REQUIRE(write(fd, "XXX", 3) == 3);
+
+ map = mmap(NULL, 3, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
+ map_check(map, 1);
+
+ map = mmap(NULL, 3, PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0);
+ map_check(map, 0);
+
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC_CLEANUP(mmap_prot_1, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(mmap_prot_2);
+ATF_TC_HEAD(mmap_prot_2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #2");
+}
+
+ATF_TC_BODY(mmap_prot_2, tc)
+{
+ char buf[2];
+ void *map;
+ pid_t pid;
+ int sta;
+
+ /*
+ * Make a PROT_NONE mapping and try to access it.
+ * If we catch a SIGSEGV, all works as expected.
+ */
+ map = mmap(NULL, page, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR);
+ ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0);
+ }
+
+ (void)wait(&sta);
+
+ ATF_REQUIRE(WIFEXITED(sta) != 0);
+ ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV);
+ ATF_REQUIRE(munmap(map, page) == 0);
+}
+
+ATF_TC_WITH_CLEANUP(mmap_prot_3);
+ATF_TC_HEAD(mmap_prot_3, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) protections, #3");
+}
+
+ATF_TC_BODY(mmap_prot_3, tc)
+{
+ char buf[2];
+ int fd, sta;
+ void *map;
+ pid_t pid;
+
+ /*
+ * Open a file, change the permissions
+ * to read-only, and try to map it as
+ * PROT_NONE. This should succeed, but
+ * the access should generate SIGSEGV.
+ */
+ fd = open(path, O_RDWR | O_CREAT, 0700);
+
+ if (fd < 0)
+ return;
+
+ ATF_REQUIRE(write(fd, "XXX", 3) == 3);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(chmod(path, 0444) == 0);
+
+ fd = open(path, O_RDONLY);
+ ATF_REQUIRE(fd != -1);
+
+ map = mmap(NULL, 3, PROT_NONE, MAP_FILE | MAP_SHARED, fd, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ pid = fork();
+
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ ATF_REQUIRE(signal(SIGSEGV, map_sighandler) != SIG_ERR);
+ ATF_REQUIRE(strlcpy(buf, map, sizeof(buf)) != 0);
+ }
+
+ (void)wait(&sta);
+
+ ATF_REQUIRE(WIFEXITED(sta) != 0);
+ ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV);
+ ATF_REQUIRE(munmap(map, 3) == 0);
+}
+
+ATF_TC_CLEANUP(mmap_prot_3, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(mmap_truncate);
+ATF_TC_HEAD(mmap_truncate, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) and ftruncate(2)");
+}
+
+ATF_TC_BODY(mmap_truncate, tc)
+{
+ char *map;
+ long i;
+ int fd;
+
+ fd = open(path, O_RDWR | O_CREAT, 0700);
+
+ if (fd < 0)
+ return;
+
+ /*
+ * See that ftruncate(2) works
+ * while the file is mapped.
+ */
+ ATF_REQUIRE(ftruncate(fd, page) == 0);
+
+ map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE,
+ fd, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ for (i = 0; i < page; i++)
+ map[i] = 'x';
+
+ ATF_REQUIRE(ftruncate(fd, 0) == 0);
+ ATF_REQUIRE(ftruncate(fd, page / 8) == 0);
+ ATF_REQUIRE(ftruncate(fd, page / 4) == 0);
+ ATF_REQUIRE(ftruncate(fd, page / 2) == 0);
+ ATF_REQUIRE(ftruncate(fd, page / 12) == 0);
+ ATF_REQUIRE(ftruncate(fd, page / 64) == 0);
+
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC_CLEANUP(mmap_truncate, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(mmap_va0);
+ATF_TC_HEAD(mmap_va0, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mmap(2) and vm.user_va0_disable");
+}
+
+ATF_TC_BODY(mmap_va0, tc)
+{
+ int flags = MAP_ANON | MAP_FIXED | MAP_PRIVATE;
+ size_t len = sizeof(int);
+ void *map;
+ int val;
+
+ /*
+ * Make an anonymous fixed mapping at zero address. If the address
+ * is restricted as noted in security(7), the syscall should fail.
+ */
+#ifdef __FreeBSD__
+ if (sysctlbyname("security.bsd.map_at_zero", &val, &len, NULL, 0) != 0)
+ atf_tc_fail("failed to read security.bsd.map_at_zero");
+ val = !val; /* 1 == enable map at zero */
+#endif
+#ifdef __NetBSD__
+ if (sysctlbyname("vm.user_va0_disable", &val, &len, NULL, 0) != 0)
+ atf_tc_fail("failed to read vm.user_va0_disable");
+#endif
+
+ map = mmap(NULL, page, PROT_EXEC, flags, -1, 0);
+ map_check(map, val);
+
+ map = mmap(NULL, page, PROT_READ, flags, -1, 0);
+ map_check(map, val);
+
+ map = mmap(NULL, page, PROT_WRITE, flags, -1, 0);
+ map_check(map, val);
+
+ map = mmap(NULL, page, PROT_READ|PROT_WRITE, flags, -1, 0);
+ map_check(map, val);
+
+ map = mmap(NULL, page, PROT_EXEC|PROT_READ|PROT_WRITE, flags, -1, 0);
+ map_check(map, val);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, mmap_block);
+#endif
+ ATF_TP_ADD_TC(tp, mmap_err);
+ ATF_TP_ADD_TC(tp, mmap_loan);
+ ATF_TP_ADD_TC(tp, mmap_prot_1);
+ ATF_TP_ADD_TC(tp, mmap_prot_2);
+ ATF_TP_ADD_TC(tp, mmap_prot_3);
+ ATF_TP_ADD_TC(tp, mmap_truncate);
+ ATF_TP_ADD_TC(tp, mmap_va0);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c
new file mode 100644
index 000000000000..ee345aadf2c0
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_mprotect.c
@@ -0,0 +1,365 @@
+/* $NetBSD: t_mprotect.c,v 1.3 2011/07/20 22:53:44 jym Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_mprotect.c,v 1.3 2011/07/20 22:53:44 jym Exp $");
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#ifdef __NetBSD__
+#include "../common/exec_prot.h"
+#endif
+
+static long page = 0;
+static int pax_global = -1;
+static int pax_enabled = -1;
+static char path[] = "mmap";
+
+static void sighandler(int);
+static bool paxinit(void);
+static bool paxset(int, int);
+
+static void
+sighandler(int signo)
+{
+ _exit(signo);
+}
+
+static bool
+paxinit(void)
+{
+ size_t len = sizeof(int);
+ int rv;
+
+ rv = sysctlbyname("security.pax.mprotect.global",
+ &pax_global, &len, NULL, 0);
+
+ if (rv != 0)
+ return false;
+
+ rv = sysctlbyname("security.pax.mprotect.enabled",
+ &pax_enabled, &len, NULL, 0);
+
+ if (rv != 0)
+ return false;
+
+ return paxset(1, 1);
+}
+
+static bool
+paxset(int global, int enabled)
+{
+ size_t len = sizeof(int);
+ int rv;
+
+ rv = sysctlbyname("security.pax.mprotect.global",
+ NULL, NULL, &global, len);
+
+ if (rv != 0)
+ return false;
+
+ rv = sysctlbyname("security.pax.mprotect.enabled",
+ NULL, NULL, &enabled, len);
+
+ if (rv != 0)
+ return false;
+
+ return true;
+}
+
+
+ATF_TC_WITH_CLEANUP(mprotect_access);
+ATF_TC_HEAD(mprotect_access, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test for EACCES from mprotect(2)");
+}
+
+ATF_TC_BODY(mprotect_access, tc)
+{
+ int prot[2] = { PROT_NONE, PROT_READ };
+ void *map;
+ size_t i;
+ int fd;
+
+ fd = open(path, O_RDONLY | O_CREAT);
+ ATF_REQUIRE(fd >= 0);
+
+ /*
+ * The call should fail with EACCES if we try to mark
+ * a PROT_NONE or PROT_READ file/section as PROT_WRITE.
+ */
+ for (i = 0; i < __arraycount(prot); i++) {
+
+ map = mmap(NULL, page, prot[i], MAP_SHARED, fd, 0);
+
+ if (map == MAP_FAILED)
+ continue;
+
+ errno = 0;
+
+ ATF_REQUIRE(mprotect(map, page, PROT_WRITE) != 0);
+ ATF_REQUIRE(errno == EACCES);
+ ATF_REQUIRE(munmap(map, page) == 0);
+ }
+
+ ATF_REQUIRE(close(fd) == 0);
+}
+
+ATF_TC_CLEANUP(mprotect_access, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(mprotect_err);
+ATF_TC_HEAD(mprotect_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of mprotect(2)");
+}
+
+ATF_TC_BODY(mprotect_err, tc)
+{
+ errno = 0;
+
+ ATF_REQUIRE(mprotect((char *)-1, 1, PROT_READ) != 0);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+#ifdef __NetBSD__
+ATF_TC(mprotect_exec);
+ATF_TC_HEAD(mprotect_exec, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test mprotect(2) executable space protections");
+}
+
+/*
+ * Trivial function -- should fit into a page
+ */
+ATF_TC_BODY(mprotect_exec, tc)
+{
+ pid_t pid;
+ void *map;
+ int sta, xp_support;
+
+ xp_support = exec_prot_support();
+
+ switch (xp_support) {
+ case NOTIMPL:
+ atf_tc_skip(
+ "Execute protection callback check not implemented");
+ break;
+ case NO_XP:
+ atf_tc_skip(
+ "Host does not support executable space protection");
+ break;
+ case PARTIAL_XP: case PERPAGE_XP: default:
+ break;
+ }
+
+ /*
+ * Map a page read/write and copy a trivial assembly function inside.
+ * We will then change the mapping rights:
+ * - first by setting the execution right, and check that we can
+ * call the code found in the allocated page.
+ * - second by removing the execution right. This should generate
+ * a SIGSEGV on architectures that can enforce --x permissions.
+ */
+
+ map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ memcpy(map, (void *)return_one,
+ (uintptr_t)return_one_end - (uintptr_t)return_one);
+
+ /* give r-x rights then call code in page */
+ ATF_REQUIRE(mprotect(map, page, PROT_EXEC|PROT_READ) == 0);
+ ATF_REQUIRE(((int (*)(void))map)() == 1);
+
+ /* remove --x right */
+ ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR);
+ ATF_CHECK(((int (*)(void))map)() == 1);
+ _exit(0);
+ }
+
+ (void)wait(&sta);
+
+ ATF_REQUIRE(munmap(map, page) == 0);
+
+ ATF_REQUIRE(WIFEXITED(sta) != 0);
+
+ switch (xp_support) {
+ case PARTIAL_XP:
+ /* Partial protection might fail; skip the test when it does */
+ if (WEXITSTATUS(sta) != SIGSEGV) {
+ atf_tc_skip("Host only supports "
+ "partial executable space protection");
+ }
+ break;
+ case PERPAGE_XP: default:
+ /* Per-page --x protection should not fail */
+ ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV);
+ break;
+ }
+}
+#endif
+
+ATF_TC(mprotect_pax);
+ATF_TC_HEAD(mprotect_pax, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "PaX restrictions and mprotect(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(mprotect_pax, tc)
+{
+ const int prot[4] = { PROT_NONE, PROT_READ, PROT_WRITE };
+ const char *str = NULL;
+ void *map;
+ size_t i;
+ int rv;
+
+ if (paxinit() != true)
+ return;
+
+ /*
+ * As noted in the original PaX documentation [1],
+ * the following restrictions should apply:
+ *
+ * (1) creating executable anonymous mappings
+ *
+ * (2) creating executable/writable file mappings
+ *
+ * (3) making a non-executable mapping executable
+ *
+ * (4) making an executable/read-only file mapping
+ * writable except for performing relocations
+ * on an ET_DYN ELF file (non-PIC shared library)
+ *
+ * The following will test only the case (3).
+ *
+ * [1] http://pax.grsecurity.net/docs/mprotect.txt
+ *
+ * (Sun Apr 3 11:06:53 EEST 2011.)
+ */
+ for (i = 0; i < __arraycount(prot); i++) {
+
+ map = mmap(NULL, page, prot[i], MAP_ANON, -1, 0);
+
+ if (map == MAP_FAILED)
+ continue;
+
+ rv = mprotect(map, 1, prot[i] | PROT_EXEC);
+
+ (void)munmap(map, page);
+
+ if (rv == 0) {
+ str = "non-executable mapping made executable";
+ goto out;
+ }
+ }
+
+out:
+ if (pax_global != -1 && pax_enabled != -1)
+ (void)paxset(pax_global, pax_enabled);
+
+ if (str != NULL)
+ atf_tc_fail("%s", str);
+}
+
+ATF_TC(mprotect_write);
+ATF_TC_HEAD(mprotect_write, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test mprotect(2) write protections");
+}
+
+ATF_TC_BODY(mprotect_write, tc)
+{
+ pid_t pid;
+ void *map;
+ int sta;
+
+ /*
+ * Map a page read/write, change the protection
+ * to read-only with mprotect(2), and try to write
+ * to the page. This should generate a SIGSEGV.
+ */
+ map = mmap(NULL, page, PROT_WRITE|PROT_READ, MAP_ANON, -1, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ ATF_REQUIRE(strlcpy(map, "XXX", 3) == 3);
+ ATF_REQUIRE(mprotect(map, page, PROT_READ) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ ATF_REQUIRE(signal(SIGSEGV, sighandler) != SIG_ERR);
+ ATF_REQUIRE(strlcpy(map, "XXX", 3) == 0);
+ }
+
+ (void)wait(&sta);
+
+ ATF_REQUIRE(WIFEXITED(sta) != 0);
+ ATF_REQUIRE(WEXITSTATUS(sta) == SIGSEGV);
+ ATF_REQUIRE(munmap(map, page) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+ ATF_TP_ADD_TC(tp, mprotect_access);
+ ATF_TP_ADD_TC(tp, mprotect_err);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, mprotect_exec);
+#endif
+ ATF_TP_ADD_TC(tp, mprotect_pax);
+ ATF_TP_ADD_TC(tp, mprotect_write);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c b/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c
new file mode 100644
index 000000000000..b9b306742699
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msgctl.c
@@ -0,0 +1,362 @@
+/* $NetBSD: t_msgctl.c,v 1.4 2014/02/27 00:59:50 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_msgctl.c,v 1.4 2014/02/27 00:59:50 joerg Exp $");
+
+#include <sys/msg.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+#define MSG_KEY 12345689
+#define MSG_MTYPE_1 0x41
+
+struct msg {
+ long mtype;
+ char buf[3];
+};
+
+static void clean(void);
+
+static void
+clean(void)
+{
+ int id;
+
+ if ((id = msgget(MSG_KEY, 0)) != -1)
+ (void)msgctl(id, IPC_RMID, 0);
+}
+
+ATF_TC_WITH_CLEANUP(msgctl_err);
+ATF_TC_HEAD(msgctl_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from msgctl(2)");
+}
+
+ATF_TC_BODY(msgctl_err, tc)
+{
+ const int cmd[] = { IPC_STAT, IPC_SET, IPC_RMID };
+ struct msqid_ds msgds;
+ size_t i;
+ int id;
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, msgctl(id, INT_MAX, &msgds) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, msgctl(id, IPC_STAT, (void *)-1) == -1);
+
+ for (i = 0; i < __arraycount(cmd); i++) {
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, msgctl(-1, cmd[i], &msgds) == -1);
+ }
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgctl_err, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgctl_perm);
+ATF_TC_HEAD(msgctl_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with msgctl(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(msgctl_perm, tc)
+{
+ struct msqid_ds msgds;
+ struct passwd *pw;
+ pid_t pid;
+ int sta;
+ int id;
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ pw = getpwnam("nobody");
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+
+ ATF_REQUIRE(id != -1);
+ ATF_REQUIRE(pw != NULL);
+ ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (setuid(pw->pw_uid) != 0)
+ _exit(EX_OSERR);
+
+ msgds.msg_perm.uid = getuid();
+ msgds.msg_perm.gid = getgid();
+
+ errno = 0;
+
+ if (msgctl(id, IPC_SET, &msgds) == 0)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EPERM)
+ _exit(EXIT_FAILURE);
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ if (msgctl(id, IPC_STAT, &msgds) != 0)
+ _exit(EX_OSERR);
+
+ msgds.msg_qbytes = 1;
+
+ if (msgctl(id, IPC_SET, &msgds) == 0)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EPERM)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0) {
+
+ if (WEXITSTATUS(sta) == EX_OSERR)
+ atf_tc_fail("system call failed");
+
+ if (WEXITSTATUS(sta) == EXIT_FAILURE)
+ atf_tc_fail("UID %u manipulated root's "
+ "message queue", pw->pw_uid);
+ }
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgctl_perm, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgctl_pid);
+ATF_TC_HEAD(msgctl_pid, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that PIDs are updated");
+}
+
+ATF_TC_BODY(msgctl_pid, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msqid_ds msgds;
+ int id, sta;
+ pid_t pid;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)sleep(1);
+ (void)wait(&sta);
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
+
+ if (pid != msgds.msg_lspid)
+ atf_tc_fail("the PID of last msgsnd(2) was not updated");
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ (void)msgrcv(id, &msg,
+ sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)sleep(1);
+ (void)wait(&sta);
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
+
+ if (pid != msgds.msg_lrpid)
+ atf_tc_fail("the PID of last msgrcv(2) was not updated");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgctl_pid, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgctl_set);
+ATF_TC_HEAD(msgctl_set, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test msgctl(2) with IPC_SET");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(msgctl_set, tc)
+{
+ struct msqid_ds msgds;
+ struct passwd *pw;
+ int id;
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+
+ pw = getpwnam("nobody");
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+
+ ATF_REQUIRE(id != -1);
+ ATF_REQUIRE(pw != NULL);
+ ATF_REQUIRE(msgctl(id, IPC_STAT, &msgds) == 0);
+
+ msgds.msg_perm.uid = pw->pw_uid;
+
+ if (msgctl(id, IPC_SET, &msgds) != 0)
+ atf_tc_fail("root failed to change the UID of message queue");
+
+ msgds.msg_perm.uid = getuid();
+ msgds.msg_perm.gid = pw->pw_gid;
+
+ if (msgctl(id, IPC_SET, &msgds) != 0)
+ atf_tc_fail("root failed to change the GID of message queue");
+
+ /*
+ * Note: setting the qbytes to zero fails even as root.
+ */
+ msgds.msg_qbytes = 1;
+ msgds.msg_perm.gid = getgid();
+
+ if (msgctl(id, IPC_SET, &msgds) != 0)
+ atf_tc_fail("root failed to change qbytes of message queue");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgctl_set, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgctl_time);
+ATF_TC_HEAD(msgctl_time, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that access times are updated");
+}
+
+ATF_TC_BODY(msgctl_time, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msqid_ds msgds;
+ time_t t;
+ int id;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ t = time(NULL);
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+ (void)msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
+ (void)msgctl(id, IPC_STAT, &msgds);
+
+ if (llabs(t - msgds.msg_stime) > 1)
+ atf_tc_fail("time of last msgsnd(2) was not updated");
+
+ if (msgds.msg_rtime != 0)
+ atf_tc_fail("time of last msgrcv(2) was updated incorrectly");
+
+ t = time(NULL);
+
+ (void)memset(&msgds, 0, sizeof(struct msqid_ds));
+ (void)msgrcv(id, &msg, sizeof(struct msg), MSG_MTYPE_1, IPC_NOWAIT);
+ (void)msgctl(id, IPC_STAT, &msgds);
+
+ if (llabs(t - msgds.msg_rtime) > 1)
+ atf_tc_fail("time of last msgrcv(2) was not updated");
+
+ /*
+ * Note: this is non-zero even after the memset(3).
+ */
+ if (msgds.msg_stime == 0)
+ atf_tc_fail("time of last msgsnd(2) was updated incorrectly");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgctl_time, tc)
+{
+ clean();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, msgctl_err);
+ ATF_TP_ADD_TC(tp, msgctl_perm);
+ ATF_TP_ADD_TC(tp, msgctl_pid);
+ ATF_TP_ADD_TC(tp, msgctl_set);
+ ATF_TP_ADD_TC(tp, msgctl_time);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgget.c b/contrib/netbsd-tests/lib/libc/sys/t_msgget.c
new file mode 100644
index 000000000000..e26cde2ddfe6
--- /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 000000000000..70f890682a76
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msgrcv.c
@@ -0,0 +1,346 @@
+/* $NetBSD: t_msgrcv.c,v 1.3 2013/07/24 11:44:10 skrll Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_msgrcv.c,v 1.3 2013/07/24 11:44:10 skrll Exp $");
+
+#include <sys/msg.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+#define MSG_KEY 1234
+#define MSG_MTYPE_1 0x41
+#define MSG_MTYPE_2 0x42
+#define MSG_MTYPE_3 0x43
+#define MSG_LEN 3
+
+struct msg {
+ long mtype;
+ char buf[MSG_LEN];
+};
+
+static void clean(void);
+
+static void
+clean(void)
+{
+ int id;
+
+ if ((id = msgget(MSG_KEY, 0)) != -1)
+ (void)msgctl(id, IPC_RMID, 0);
+}
+
+ATF_TC_WITH_CLEANUP(msgrcv_basic);
+ATF_TC_HEAD(msgrcv_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of msgrcv(2)");
+}
+
+ATF_TC_BODY(msgrcv_basic, tc)
+{
+ struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msg msg2 = { MSG_MTYPE_1, { 'x', 'y', 'z' } };
+ int id;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT);
+ (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT);
+
+ ATF_CHECK(msg1.buf[0] == msg2.buf[0]);
+ ATF_CHECK(msg1.buf[1] == msg2.buf[1]);
+ ATF_CHECK(msg1.buf[2] == msg2.buf[2]);
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_basic, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgrcv_block);
+ATF_TC_HEAD(msgrcv_block, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that msgrcv(2) blocks");
+}
+
+ATF_TC_BODY(msgrcv_block, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ int id, sta;
+ pid_t pid;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1, 0) < 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ /*
+ * Below msgsnd(2) should unblock the child,
+ * and hence kill(2) should fail with ESRCH.
+ */
+ (void)sleep(1);
+ (void)msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT);
+ (void)sleep(1);
+ (void)kill(pid, SIGKILL);
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0)
+ atf_tc_fail("msgrcv(2) did not block");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_block, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgrcv_err);
+ATF_TC_HEAD(msgrcv_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from msgrcv(2)");
+}
+
+ATF_TC_BODY(msgrcv_err, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ int id, r = 0;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(ENOMSG, msgrcv(id, &msg,
+ MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1);
+
+ ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EFAULT, msgrcv(id, (void *)-1,
+ MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg,
+ MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT) == -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EINVAL, msgrcv(-1, &msg,
+ SSIZE_MAX, MSG_MTYPE_1, IPC_NOWAIT) == -1);
+
+ ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(E2BIG, msgrcv(id, &r,
+ MSG_LEN - 1, MSG_MTYPE_1, IPC_NOWAIT) == -1);
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_err, tc)
+{
+ clean();
+}
+
+
+ATF_TC_WITH_CLEANUP(msgrcv_mtype);
+ATF_TC_HEAD(msgrcv_mtype, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test message types with msgrcv(2)");
+}
+
+ATF_TC_BODY(msgrcv_mtype, tc)
+{
+ struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msg msg2 = { MSG_MTYPE_3, { 'x', 'y', 'z' } };
+ int id;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT);
+ (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_2, IPC_NOWAIT);
+
+ ATF_CHECK(msg1.buf[0] != msg2.buf[0]); /* Different mtype. */
+ ATF_CHECK(msg1.buf[1] != msg2.buf[1]);
+ ATF_CHECK(msg1.buf[2] != msg2.buf[2]);
+
+ (void)msgrcv(id, &msg2, MSG_LEN, MSG_MTYPE_1, IPC_NOWAIT);
+
+ ATF_CHECK(msg1.buf[0] == msg2.buf[0]); /* Same mtype. */
+ ATF_CHECK(msg1.buf[1] == msg2.buf[1]);
+ ATF_CHECK(msg1.buf[2] == msg2.buf[2]);
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_mtype, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgrcv_nonblock);
+ATF_TC_HEAD(msgrcv_nonblock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with IPC_NOWAIT");
+ atf_tc_set_md_var(tc, "timeout", "10");
+}
+
+ATF_TC_BODY(msgrcv_nonblock, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ const ssize_t n = 10;
+ int id, sta;
+ ssize_t i;
+ pid_t pid;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ for (i = 0; i < n; i++) {
+
+ ATF_REQUIRE(msgsnd(id, &msg, MSG_LEN, IPC_NOWAIT) == 0);
+ }
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ while (i != 0) {
+
+ if (msgrcv(id, &msg, MSG_LEN, MSG_MTYPE_1,
+ IPC_NOWAIT) == -1)
+ _exit(EXIT_FAILURE);
+
+ i--;
+ }
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)sleep(2);
+ (void)kill(pid, SIGKILL);
+ (void)wait(&sta);
+
+ if (WIFSIGNALED(sta) != 0 || WTERMSIG(sta) == SIGKILL)
+ atf_tc_fail("msgrcv(2) blocked with IPC_NOWAIT");
+
+ if (WIFEXITED(sta) == 0 && WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("msgrcv(2) failed");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_nonblock, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgrcv_truncate);
+ATF_TC_HEAD(msgrcv_truncate, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test msgrcv(2) with MSG_NOERROR");
+}
+
+ATF_TC_BODY(msgrcv_truncate, tc)
+{
+#define MSG_SMALLLEN 2
+ struct msgsmall {
+ long mtype;
+ char buf[MSG_SMALLLEN];
+ };
+
+ struct msg msg1 = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msgsmall msg2 = { MSG_MTYPE_1, { 'x', 'y' } };
+ int id;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ (void)msgsnd(id, &msg1, MSG_LEN, IPC_NOWAIT);
+ (void)msgrcv(id, &msg2, MSG_SMALLLEN,
+ MSG_MTYPE_1, IPC_NOWAIT | MSG_NOERROR);
+
+ ATF_CHECK(msg1.buf[0] == msg2.buf[0]);
+ ATF_CHECK(msg1.buf[1] == msg2.buf[1]);
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgrcv_truncate, tc)
+{
+ clean();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, msgrcv_basic);
+ ATF_TP_ADD_TC(tp, msgrcv_block);
+ ATF_TP_ADD_TC(tp, msgrcv_err);
+ ATF_TP_ADD_TC(tp, msgrcv_mtype);
+ ATF_TP_ADD_TC(tp, msgrcv_nonblock);
+ ATF_TP_ADD_TC(tp, msgrcv_truncate);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c
new file mode 100644
index 000000000000..d30cb7b97f26
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msgsnd.c
@@ -0,0 +1,342 @@
+/* $NetBSD: t_msgsnd.c,v 1.2 2011/11/05 08:47:54 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_msgsnd.c,v 1.2 2011/11/05 08:47:54 jruoho Exp $");
+
+#include <sys/msg.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+#define MSG_KEY 1234
+#define MSG_MTYPE_1 0x41
+#define MSG_MTYPE_2 0x42
+#define MSG_MTYPE_3 0x43
+
+struct msg {
+ long mtype;
+ char buf[3];
+};
+
+static void clean(void);
+
+static void
+clean(void)
+{
+ int id;
+
+ if ((id = msgget(MSG_KEY, 0)) != -1)
+ (void)msgctl(id, IPC_RMID, 0);
+}
+
+ATF_TC_WITH_CLEANUP(msgsnd_block);
+ATF_TC_HEAD(msgsnd_block, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that msgsnd(2) blocks");
+ atf_tc_set_md_var(tc, "timeout", "10");
+}
+
+ATF_TC_BODY(msgsnd_block, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ int id, sta;
+ pid_t pid;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * Enqueue messages until some limit (e.g. the maximum
+ * number of messages in the queue or the maximum number
+ * of bytes in the queue) is reached. After this the call
+ * should block when the IPC_NOWAIT is not set.
+ */
+ for (;;) {
+
+ if (msgsnd(id, &msg, sizeof(struct msg), 0) < 0)
+ _exit(EXIT_FAILURE);
+ }
+ }
+
+ (void)sleep(2);
+ (void)kill(pid, SIGKILL);
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) != 0 || WIFSIGNALED(sta) == 0)
+ atf_tc_fail("msgsnd(2) did not block");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgsnd_block, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgsnd_count);
+ATF_TC_HEAD(msgsnd_count, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test that msgsnd(2) increments the amount of "
+ "message in the queue, as given by msgctl(2)");
+ atf_tc_set_md_var(tc, "timeout", "10");
+}
+
+ATF_TC_BODY(msgsnd_count, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct msqid_ds ds;
+ size_t i = 0;
+ int id, rv;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ for (;;) {
+
+ errno = 0;
+ rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
+
+ if (rv == 0) {
+ i++;
+ continue;
+ }
+
+ if (rv == -1 && errno == EAGAIN)
+ break;
+
+ atf_tc_fail("failed to enqueue a message");
+ }
+
+ (void)memset(&ds, 0, sizeof(struct msqid_ds));
+ (void)msgctl(id, IPC_STAT, &ds);
+
+ if (ds.msg_qnum != i)
+ atf_tc_fail("incorrect message count");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgsnd_count, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgsnd_err);
+ATF_TC_HEAD(msgsnd_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from msgsnd(2)");
+}
+
+ATF_TC_BODY(msgsnd_err, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ int id;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EFAULT, msgsnd(id, (void *)-1,
+ sizeof(struct msg), IPC_NOWAIT) == -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg,
+ sizeof(struct msg), IPC_NOWAIT) == -1);
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EINVAL, msgsnd(-1, &msg,
+ SSIZE_MAX, IPC_NOWAIT) == -1);
+
+ errno = 0;
+ msg.mtype = 0;
+
+ ATF_REQUIRE_ERRNO(EINVAL, msgsnd(id, &msg,
+ sizeof(struct msg), IPC_NOWAIT) == -1);
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgsnd_err, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgsnd_nonblock);
+ATF_TC_HEAD(msgsnd_nonblock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test msgsnd(2) with IPC_NOWAIT");
+ atf_tc_set_md_var(tc, "timeout", "10");
+}
+
+ATF_TC_BODY(msgsnd_nonblock, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ int id, rv, sta;
+ pid_t pid;
+
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+ ATF_REQUIRE(id != -1);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ for (;;) {
+
+ errno = 0;
+ rv = msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT);
+
+ if (rv == -1 && errno == EAGAIN)
+ _exit(EXIT_SUCCESS);
+ }
+ }
+
+ (void)sleep(2);
+ (void)kill(pid, SIGKILL);
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WIFSIGNALED(sta) != 0)
+ atf_tc_fail("msgsnd(2) blocked with IPC_NOWAIT");
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgsnd_nonblock, tc)
+{
+ clean();
+}
+
+ATF_TC_WITH_CLEANUP(msgsnd_perm);
+ATF_TC_HEAD(msgsnd_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with msgsnd(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(msgsnd_perm, tc)
+{
+ struct msg msg = { MSG_MTYPE_1, { 'a', 'b', 'c' } };
+ struct passwd *pw;
+ int id, sta;
+ pid_t pid;
+ uid_t uid;
+
+ pw = getpwnam("nobody");
+ id = msgget(MSG_KEY, IPC_CREAT | 0600);
+
+ ATF_REQUIRE(id != -1);
+ ATF_REQUIRE(pw != NULL);
+
+ uid = pw->pw_uid;
+ ATF_REQUIRE(uid != 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * Try to enqueue a message to the queue
+ * created by root as RW for owner only.
+ */
+ if (setuid(uid) != 0)
+ _exit(EX_OSERR);
+
+ id = msgget(MSG_KEY, 0);
+
+ if (id == -1)
+ _exit(EX_OSERR);
+
+ errno = 0;
+
+ if (msgsnd(id, &msg, sizeof(struct msg), IPC_NOWAIT) == 0)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EACCES)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
+
+ if (errno == EX_OSERR)
+ atf_tc_fail("system call failed");
+
+ atf_tc_fail("UID %u enqueued message to root's queue", uid);
+ }
+
+ ATF_REQUIRE(msgctl(id, IPC_RMID, 0) == 0);
+}
+
+ATF_TC_CLEANUP(msgsnd_perm, tc)
+{
+ clean();
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, msgsnd_block);
+ ATF_TP_ADD_TC(tp, msgsnd_count);
+ ATF_TP_ADD_TC(tp, msgsnd_err);
+ ATF_TP_ADD_TC(tp, msgsnd_nonblock);
+ ATF_TP_ADD_TC(tp, msgsnd_perm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_msync.c b/contrib/netbsd-tests/lib/libc/sys/t_msync.c
new file mode 100644
index 000000000000..70d0ccf69df1
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_msync.c
@@ -0,0 +1,248 @@
+/* $NetBSD: t_msync.c,v 1.2 2012/03/16 06:15:17 matt Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_msync.c,v 1.2 2012/03/16 06:15:17 matt Exp $");
+
+#include <sys/mman.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static long page = 0;
+static const off_t off = 512;
+static const char path[] = "msync";
+
+static const char *msync_sync(const char *, int);
+
+static const char *
+msync_sync(const char *garbage, int flags)
+{
+ char *buf, *map = MAP_FAILED;
+ const char *str = NULL;
+ size_t i, len;
+ ssize_t tot;
+ int fd, rv;
+
+ /*
+ * Create a temporary file, write
+ * one page to it, and map the file.
+ */
+ buf = malloc(page);
+
+ if (buf == NULL)
+ return NULL;
+
+ for (i = 0; i < (size_t)page; i++)
+ buf[i] = 'x';
+
+ fd = open(path, O_RDWR | O_CREAT, 0700);
+
+ if (fd < 0) {
+ str = "failed to open";
+ goto out;
+ }
+
+ tot = 0;
+
+ while (tot < page) {
+
+ rv = write(fd, buf, sizeof(buf));
+
+ if (rv < 0) {
+ str = "failed to write";
+ goto out;
+ }
+
+ tot += rv;
+ }
+
+ map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_FILE|MAP_PRIVATE,
+ fd, 0);
+
+ if (map == MAP_FAILED) {
+ str = "failed to map";
+ goto out;
+ }
+
+ /*
+ * Seek to an arbitrary offset and
+ * write garbage to this position.
+ */
+ if (lseek(fd, off, SEEK_SET) != off) {
+ str = "failed to seek";
+ goto out;
+ }
+
+ len = strlen(garbage);
+ rv = write(fd, garbage, len);
+
+ if (rv != (ssize_t)len) {
+ str = "failed to write garbage";
+ goto out;
+ }
+
+ /*
+ * Synchronize the mapping and verify
+ * that garbage is at the given offset.
+ */
+ if (msync(map, page, flags) != 0) {
+ str = "failed to msync";
+ goto out;
+ }
+
+ if (memcmp(map + off, garbage, len) != 0) {
+ str = "msync did not synchronize";
+ goto out;
+ }
+
+out:
+ free(buf);
+
+ (void)close(fd);
+ (void)unlink(path);
+
+ if (map != MAP_FAILED)
+ (void)munmap(map, page);
+
+ return str;
+}
+
+ATF_TC(msync_async);
+ATF_TC_HEAD(msync_async, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_ASYNC");
+}
+
+ATF_TC_BODY(msync_async, tc)
+{
+ const char *str;
+
+ str = msync_sync("garbage", MS_ASYNC);
+
+ if (str != NULL)
+ atf_tc_fail("%s", str);
+}
+
+ATF_TC(msync_err);
+ATF_TC_HEAD(msync_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions in msync(2)");
+}
+
+ATF_TC_BODY(msync_err, tc)
+{
+
+ char *map = MAP_FAILED;
+
+ /*
+ * Test that invalid flags error out.
+ */
+#ifdef __FreeBSD__
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, msync_sync("error", -1) != NULL);
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, msync_sync("error", INT_MAX) != NULL);
+#else
+ ATF_REQUIRE(msync_sync("error", -1) != NULL);
+ ATF_REQUIRE(msync_sync("error", INT_MAX) != NULL);
+#endif
+
+ errno = 0;
+
+ /*
+ * Map a page and then unmap to get an unmapped address.
+ */
+ map = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
+ -1, 0);
+ ATF_REQUIRE(map != MAP_FAILED);
+
+ (void)munmap(map, page);
+
+ ATF_REQUIRE(msync(map, page, MS_SYNC) != 0);
+#ifdef __FreeBSD__
+ ATF_REQUIRE(errno == ENOMEM);
+#else
+ ATF_REQUIRE(errno == EFAULT);
+#endif
+}
+
+ATF_TC(msync_invalidate);
+ATF_TC_HEAD(msync_invalidate, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_INVALIDATE");
+}
+
+ATF_TC_BODY(msync_invalidate, tc)
+{
+ const char *str;
+
+ str = msync_sync("garbage", MS_INVALIDATE);
+
+ if (str != NULL)
+ atf_tc_fail("%s", str);
+}
+
+ATF_TC(msync_sync);
+ATF_TC_HEAD(msync_sync, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test of msync(2), MS_SYNC");
+}
+
+ATF_TC_BODY(msync_sync, tc)
+{
+ const char *str;
+
+ str = msync_sync("garbage", MS_SYNC);
+
+ if (str != NULL)
+ atf_tc_fail("%s", str);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ page = sysconf(_SC_PAGESIZE);
+
+ ATF_REQUIRE(page >= 0);
+ ATF_REQUIRE(page > off);
+
+ ATF_TP_ADD_TC(tp, msync_async);
+ ATF_TP_ADD_TC(tp, msync_err);
+ ATF_TP_ADD_TC(tp, msync_invalidate);
+ ATF_TP_ADD_TC(tp, msync_sync);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c
new file mode 100644
index 000000000000..b4d9f8a809eb
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_nanosleep.c
@@ -0,0 +1,191 @@
+/* $NetBSD: t_nanosleep.c,v 1.3 2013/03/31 16:47:16 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_nanosleep.c,v 1.3 2013/03/31 16:47:16 christos Exp $");
+
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <time.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+static void
+#ifdef __FreeBSD__
+handler(int signo __unused)
+#else
+handler(int signo)
+#endif
+{
+ /* Nothing. */
+}
+
+ATF_TC(nanosleep_basic);
+ATF_TC_HEAD(nanosleep_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that nanosleep(2) works");
+}
+
+ATF_TC_BODY(nanosleep_basic, tc)
+{
+ static const size_t maxiter = 10;
+ struct timespec ts1, ts2, tsn;
+ size_t i;
+
+ for (i = 1; i < maxiter; i++) {
+
+ tsn.tv_sec = 0;
+ tsn.tv_nsec = i;
+
+ (void)memset(&ts1, 0, sizeof(struct timespec));
+ (void)memset(&ts2, 0, sizeof(struct timespec));
+
+ ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts1) == 0);
+ ATF_REQUIRE(nanosleep(&tsn, NULL) == 0);
+ ATF_REQUIRE(clock_gettime(CLOCK_MONOTONIC, &ts2) == 0);
+
+ /*
+ * Verify that we slept at least one nanosecond.
+ */
+ if (timespeccmp(&ts2, &ts1, <=) != 0) {
+
+ (void)fprintf(stderr,
+ "sleep time:: sec %llu, nsec %lu\n\t\t"
+ "ts1: sec %llu, nsec %lu\n\t\t"
+ "ts2: sec %llu, nsec %lu\n",
+ (unsigned long long)tsn.tv_sec, tsn.tv_nsec,
+ (unsigned long long)ts1.tv_sec, ts1.tv_nsec,
+ (unsigned long long)ts2.tv_sec, ts2.tv_nsec);
+
+ atf_tc_fail_nonfatal("inaccuracies in sleep time "
+ "(resolution = %lu nsec)", tsn.tv_nsec);
+ }
+ }
+}
+
+ATF_TC(nanosleep_err);
+ATF_TC_HEAD(nanosleep_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test errors from nanosleep(2) (PR bin/14558)");
+}
+
+ATF_TC_BODY(nanosleep_err, tc)
+{
+ struct timespec ts;
+
+ ts.tv_sec = 1;
+ ts.tv_nsec = -1;
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, nanosleep(&ts, NULL) == -1);
+
+ ts.tv_sec = 1;
+ ts.tv_nsec = 1000000000;
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, nanosleep(&ts, NULL) == -1);
+
+ ts.tv_sec = -1;
+ ts.tv_nsec = 0;
+ errno = 0;
+ ATF_REQUIRE_ERRNO(0, nanosleep(&ts, NULL) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, nanosleep((void *)-1, NULL) == -1);
+}
+
+ATF_TC(nanosleep_sig);
+ATF_TC_HEAD(nanosleep_sig, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test signal for nanosleep(2)");
+}
+
+ATF_TC_BODY(nanosleep_sig, tc)
+{
+ struct timespec tsn, tsr;
+ pid_t pid;
+ int sta;
+
+ /*
+ * Test that a signal interrupts nanosleep(2).
+ *
+ * (In which case the return value should be -1 and the
+ * second parameter should contain the unslept time.)
+ */
+ pid = fork();
+
+ ATF_REQUIRE(pid >= 0);
+ ATF_REQUIRE(signal(SIGINT, handler) == 0);
+
+ if (pid == 0) {
+
+ tsn.tv_sec = 10;
+ tsn.tv_nsec = 0;
+
+ tsr.tv_sec = 0;
+ tsr.tv_nsec = 0;
+
+ errno = 0;
+
+ if (nanosleep(&tsn, &tsr) != -1)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EINTR)
+ _exit(EXIT_FAILURE);
+
+ if (tsr.tv_sec == 0 && tsr.tv_nsec == 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)sleep(1);
+ (void)kill(pid, SIGINT);
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("signal did not interrupt nanosleep(2)");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, nanosleep_basic);
+ ATF_TP_ADD_TC(tp, nanosleep_err);
+ ATF_TP_ADD_TC(tp, nanosleep_sig);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_pipe.c b/contrib/netbsd-tests/lib/libc/sys/t_pipe.c
new file mode 100644
index 000000000000..b30b94df702f
--- /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 000000000000..8208cf79231f
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_pipe2.c
@@ -0,0 +1,210 @@
+/* $NetBSD: t_pipe2.c,v 1.8 2012/05/16 13:54:28 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_pipe2.c,v 1.8 2012/05/16 13:54:28 jruoho Exp $");
+
+#include <atf-c.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/resource.h>
+
+static void
+run(int flags)
+{
+ int fd[2], i;
+
+ while ((i = open("/", O_RDONLY)) < 3)
+ ATF_REQUIRE(i != -1);
+
+#ifdef __FreeBSD__
+ closefrom(3);
+#else
+ ATF_REQUIRE(fcntl(3, F_CLOSEM) != -1);
+#endif
+
+ ATF_REQUIRE(pipe2(fd, flags) == 0);
+
+ ATF_REQUIRE(fd[0] == 3);
+ ATF_REQUIRE(fd[1] == 4);
+
+ if (flags & O_CLOEXEC) {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0);
+ } else {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0);
+ }
+
+ if (flags & O_NONBLOCK) {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0);
+ } else {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0);
+ }
+
+#ifndef __FreeBSD__
+ if (flags & O_NOSIGPIPE) {
+ ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) != 0);
+ ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) != 0);
+ } else {
+ ATF_REQUIRE(fcntl(fd[0], F_GETNOSIGPIPE) == 0);
+ ATF_REQUIRE(fcntl(fd[1], F_GETNOSIGPIPE) == 0);
+ }
+#endif
+
+ ATF_REQUIRE(close(fd[0]) != -1);
+ ATF_REQUIRE(close(fd[1]) != -1);
+}
+
+ATF_TC(pipe2_basic);
+ATF_TC_HEAD(pipe2_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of pipe2(2)");
+}
+
+ATF_TC_BODY(pipe2_basic, tc)
+{
+ run(0);
+}
+
+ATF_TC(pipe2_consume);
+ATF_TC_HEAD(pipe2_consume, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test that consuming file descriptors "
+ "with pipe2(2) does not crash the system (PR kern/46457)");
+}
+
+ATF_TC_BODY(pipe2_consume, tc)
+{
+ struct rlimit rl;
+ int err, filedes[2];
+#ifdef __FreeBSD__
+ int old;
+
+ closefrom(4);
+#else
+ err = fcntl(4, F_CLOSEM);
+ ATF_REQUIRE(err == 0);
+#endif
+
+ err = getrlimit(RLIMIT_NOFILE, &rl);
+ ATF_REQUIRE(err == 0);
+ /*
+ * The heart of this test is to run against the number of open
+ * file descriptor limit in the middle of a pipe2() call - i.e.
+ * before the call only a single descriptor may be openend.
+ */
+#ifdef __FreeBSD__
+ old = rl.rlim_cur;
+#endif
+ rl.rlim_cur = 4;
+ err = setrlimit(RLIMIT_NOFILE, &rl);
+ ATF_REQUIRE(err == 0);
+
+ err = pipe2(filedes, O_CLOEXEC);
+ ATF_REQUIRE(err == -1);
+#ifdef __FreeBSD__
+ rl.rlim_cur = old;
+ err = setrlimit(RLIMIT_NOFILE, &rl);
+#endif
+}
+
+ATF_TC(pipe2_nonblock);
+ATF_TC_HEAD(pipe2_nonblock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A non-blocking test of pipe2(2)");
+}
+
+ATF_TC_BODY(pipe2_nonblock, tc)
+{
+ run(O_NONBLOCK);
+}
+
+ATF_TC(pipe2_cloexec);
+ATF_TC_HEAD(pipe2_cloexec, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A close-on-exec test of pipe2(2)");
+}
+
+ATF_TC_BODY(pipe2_cloexec, tc)
+{
+ run(O_CLOEXEC);
+}
+
+#ifdef __NetBSD__
+ATF_TC(pipe2_nosigpipe);
+ATF_TC_HEAD(pipe2_nosigpipe, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A no sigpipe test of pipe2(2)");
+}
+
+ATF_TC_BODY(pipe2_nosigpipe, tc)
+{
+ run(O_NOSIGPIPE);
+}
+#endif
+
+ATF_TC(pipe2_einval);
+ATF_TC_HEAD(pipe2_einval, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A error check of pipe2(2)");
+}
+
+ATF_TC_BODY(pipe2_einval, tc)
+{
+ int fd[2];
+ ATF_REQUIRE_ERRNO(EINVAL, pipe2(fd, O_ASYNC) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, pipe2_basic);
+ ATF_TP_ADD_TC(tp, pipe2_consume);
+ ATF_TP_ADD_TC(tp, pipe2_nonblock);
+ ATF_TP_ADD_TC(tp, pipe2_cloexec);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, pipe2_nosigpipe);
+#endif
+ ATF_TP_ADD_TC(tp, pipe2_einval);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_poll.c b/contrib/netbsd-tests/lib/libc/sys/t_poll.c
new file mode 100644
index 000000000000..621448638372
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_poll.c
@@ -0,0 +1,396 @@
+/* $NetBSD: t_poll.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matthias Scheler.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <paths.h>
+#include <poll.h>
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+
+static int desc;
+
+static void
+child1(void)
+{
+ struct pollfd pfd;
+
+ pfd.fd = desc;
+ pfd.events = POLLIN | POLLHUP | POLLOUT;
+
+ (void)poll(&pfd, 1, 2000);
+ (void)printf("child1 exit\n");
+}
+
+static void
+child2(void)
+{
+ struct pollfd pfd;
+
+ pfd.fd = desc;
+ pfd.events = POLLIN | POLLHUP | POLLOUT;
+
+ (void)sleep(1);
+ (void)poll(&pfd, 1, INFTIM);
+ (void)printf("child2 exit\n");
+}
+
+static void
+child3(void)
+{
+ struct pollfd pfd;
+
+ (void)sleep(5);
+
+ pfd.fd = desc;
+ pfd.events = POLLIN | POLLHUP | POLLOUT;
+
+ (void)poll(&pfd, 1, INFTIM);
+ (void)printf("child3 exit\n");
+}
+
+ATF_TC(poll_3way);
+ATF_TC_HEAD(poll_3way, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "15");
+ atf_tc_set_md_var(tc, "descr",
+ "Check for 3-way collision for descriptor. First child comes "
+ "and polls on descriptor, second child comes and polls, first "
+ "child times out and exits, third child comes and polls. When "
+ "the wakeup event happens, the two remaining children should "
+ "both be awaken. (kern/17517)");
+}
+
+ATF_TC_BODY(poll_3way, tc)
+{
+ int pf[2];
+ int status, i;
+ pid_t pid;
+
+ pipe(pf);
+ desc = pf[0];
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ (void)close(pf[1]);
+ child1();
+ _exit(0);
+ /* NOTREACHED */
+ }
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+ (void)close(pf[1]);
+ child2();
+ _exit(0);
+ /* NOTREACHED */
+ }
+
+ pid = fork();
+ ATF_REQUIRE( pid >= 0);
+
+ if (pid == 0) {
+ (void)close(pf[1]);
+ child3();
+ _exit(0);
+ /* NOTREACHED */
+ }
+
+ (void)sleep(10);
+
+ (void)printf("parent write\n");
+
+ ATF_REQUIRE(write(pf[1], "konec\n", 6) == 6);
+
+ for(i = 0; i < 3; ++i)
+ (void)wait(&status);
+
+ (void)printf("parent terminated\n");
+}
+
+ATF_TC(poll_basic);
+ATF_TC_HEAD(poll_basic, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "10");
+ atf_tc_set_md_var(tc, "descr",
+ "Basis functionality test for poll(2)");
+}
+
+ATF_TC_BODY(poll_basic, tc)
+{
+ int fds[2];
+ struct pollfd pfds[2];
+ int ret;
+
+ ATF_REQUIRE_EQ(pipe(fds), 0);
+
+ pfds[0].fd = fds[0];
+ pfds[0].events = POLLIN;
+ pfds[1].fd = fds[1];
+ pfds[1].events = POLLOUT;
+
+ /*
+ * Check that we get a timeout waiting for data on the read end
+ * of our pipe.
+ */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[0], 1, 1), 0,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents);
+
+ /* Check that the write end of the pipe as reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = poll(&pfds[1], 1, 1), 1,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\
+ pfds[1].revents);
+
+ /* Check that only the write end of the pipe as reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 1,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
+ pfds[1].revents);
+
+ /* Write data to our pipe. */
+ ATF_REQUIRE_EQ(write(fds[1], "", 1), 1);
+
+ /* Check that both ends of our pipe are reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = poll(pfds, 2, 1), 2,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d",
+ pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
+ pfds[1].revents);
+
+ ATF_REQUIRE_EQ(close(fds[0]), 0);
+ ATF_REQUIRE_EQ(close(fds[1]), 0);
+}
+
+ATF_TC(poll_err);
+ATF_TC_HEAD(poll_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check errors from poll(2)");
+}
+
+ATF_TC_BODY(poll_err, tc)
+{
+ struct pollfd pfd;
+ int fd = 0;
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, poll((struct pollfd *)-1, 1, -1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, poll(&pfd, 1, -2) == -1);
+}
+
+#ifndef __FreeBSD__
+ATF_TC(pollts_basic);
+ATF_TC_HEAD(pollts_basic, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "10");
+ atf_tc_set_md_var(tc, "descr",
+ "Basis functionality test for pollts(2)");
+}
+
+ATF_TC_BODY(pollts_basic, tc)
+{
+ int fds[2];
+ struct pollfd pfds[2];
+ struct timespec timeout;
+ int ret;
+
+ ATF_REQUIRE_EQ(pipe(fds), 0);
+
+ pfds[0].fd = fds[0];
+ pfds[0].events = POLLIN;
+ pfds[1].fd = fds[1];
+ pfds[1].events = POLLOUT;
+
+ /* Use a timeout of 1 second. */
+ timeout.tv_sec = 1;
+ timeout.tv_nsec = 0;
+
+ /*
+ * Check that we get a timeout waiting for data on the read end
+ * of our pipe.
+ */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[0], 1, &timeout, NULL), 0,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, -1, "got: %d", pfds[1].revents);
+
+ /* Check that the write end of the pipe as reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = pollts(&pfds[1], 1, &timeout, NULL), 1,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, -1, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",\
+ pfds[1].revents);
+
+ /* Check that only the write end of the pipe as reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 1,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, 0, "got: %d", pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
+ pfds[1].revents);
+
+ /* Write data to our pipe. */
+ ATF_REQUIRE_EQ(write(fds[1], "", 1), 1);
+
+ /* Check that both ends of our pipe are reported as ready. */
+ pfds[0].revents = -1;
+ pfds[1].revents = -1;
+ ATF_REQUIRE_EQ_MSG(ret = pollts(pfds, 2, &timeout, NULL), 2,
+ "got: %d", ret);
+ ATF_REQUIRE_EQ_MSG(pfds[0].revents, POLLIN, "got: %d",
+ pfds[0].revents);
+ ATF_REQUIRE_EQ_MSG(pfds[1].revents, POLLOUT, "got: %d",
+ pfds[1].revents);
+
+ ATF_REQUIRE_EQ(close(fds[0]), 0);
+ ATF_REQUIRE_EQ(close(fds[1]), 0);
+}
+
+ATF_TC(pollts_err);
+ATF_TC_HEAD(pollts_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Check errors from pollts(2)");
+}
+
+ATF_TC_BODY(pollts_err, tc)
+{
+ struct timespec timeout;
+ struct pollfd pfd;
+ int fd = 0;
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ timeout.tv_sec = 1;
+ timeout.tv_nsec = 0;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, pollts((void *)-1, 1, &timeout, NULL) == -1);
+
+ timeout.tv_sec = -1;
+ timeout.tv_nsec = -1;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, pollts(&pfd, 1, &timeout, NULL) == -1);
+}
+
+ATF_TC(pollts_sigmask);
+ATF_TC_HEAD(pollts_sigmask, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "10");
+ atf_tc_set_md_var(tc, "descr",
+ "Check that pollts(2) restores the signal mask (PR kern/44986)");
+}
+
+ATF_TC_BODY(pollts_sigmask, tc)
+{
+ int fd;
+ struct pollfd pfd;
+ struct timespec timeout;
+ sigset_t mask;
+ int ret;
+
+ fd = open(_PATH_DEVNULL, O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+
+ /* Use a timeout of 1 second. */
+ timeout.tv_sec = 1;
+ timeout.tv_nsec = 0;
+
+ /* Unblock all signals. */
+ ATF_REQUIRE_EQ(sigfillset(&mask), 0);
+ ATF_REQUIRE_EQ(sigprocmask(SIG_UNBLOCK, &mask, NULL), 0);
+
+ /*
+ * Check that pollts(2) immediately returns. We block *all*
+ * signals during pollts(2).
+ */
+ ATF_REQUIRE_EQ_MSG(ret = pollts(&pfd, 1, &timeout, &mask), 1,
+ "got: %d", ret);
+
+ /* Check that signals are now longer blocked. */
+ ATF_REQUIRE_EQ(sigprocmask(SIG_SETMASK, NULL, &mask), 0);
+ ATF_REQUIRE_EQ_MSG(sigismember(&mask, SIGUSR1), 0,
+ "signal mask was changed.");
+
+ ATF_REQUIRE_EQ(close(fd), 0);
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, poll_3way);
+ ATF_TP_ADD_TC(tp, poll_basic);
+ ATF_TP_ADD_TC(tp, poll_err);
+#ifndef __FreeBSD__
+ ATF_TP_ADD_TC(tp, pollts_basic);
+ ATF_TP_ADD_TC(tp, pollts_err);
+ ATF_TP_ADD_TC(tp, pollts_sigmask);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c b/contrib/netbsd-tests/lib/libc/sys/t_posix_fadvise.c
new file mode 100644
index 000000000000..da4e7461c8af
--- /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 000000000000..76bc7dde8e19
--- /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 000000000000..926d27406aa2
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_revoke.c
@@ -0,0 +1,195 @@
+/* $NetBSD: t_revoke.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_revoke.c,v 1.1 2011/07/07 06:57:54 jruoho Exp $");
+
+#include <sys/resource.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char path[] = "revoke";
+
+ATF_TC_WITH_CLEANUP(revoke_basic);
+ATF_TC_HEAD(revoke_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of revoke(2)");
+}
+
+ATF_TC_BODY(revoke_basic, tc)
+{
+ struct rlimit res;
+ char tmp[10];
+ size_t i, n;
+ int *buf;
+
+#ifdef __FreeBSD__
+ atf_tc_skip("revoke(2) is only implemented for devfs(5).");
+#endif
+ (void)memset(&res, 0, sizeof(struct rlimit));
+ (void)getrlimit(RLIMIT_NOFILE, &res);
+
+ if ((n = res.rlim_cur / 10) == 0)
+ n = 10;
+
+ buf = calloc(n, sizeof(int));
+ ATF_REQUIRE(buf != NULL);
+
+ buf[0] = open(path, O_RDWR | O_CREAT, 0600);
+ ATF_REQUIRE(buf[0] >= 0);
+
+ for (i = 1; i < n; i++) {
+ buf[i] = open(path, O_RDWR);
+ ATF_REQUIRE(buf[i] >= 0);
+ }
+
+ ATF_REQUIRE(revoke(path) == 0);
+
+ for (i = 0; i < n; i++) {
+
+ ATF_REQUIRE(read(buf[i], tmp, sizeof(tmp)) == -1);
+
+ (void)close(buf[i]);
+ }
+
+ free(buf);
+
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(revoke_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(revoke_err);
+ATF_TC_HEAD(revoke_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from revoke(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(revoke_err, tc)
+{
+ char buf[1024 + 1]; /* XXX: From the manual page... */
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, revoke((char *)-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, revoke(buf) == -1);
+
+#ifdef __FreeBSD__
+ atf_tc_skip("revoke(2) is only implemented for devfs(5).");
+#endif
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EPERM, revoke("/etc/passwd") == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, revoke("/etc/xxx/yyy") == -1);
+}
+
+ATF_TC_WITH_CLEANUP(revoke_perm);
+ATF_TC_HEAD(revoke_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions revoke(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(revoke_perm, tc)
+{
+ struct passwd *pw;
+ int fd, sta;
+ pid_t pid;
+
+#ifdef __FreeBSD__
+ atf_tc_skip("revoke(2) is only implemented for devfs(5).");
+#endif
+ pw = getpwnam("nobody");
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(pw != NULL);
+ ATF_REQUIRE(revoke(path) == 0);
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ if (setuid(pw->pw_uid) != 0)
+ _exit(EXIT_FAILURE);
+
+ errno = 0;
+
+ if (revoke(path) == 0)
+ _exit(EXIT_FAILURE);
+
+ if (errno != EACCES)
+ _exit(EXIT_FAILURE);
+
+ if (close(fd) != 0)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("revoke(2) did not obey permissions");
+
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(revoke_perm, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, revoke_basic);
+ ATF_TP_ADD_TC(tp, revoke_err);
+ ATF_TP_ADD_TC(tp, revoke_perm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_select.c b/contrib/netbsd-tests/lib/libc/sys/t_select.c
new file mode 100644
index 000000000000..7af725a9a1f4
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_select.c
@@ -0,0 +1,223 @@
+/* $NetBSD: t_select.c,v 1.3 2012/03/18 07:00:52 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundatiom
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+#include <err.h>
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <atf-c.h>
+
+static sig_atomic_t keep_going = 1;
+
+static void
+#ifdef __FreeBSD__
+sig_handler(int signum __unused)
+#else
+sig_handler(int signum)
+#endif
+{
+ keep_going = 0;
+}
+
+static void
+#ifdef __FreeBSD__
+sigchld(int signum __unused)
+#else
+sigchld(int signum)
+#endif
+{
+}
+
+static char
+xtoa(uint8_t n)
+{
+ static const char xarray[] = "0123456789abcdef";
+ assert(n < sizeof(xarray));
+ return xarray[n];
+}
+
+static const char *
+prmask(const sigset_t *m, char *buf, size_t len)
+{
+ size_t j = 2;
+ assert(len >= 3 + sizeof(*m));
+ buf[0] = '0';
+ buf[1] = 'x';
+#define N(p, a) (((p) >> ((a) * 4)) & 0xf)
+ for (size_t i = __arraycount(m->__bits); i > 0; i--) {
+ uint32_t p = m->__bits[i - 1];
+ for (size_t k = sizeof(p); k > 0; k--)
+ buf[j++] = xtoa(N(p, k - 1));
+ }
+ buf[j] = '\0';
+ return buf;
+}
+
+static void
+child(const struct timespec *ts)
+{
+ struct sigaction sa;
+ sigset_t set, oset, nset;
+ char obuf[sizeof(oset) + 3], nbuf[sizeof(nset) + 3];
+ int fd;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = sig_handler;
+ if ((fd = open("/dev/null", O_RDONLY)) == -1)
+ err(1, "open");
+
+ if (sigaction(SIGTERM, &sa, NULL) == -1)
+ err(1, "sigaction");
+
+ sigfillset(&set);
+ if (sigprocmask(SIG_BLOCK, &set, NULL) == -1)
+ err(1, "sigprocmask");
+
+ if (sigprocmask(SIG_BLOCK, NULL, &oset) == -1)
+ err(1, "sigprocmask");
+
+ sigemptyset(&set);
+
+ for (;;) {
+ fd_set rset;
+ FD_ZERO(&rset);
+ FD_SET(fd, &rset);
+ if (pselect(1, &rset, NULL, NULL, ts, &set) == -1) {
+ if(errno == EINTR) {
+ if (!keep_going)
+ break;
+ }
+ }
+ if (ts)
+ break;
+ }
+ if (sigprocmask(SIG_BLOCK, NULL, &nset) == -1)
+ err(1, "sigprocmask");
+ if (memcmp(&oset, &nset, sizeof(oset)) != 0)
+ atf_tc_fail("pselect() masks don't match "
+ "after timeout %s != %s",
+ prmask(&nset, nbuf, sizeof(nbuf)),
+ prmask(&oset, obuf, sizeof(obuf)));
+}
+
+ATF_TC(pselect_sigmask);
+ATF_TC_HEAD(pselect_sigmask, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask "
+ "setting when a signal is received (PR lib/43625)");
+}
+
+ATF_TC_BODY(pselect_sigmask, tc)
+{
+ pid_t pid;
+ int status;
+
+ signal(SIGCHLD, sigchld);
+
+ switch (pid = fork()) {
+ case 0:
+ child(NULL);
+ case -1:
+ err(1, "fork");
+ default:
+ sleep(1);
+ if (kill(pid, SIGTERM) == -1)
+ err(1, "kill");
+ sleep(1);
+ switch (waitpid(pid, &status, WNOHANG)) {
+ case -1:
+ err(1, "wait");
+ case 0:
+ if (kill(pid, SIGKILL) == -1)
+ err(1, "kill");
+ atf_tc_fail("pselect() did not receive signal");
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+ATF_TC(pselect_timeout);
+ATF_TC_HEAD(pselect_timeout, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks pselect's temporary mask "
+ "setting when a timeout occurs");
+}
+
+ATF_TC_BODY(pselect_timeout, tc)
+{
+ pid_t pid;
+ int status;
+ static const struct timespec zero = { 0, 0 };
+
+ signal(SIGCHLD, sigchld);
+
+ switch (pid = fork()) {
+ case 0:
+ child(&zero);
+ break;
+ case -1:
+ err(1, "fork");
+ default:
+ sleep(1);
+ switch (waitpid(pid, &status, WNOHANG)) {
+ case -1:
+ err(1, "wait");
+ case 0:
+ if (kill(pid, SIGKILL) == -1)
+ err(1, "kill");
+ atf_tc_fail("pselect() did not receive signal");
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, pselect_sigmask);
+ ATF_TP_ADD_TC(tp, pselect_timeout);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c
new file mode 100644
index 000000000000..72175e4f682d
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_setrlimit.c
@@ -0,0 +1,532 @@
+/* $NetBSD: t_setrlimit.c,v 1.4 2012/06/12 23:56:19 christos Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_setrlimit.c,v 1.4 2012/06/12 23:56:19 christos Exp $");
+
+#include <sys/resource.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#ifdef __NetBSD__
+#include <lwp.h>
+#endif
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+static void sighandler(int);
+static const char path[] = "setrlimit";
+
+static const int rlimit[] = {
+ RLIMIT_AS,
+ RLIMIT_CORE,
+ RLIMIT_CPU,
+ RLIMIT_DATA,
+ RLIMIT_FSIZE,
+ RLIMIT_MEMLOCK,
+ RLIMIT_NOFILE,
+ RLIMIT_NPROC,
+ RLIMIT_RSS,
+ RLIMIT_SBSIZE,
+ RLIMIT_STACK
+};
+
+ATF_TC(setrlimit_basic);
+ATF_TC_HEAD(setrlimit_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic soft limit test");
+}
+
+ATF_TC_BODY(setrlimit_basic, tc)
+{
+ struct rlimit res;
+ int *buf, lim;
+ size_t i;
+
+ buf = calloc(__arraycount(rlimit), sizeof(int));
+
+ if (buf == NULL)
+ atf_tc_fail("initialization failed");
+
+ for (i = lim = 0; i < __arraycount(rlimit); i++) {
+
+ (void)memset(&res, 0, sizeof(struct rlimit));
+
+ if (getrlimit(rlimit[i], &res) != 0)
+ continue;
+
+ if (res.rlim_cur == RLIM_INFINITY || res.rlim_cur == 0)
+ continue;
+
+ if (res.rlim_cur == res.rlim_max) /* An unprivileged run. */
+ continue;
+
+ buf[i] = res.rlim_cur;
+ res.rlim_cur = res.rlim_cur - 1;
+
+ if (setrlimit(rlimit[i], &res) != 0) {
+ lim = rlimit[i];
+ goto out;
+ }
+ }
+
+out:
+ for (i = 0; i < __arraycount(rlimit); i++) {
+
+ (void)memset(&res, 0, sizeof(struct rlimit));
+
+ if (buf[i] == 0)
+ continue;
+
+ if (getrlimit(rlimit[i], &res) != 0)
+ continue;
+
+ res.rlim_cur = buf[i];
+
+ (void)setrlimit(rlimit[i], &res);
+ }
+
+ if (lim != 0)
+ atf_tc_fail("failed to set limit (%d)", lim);
+}
+
+ATF_TC(setrlimit_current);
+ATF_TC_HEAD(setrlimit_current, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "setrlimit(3) with current limits");
+}
+
+ATF_TC_BODY(setrlimit_current, tc)
+{
+ struct rlimit res;
+ size_t i;
+
+ for (i = 0; i < __arraycount(rlimit); i++) {
+
+ (void)memset(&res, 0, sizeof(struct rlimit));
+
+ ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0);
+ ATF_REQUIRE(setrlimit(rlimit[i], &res) == 0);
+ }
+}
+
+ATF_TC(setrlimit_err);
+ATF_TC_HEAD(setrlimit_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions");
+}
+
+ATF_TC_BODY(setrlimit_err, tc)
+{
+ struct rlimit res;
+ size_t i;
+
+ for (i = 0; i < __arraycount(rlimit); i++) {
+
+ errno = 0;
+
+ ATF_REQUIRE(getrlimit(rlimit[i], (void *)0) != 0);
+ ATF_REQUIRE(errno == EFAULT);
+ }
+
+ errno = 0;
+
+ ATF_REQUIRE(getrlimit(INT_MAX, &res) != 0);
+ ATF_REQUIRE(errno == EINVAL);
+}
+
+ATF_TC_WITH_CLEANUP(setrlimit_fsize);
+ATF_TC_HEAD(setrlimit_fsize, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_FSIZE");
+}
+
+ATF_TC_BODY(setrlimit_fsize, tc)
+{
+ struct rlimit res;
+ int fd, sta;
+ pid_t pid;
+
+ fd = open(path, O_RDWR | O_CREAT, 0700);
+
+ if (fd < 0)
+ atf_tc_fail("initialization failed");
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ res.rlim_cur = 2;
+ res.rlim_max = 2;
+
+ if (setrlimit(RLIMIT_FSIZE, &res) != 0)
+ _exit(EXIT_FAILURE);
+
+ if (signal(SIGXFSZ, sighandler) == SIG_ERR)
+ _exit(EXIT_FAILURE);
+
+ /*
+ * The third call should generate a SIGXFSZ.
+ */
+ (void)write(fd, "X", 1);
+ (void)write(fd, "X", 1);
+ (void)write(fd, "X", 1);
+
+ _exit(EXIT_FAILURE);
+ }
+
+ (void)close(fd);
+ (void)wait(&sta);
+ (void)unlink(path);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("RLIMIT_FSIZE not enforced");
+}
+
+ATF_TC_CLEANUP(setrlimit_fsize, tc)
+{
+ (void)unlink(path);
+}
+
+static void
+sighandler(int signo)
+{
+
+ if (signo != SIGXFSZ)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+}
+
+ATF_TC(setrlimit_memlock);
+ATF_TC_HEAD(setrlimit_memlock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_MEMLOCK");
+}
+
+ATF_TC_BODY(setrlimit_memlock, tc)
+{
+ struct rlimit res;
+ void *buf;
+ long page;
+ pid_t pid;
+ int sta;
+
+ page = sysconf(_SC_PAGESIZE);
+ ATF_REQUIRE(page >= 0);
+
+ buf = malloc(page);
+ pid = fork();
+
+ if (buf == NULL || pid < 0)
+ atf_tc_fail("initialization failed");
+
+ if (pid == 0) {
+
+ /*
+ * Try to lock a page while
+ * RLIMIT_MEMLOCK is zero.
+ */
+ if (mlock(buf, page) != 0)
+ _exit(EXIT_FAILURE);
+
+ if (munlock(buf, page) != 0)
+ _exit(EXIT_FAILURE);
+
+ res.rlim_cur = 0;
+ res.rlim_max = 0;
+
+ if (setrlimit(RLIMIT_MEMLOCK, &res) != 0)
+ _exit(EXIT_FAILURE);
+
+ if (mlock(buf, page) != 0)
+ _exit(EXIT_SUCCESS);
+
+ (void)munlock(buf, page);
+
+ _exit(EXIT_FAILURE);
+ }
+
+ free(buf);
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("RLIMIT_MEMLOCK not enforced");
+}
+
+ATF_TC(setrlimit_nofile_1);
+ATF_TC_HEAD(setrlimit_nofile_1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #1");
+}
+
+ATF_TC_BODY(setrlimit_nofile_1, tc)
+{
+ struct rlimit res;
+ int fd, i, rv, sta;
+ pid_t pid;
+
+ res.rlim_cur = 0;
+ res.rlim_max = 0;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * Close all descriptors, set RLIMIT_NOFILE
+ * to zero, and try to open a random file.
+ * This should fail with EMFILE.
+ */
+ for (i = 0; i < 1024; i++)
+ (void)close(i);
+
+ rv = setrlimit(RLIMIT_NOFILE, &res);
+
+ if (rv != 0)
+ _exit(EXIT_FAILURE);
+
+ errno = 0;
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd >= 0 || errno != EMFILE)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("RLIMIT_NOFILE not enforced");
+}
+
+ATF_TC(setrlimit_nofile_2);
+ATF_TC_HEAD(setrlimit_nofile_2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NOFILE, #2");
+}
+
+ATF_TC_BODY(setrlimit_nofile_2, tc)
+{
+ static const rlim_t lim = 12;
+ struct rlimit res;
+ int fd, i, rv, sta;
+ pid_t pid;
+
+ /*
+ * See that an arbitrary limit on
+ * open files is being enforced.
+ */
+ res.rlim_cur = lim;
+ res.rlim_max = lim;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ for (i = 0; i < 1024; i++)
+ (void)close(i);
+
+ rv = setrlimit(RLIMIT_NOFILE, &res);
+
+ if (rv != 0)
+ _exit(EXIT_FAILURE);
+
+ for (i = 0; i < (int)lim; i++) {
+
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd < 0)
+ _exit(EXIT_FAILURE);
+ }
+
+ /*
+ * After the limit has been reached,
+ * EMFILE should again follow.
+ */
+ fd = open("/etc/passwd", O_RDONLY);
+
+ if (fd >= 0 || errno != EMFILE)
+ _exit(EXIT_FAILURE);
+
+ _exit(EXIT_SUCCESS);
+ }
+
+ (void)wait(&sta);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("RLIMIT_NOFILE not enforced");
+}
+
+ATF_TC(setrlimit_nproc);
+ATF_TC_HEAD(setrlimit_nproc, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NPROC");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(setrlimit_nproc, tc)
+{
+ struct rlimit res;
+ pid_t pid, cpid;
+ int sta;
+
+ pid = fork();
+ ATF_REQUIRE(pid >= 0);
+
+ if (pid == 0) {
+
+ /*
+ * Set RLIMIT_NPROC to zero and try to fork.
+ */
+ res.rlim_cur = 0;
+ res.rlim_max = 0;
+
+ if (setrlimit(RLIMIT_NPROC, &res) != 0)
+ _exit(EXIT_FAILURE);
+
+ cpid = fork();
+
+ if (cpid < 0)
+ _exit(EXIT_SUCCESS);
+
+ _exit(EXIT_FAILURE);
+ }
+
+ (void)waitpid(pid, &sta, 0);
+
+ if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS)
+ atf_tc_fail("RLIMIT_NPROC not enforced");
+}
+
+#ifdef __NetBSD__
+ATF_TC(setrlimit_nthr);
+ATF_TC_HEAD(setrlimit_nthr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2), RLIMIT_NTHR");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+static void
+func(lwpid_t *id)
+{
+ printf("thread %d\n", *id);
+ fflush(stdout);
+ _lwp_exit();
+}
+
+ATF_TC_BODY(setrlimit_nthr, tc)
+{
+ struct rlimit res;
+ lwpid_t lwpid;
+ ucontext_t c;
+
+ /*
+ * Set RLIMIT_NTHR to zero and try to create a thread.
+ */
+ res.rlim_cur = 0;
+ res.rlim_max = 0;
+ ATF_REQUIRE(setrlimit(RLIMIT_NTHR, &res) == 0);
+ ATF_REQUIRE(getcontext(&c) == 0);
+ c.uc_link = NULL;
+ sigemptyset(&c.uc_sigmask);
+ c.uc_stack.ss_flags = 0;
+ c.uc_stack.ss_size = 4096;
+ ATF_REQUIRE((c.uc_stack.ss_sp = malloc(c.uc_stack.ss_size)) != NULL);
+ makecontext(&c, func, 1, &lwpid);
+ ATF_CHECK_ERRNO(EAGAIN, _lwp_create(&c, 0, &lwpid) == -1);
+}
+#endif
+
+ATF_TC(setrlimit_perm);
+ATF_TC_HEAD(setrlimit_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test setrlimit(2) for EPERM");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(setrlimit_perm, tc)
+{
+ struct rlimit res;
+ size_t i;
+
+ /*
+ * Try to raise the maximum limits as an user.
+ */
+ for (i = 0; i < __arraycount(rlimit); i++) {
+
+ ATF_REQUIRE(getrlimit(rlimit[i], &res) == 0);
+
+#ifdef __FreeBSD__
+ if (res.rlim_max == INT64_MAX) /* Overflow. */
+#else
+ if (res.rlim_max == UINT64_MAX) /* Overflow. */
+#endif
+ continue;
+
+ errno = 0;
+ res.rlim_max = res.rlim_max + 1;
+
+ ATF_CHECK_ERRNO(EPERM, setrlimit(rlimit[i], &res) != 0);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, setrlimit_basic);
+ ATF_TP_ADD_TC(tp, setrlimit_current);
+ ATF_TP_ADD_TC(tp, setrlimit_err);
+ ATF_TP_ADD_TC(tp, setrlimit_fsize);
+ ATF_TP_ADD_TC(tp, setrlimit_memlock);
+ ATF_TP_ADD_TC(tp, setrlimit_nofile_1);
+ ATF_TP_ADD_TC(tp, setrlimit_nofile_2);
+ ATF_TP_ADD_TC(tp, setrlimit_nproc);
+ ATF_TP_ADD_TC(tp, setrlimit_perm);
+#ifdef __NetBSD__
+ ATF_TP_ADD_TC(tp, setrlimit_nthr);
+#endif
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_setuid.c b/contrib/netbsd-tests/lib/libc/sys/t_setuid.c
new file mode 100644
index 000000000000..d2bf523f4cf4
--- /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 000000000000..23ca36a659f8
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_sigaction.c
@@ -0,0 +1,165 @@
+/* $NetBSD: t_sigaction.c,v 1.3 2014/11/04 00:20:19 justin Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2010\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_sigaction.c,v 1.3 2014/11/04 00:20:19 justin Exp $");
+
+#include <sys/wait.h>
+
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#ifdef __NetBSD__
+#include "../../../h_macros.h"
+#else
+#include "h_macros.h"
+#endif
+
+static bool handler_called = false;
+
+static void
+#ifdef __FreeBSD__
+handler(int signo __unused)
+#else
+handler(int signo)
+#endif
+{
+ handler_called = true;
+}
+
+static void
+sa_resethand_child(const int flags)
+{
+ struct sigaction sa;
+
+ sa.sa_flags = flags;
+ sa.sa_handler = &handler;
+ sigemptyset(&sa.sa_mask);
+
+ sigaction(SIGUSR1, &sa, NULL);
+ kill(getpid(), SIGUSR1);
+ exit(handler_called ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+static void
+wait_and_check_child(const pid_t pid, const char *fail_message)
+{
+ int status;
+
+ (void)waitpid(pid, &status, 0);
+
+ if (WIFEXITED(status))
+ ATF_CHECK_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+ else
+ atf_tc_fail("%s; raw exit status was %d", fail_message, status);
+}
+
+static void
+#ifdef __FreeBSD__
+catch(int sig __unused)
+#else
+catch(int sig)
+#endif
+{
+ return;
+}
+
+ATF_TC(sigaction_basic);
+ATF_TC_HEAD(sigaction_basic, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks for correct I&D cache"
+ "synchronization after copying out the trampoline code.");
+}
+
+ATF_TC_BODY(sigaction_basic, tc)
+{
+ static struct sigaction sa;
+
+ sa.sa_handler = catch;
+
+ sigaction(SIGUSR1, &sa, 0);
+ kill(getpid(), SIGUSR1);
+ atf_tc_pass();
+}
+
+ATF_TC(sigaction_noflags);
+ATF_TC_HEAD(sigaction_noflags, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks programming a signal with "
+ "sigaction(2) but without any flags");
+}
+
+ATF_TC_BODY(sigaction_noflags, tc)
+{
+ const pid_t pid = fork();
+ if (pid == -1)
+ atf_tc_fail_errno("fork(2) failed");
+ else if (pid == 0)
+ sa_resethand_child(0);
+ else
+ wait_and_check_child(pid, "Child process did not exit cleanly;"
+ " it failed to process the signal");
+}
+
+ATF_TC(sigaction_resethand);
+ATF_TC_HEAD(sigaction_resethand, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that SA_RESETHAND works");
+}
+
+ATF_TC_BODY(sigaction_resethand, tc)
+{
+ const pid_t pid = fork();
+ if (pid == -1)
+ atf_tc_fail_errno("fork(2) failed");
+ else if (pid == 0)
+ sa_resethand_child(SA_RESETHAND);
+ else {
+ wait_and_check_child(pid, "Child process did not exit cleanly;"
+ " it either failed to process the signal or SA_RESETHAND"
+ " is broken");
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sigaction_basic);
+ ATF_TP_ADD_TC(tp, sigaction_noflags);
+ ATF_TP_ADD_TC(tp, sigaction_resethand);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c
new file mode 100644
index 000000000000..6686f022b131
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_sigqueue.c
@@ -0,0 +1,115 @@
+/* $NetBSD: t_sigqueue.c,v 1.4 2011/07/07 16:31:11 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_sigqueue.c,v 1.4 2011/07/07 16:31:11 jruoho Exp $");
+
+
+#include <atf-c.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <unistd.h>
+
+static void handler(int, siginfo_t *, void *);
+
+#define VALUE (int)0xc001dad1
+static int value;
+
+static void
+#ifdef __FreeBSD__
+handler(int signo __unused, siginfo_t *info __unused, void *data __unused)
+#else
+handler(int signo, siginfo_t *info, void *data)
+#endif
+{
+ value = info->si_value.sival_int;
+ kill(0, SIGINFO);
+}
+
+ATF_TC(sigqueue_basic);
+ATF_TC_HEAD(sigqueue_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks sigqueue(3) sigval delivery");
+}
+
+ATF_TC_BODY(sigqueue_basic, tc)
+{
+ struct sigaction sa;
+ union sigval sv;
+
+ sa.sa_sigaction = handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+
+ if (sigaction(SIGUSR1, &sa, NULL) != 0)
+ atf_tc_fail("sigaction failed");
+
+ sv.sival_int = VALUE;
+
+#ifdef __FreeBSD__
+ /*
+ * From kern_sig.c:
+ * Specification says sigqueue can only send signal to single process.
+ */
+ if (sigqueue(getpid(), SIGUSR1, sv) != 0)
+#else
+ if (sigqueue(0, SIGUSR1, sv) != 0)
+#endif
+ atf_tc_fail("sigqueue failed");
+
+ sched_yield();
+ ATF_REQUIRE_EQ(sv.sival_int, value);
+}
+
+ATF_TC(sigqueue_err);
+ATF_TC_HEAD(sigqueue_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from sigqueue(3)");
+}
+
+ATF_TC_BODY(sigqueue_err, tc)
+{
+ union sigval sv;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, sigqueue(getpid(), -1, sv) == -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sigqueue_basic);
+ ATF_TP_ADD_TC(tp, sigqueue_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c b/contrib/netbsd-tests/lib/libc/sys/t_sigtimedwait.c
new file mode 100644
index 000000000000..64b68d9a0607
--- /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 000000000000..9da7861b1b8a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_socketpair.c
@@ -0,0 +1,141 @@
+/* $NetBSD: t_socketpair.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_socketpair.c,v 1.1 2011/11/05 18:19:02 jruoho Exp $");
+
+#include <atf-c.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+
+static void
+connected(int fd)
+{
+ struct sockaddr_un addr;
+ socklen_t len = (socklen_t)sizeof(addr);
+ ATF_REQUIRE(getpeername(fd, (struct sockaddr*)(void *)&addr,
+ &len) == 0);
+}
+
+static void
+run(int flags)
+{
+ int fd[2], i;
+
+ while ((i = open("/", O_RDONLY)) < 3)
+ ATF_REQUIRE(i != -1);
+
+#ifdef __FreeBSD__
+ closefrom(3);
+#else
+ ATF_REQUIRE(fcntl(3, F_CLOSEM) != -1);
+#endif
+
+ ATF_REQUIRE(socketpair(AF_UNIX, SOCK_DGRAM | flags, 0, fd) == 0);
+
+ ATF_REQUIRE(fd[0] == 3);
+ ATF_REQUIRE(fd[1] == 4);
+
+ connected(fd[0]);
+ connected(fd[1]);
+
+ if (flags & SOCK_CLOEXEC) {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) != 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) != 0);
+ } else {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFD) & FD_CLOEXEC) == 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFD) & FD_CLOEXEC) == 0);
+ }
+
+ if (flags & SOCK_NONBLOCK) {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) != 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) != 0);
+ } else {
+ ATF_REQUIRE((fcntl(fd[0], F_GETFL) & O_NONBLOCK) == 0);
+ ATF_REQUIRE((fcntl(fd[1], F_GETFL) & O_NONBLOCK) == 0);
+ }
+
+ ATF_REQUIRE(close(fd[0]) != -1);
+ ATF_REQUIRE(close(fd[1]) != -1);
+}
+
+ATF_TC(socketpair_basic);
+ATF_TC_HEAD(socketpair_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of socketpair(2)");
+}
+
+ATF_TC_BODY(socketpair_basic, tc)
+{
+ run(0);
+}
+
+ATF_TC(socketpair_nonblock);
+ATF_TC_HEAD(socketpair_nonblock, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A non-blocking test of socketpair(2)");
+}
+
+ATF_TC_BODY(socketpair_nonblock, tc)
+{
+ run(SOCK_NONBLOCK);
+}
+
+ATF_TC(socketpair_cloexec);
+ATF_TC_HEAD(socketpair_cloexec, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A close-on-exec of socketpair(2)");
+}
+
+ATF_TC_BODY(socketpair_cloexec, tc)
+{
+ run(SOCK_CLOEXEC);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, socketpair_basic);
+ ATF_TP_ADD_TC(tp, socketpair_nonblock);
+ ATF_TP_ADD_TC(tp, socketpair_cloexec);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_stat.c b/contrib/netbsd-tests/lib/libc/sys/t_stat.c
new file mode 100644
index 000000000000..5e1d17e28e78
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_stat.c
@@ -0,0 +1,421 @@
+/* $NetBSD: t_stat.c,v 1.4 2012/03/17 08:37:08 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_stat.c,v 1.4 2012/03/17 08:37:08 jruoho Exp $");
+
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <arpa/inet.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fts.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <stdio.h>
+
+#ifdef __FreeBSD__
+#include <netinet/in.h>
+#endif
+
+static const char *path = "stat";
+
+ATF_TC_WITH_CLEANUP(stat_chflags);
+ATF_TC_HEAD(stat_chflags, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test chflags(2) with stat(2)");
+}
+
+ATF_TC_BODY(stat_chflags, tc)
+{
+ struct stat sa, sb;
+ int fd;
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ fd = open(path, O_RDONLY | O_CREAT);
+
+ ATF_REQUIRE(fd != -1);
+ ATF_REQUIRE(stat(path, &sa) == 0);
+ ATF_REQUIRE(chflags(path, UF_NODUMP) == 0);
+ ATF_REQUIRE(stat(path, &sb) == 0);
+
+ if (sa.st_flags == sb.st_flags)
+ atf_tc_fail("stat(2) did not detect chflags(2)");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(stat_chflags, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(stat_dir);
+ATF_TC_HEAD(stat_dir, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test stat(2) with directories");
+}
+
+ATF_TC_BODY(stat_dir, tc)
+{
+ const short depth = 2;
+ struct stat sa, sb;
+ char *argv[2];
+ FTSENT *ftse;
+ FTS *fts;
+ int ops;
+
+ argv[1] = NULL;
+ argv[0] = __UNCONST("/");
+
+ ops = FTS_NOCHDIR;
+ ops |= FTS_PHYSICAL;
+
+ fts = fts_open(argv, ops, NULL);
+ ATF_REQUIRE(fts != NULL);
+
+ while ((ftse = fts_read(fts)) != NULL) {
+
+ if (ftse->fts_level < 1)
+ continue;
+
+ if (ftse->fts_level > depth) {
+ (void)fts_set(fts, ftse, FTS_SKIP);
+ continue;
+ }
+
+ switch(ftse->fts_info) {
+
+ case FTS_DP:
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(stat(ftse->fts_parent->fts_path,&sa) == 0);
+ ATF_REQUIRE(chdir(ftse->fts_path) == 0);
+ ATF_REQUIRE(stat(".", &sb) == 0);
+
+ /*
+ * The previous two stat(2) calls
+ * should be for the same directory.
+ */
+ if (sa.st_dev != sb.st_dev || sa.st_ino != sb.st_ino)
+ atf_tc_fail("inconsistent stat(2)");
+
+ /*
+ * Check that fts(3)'s stat(2)
+ * call equals the manual one.
+ */
+ if (sb.st_ino != ftse->fts_statp->st_ino)
+ atf_tc_fail("stat(2) and fts(3) differ");
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ (void)fts_close(fts);
+}
+
+ATF_TC(stat_err);
+ATF_TC_HEAD(stat_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from the stat(2) family");
+}
+
+ATF_TC_BODY(stat_err, tc)
+{
+ char buf[NAME_MAX + 1];
+ struct stat st;
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, fstat(-1, &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, stat(buf, &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, lstat(buf, &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, stat((void *)-1, &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, lstat((void *)-1, &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, stat("/etc/passwd", (void *)-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, lstat("/etc/passwd", (void *)-1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, stat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, lstat("/a/b/c/d/e/f/g/h/i/j/k", &st) == -1);
+}
+
+ATF_TC_WITH_CLEANUP(stat_mtime);
+ATF_TC_HEAD(stat_mtime, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test modification times with stat(2)");
+}
+
+ATF_TC_BODY(stat_mtime, tc)
+{
+ struct stat sa, sb;
+ int fd[3];
+ size_t i;
+
+ for (i = 0; i < __arraycount(fd); i++) {
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ fd[i] = open(path, O_WRONLY | O_CREAT);
+
+ ATF_REQUIRE(fd[i] != -1);
+ ATF_REQUIRE(write(fd[i], "X", 1) == 1);
+ ATF_REQUIRE(stat(path, &sa) == 0);
+
+ (void)sleep(1);
+
+ ATF_REQUIRE(write(fd[i], "X", 1) == 1);
+ ATF_REQUIRE(stat(path, &sb) == 0);
+
+ ATF_REQUIRE(close(fd[i]) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+
+ if (sa.st_mtime == sb.st_mtime)
+ atf_tc_fail("mtimes did not change");
+ }
+}
+
+ATF_TC_CLEANUP(stat_mtime, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(stat_perm);
+ATF_TC_HEAD(stat_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with stat(2)");
+ atf_tc_set_md_var(tc, "require.user", "root");
+}
+
+ATF_TC_BODY(stat_perm, tc)
+{
+ struct stat sa, sb;
+ gid_t gid;
+ uid_t uid;
+ int fd;
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ uid = getuid();
+ gid = getgid();
+
+ fd = open(path, O_RDONLY | O_CREAT);
+
+ ATF_REQUIRE(fd != -1);
+ ATF_REQUIRE(fstat(fd, &sa) == 0);
+ ATF_REQUIRE(stat(path, &sb) == 0);
+
+ if (gid != sa.st_gid || sa.st_gid != sb.st_gid)
+ atf_tc_fail("invalid GID");
+
+ if (uid != sa.st_uid || sa.st_uid != sb.st_uid)
+ atf_tc_fail("invalid UID");
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(stat_perm, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(stat_size);
+ATF_TC_HEAD(stat_size, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test file sizes with stat(2)");
+}
+
+ATF_TC_BODY(stat_size, tc)
+{
+ struct stat sa, sb, sc;
+ const size_t n = 10;
+ size_t i;
+ int fd;
+
+ fd = open(path, O_WRONLY | O_CREAT);
+ ATF_REQUIRE(fd >= 0);
+
+ for (i = 0; i < n; i++) {
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+ (void)memset(&sc, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(fstat(fd, &sa) == 0);
+ ATF_REQUIRE(write(fd, "X", 1) == 1);
+ ATF_REQUIRE(fstat(fd, &sb) == 0);
+ ATF_REQUIRE(stat(path, &sc) == 0);
+
+ if (sa.st_size + 1 != sb.st_size)
+ atf_tc_fail("invalid file size");
+
+ if (sb.st_size != sc.st_size)
+ atf_tc_fail("stat(2) and fstat(2) mismatch");
+ }
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(stat_size, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(stat_socket);
+ATF_TC_HEAD(stat_socket, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test fstat(2) with "
+ "a socket (PR kern/46077)");
+}
+
+ATF_TC_BODY(stat_socket, tc)
+{
+ struct sockaddr_in addr;
+ struct stat st;
+ uint32_t iaddr;
+ int fd, flags;
+
+ (void)memset(&st, 0, sizeof(struct stat));
+ (void)memset(&addr, 0, sizeof(struct sockaddr_in));
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ ATF_REQUIRE(fd >= 0);
+
+ flags = fcntl(fd, F_GETFL);
+
+ ATF_REQUIRE(flags != -1);
+ ATF_REQUIRE(fcntl(fd, F_SETFL, flags | O_NONBLOCK) != -1);
+ ATF_REQUIRE(inet_pton(AF_INET, "127.0.0.1", &iaddr) == 1);
+
+ addr.sin_port = htons(42);
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = iaddr;
+
+ errno = 0;
+
+ ATF_REQUIRE_ERRNO(EINPROGRESS,
+ connect(fd, (struct sockaddr *)&addr,
+ sizeof(struct sockaddr_in)) == -1);
+
+ errno = 0;
+
+ if (fstat(fd, &st) != 0 || errno != 0)
+ atf_tc_fail("fstat(2) failed for a EINPROGRESS socket");
+
+ (void)close(fd);
+}
+
+ATF_TC_WITH_CLEANUP(stat_symlink);
+ATF_TC_HEAD(stat_symlink, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test symbolic links with stat(2)");
+}
+
+ATF_TC_BODY(stat_symlink, tc)
+{
+ const char *pathlink = "pathlink";
+ struct stat sa, sb;
+ int fd;
+
+ (void)memset(&sa, 0, sizeof(struct stat));
+ (void)memset(&sb, 0, sizeof(struct stat));
+
+ fd = open(path, O_WRONLY | O_CREAT);
+
+ ATF_REQUIRE(fd >= 0);
+ ATF_REQUIRE(symlink(path, pathlink) == 0);
+ ATF_REQUIRE(stat(pathlink, &sa) == 0);
+ ATF_REQUIRE(lstat(pathlink, &sb) == 0);
+
+ if (S_ISLNK(sa.st_mode) != 0)
+ atf_tc_fail("stat(2) detected symbolic link");
+
+ if (S_ISLNK(sb.st_mode) == 0)
+ atf_tc_fail("lstat(2) did not detect symbolic link");
+
+ if (sa.st_mode == sb.st_mode)
+ atf_tc_fail("inconsistencies between stat(2) and lstat(2)");
+
+ ATF_REQUIRE(unlink(path) == 0);
+ ATF_REQUIRE(unlink(pathlink) == 0);
+}
+
+ATF_TC_CLEANUP(stat_symlink, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, stat_chflags);
+ ATF_TP_ADD_TC(tp, stat_dir);
+ ATF_TP_ADD_TC(tp, stat_err);
+ ATF_TP_ADD_TC(tp, stat_mtime);
+ ATF_TP_ADD_TC(tp, stat_perm);
+ ATF_TP_ADD_TC(tp, stat_size);
+ ATF_TP_ADD_TC(tp, stat_socket);
+ ATF_TP_ADD_TC(tp, stat_symlink);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c b/contrib/netbsd-tests/lib/libc/sys/t_swapcontext.c
new file mode 100644
index 000000000000..de36c8807dce
--- /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 000000000000..cc853073ff45
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_timer_create.c
@@ -0,0 +1,211 @@
+/* $NetBSD: t_timer_create.c,v 1.4 2012/03/18 07:00:52 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <errno.h>
+#include <stdio.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+static timer_t t;
+static bool fail = true;
+
+static void
+#ifdef __FreeBSD__
+timer_signal_handler(int signo, siginfo_t *si, void *osi __unused)
+#else
+timer_signal_handler(int signo, siginfo_t *si, void *osi)
+#endif
+{
+ timer_t *tp;
+
+ tp = si->si_value.sival_ptr;
+
+ if (*tp == t && signo == SIGALRM)
+ fail = false;
+
+ (void)fprintf(stderr, "%s: %s\n", __func__, strsignal(signo));
+}
+
+static void
+timer_signal_create(clockid_t cid, bool expire)
+{
+ struct itimerspec tim;
+ struct sigaction act;
+ struct sigevent evt;
+ sigset_t set;
+
+ t = 0;
+ fail = true;
+
+ (void)memset(&evt, 0, sizeof(struct sigevent));
+ (void)memset(&act, 0, sizeof(struct sigaction));
+ (void)memset(&tim, 0, sizeof(struct itimerspec));
+
+ /*
+ * Set handler.
+ */
+ act.sa_flags = SA_SIGINFO;
+ act.sa_sigaction = timer_signal_handler;
+
+ ATF_REQUIRE(sigemptyset(&set) == 0);
+ ATF_REQUIRE(sigemptyset(&act.sa_mask) == 0);
+
+ /*
+ * Block SIGALRM while configuring the timer.
+ */
+ ATF_REQUIRE(sigaction(SIGALRM, &act, NULL) == 0);
+ ATF_REQUIRE(sigaddset(&set, SIGALRM) == 0);
+ ATF_REQUIRE(sigprocmask(SIG_SETMASK, &set, NULL) == 0);
+
+ /*
+ * Create the timer (SIGEV_SIGNAL).
+ */
+ evt.sigev_signo = SIGALRM;
+ evt.sigev_value.sival_ptr = &t;
+ evt.sigev_notify = SIGEV_SIGNAL;
+
+ ATF_REQUIRE(timer_create(cid, &evt, &t) == 0);
+
+ /*
+ * Start the timer. After this, unblock the signal.
+ */
+ tim.it_value.tv_sec = expire ? 5 : 1;
+ tim.it_value.tv_nsec = 0;
+
+ ATF_REQUIRE(timer_settime(t, 0, &tim, NULL) == 0);
+
+ (void)sigprocmask(SIG_UNBLOCK, &set, NULL);
+ (void)sleep(2);
+
+ if (expire) {
+ if (!fail)
+ atf_tc_fail("timer fired too soon");
+ } else {
+ if (fail)
+ atf_tc_fail("timer failed to fire");
+ }
+
+ ATF_REQUIRE(timer_delete(t) == 0);
+}
+
+ATF_TC(timer_create_err);
+ATF_TC_HEAD(timer_create_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Check errors from timer_create(2) (PR lib/42434");
+}
+
+ATF_TC_BODY(timer_create_err, tc)
+{
+ struct sigevent ev;
+
+ (void)memset(&ev, 0, sizeof(struct sigevent));
+
+ errno = 0;
+ ev.sigev_signo = -1;
+ ev.sigev_notify = SIGEV_SIGNAL;
+
+ ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1);
+
+ errno = 0;
+ ev.sigev_signo = SIGUSR1;
+ ev.sigev_notify = SIGEV_THREAD + 100;
+
+ ATF_REQUIRE_ERRNO(EINVAL, timer_create(CLOCK_REALTIME, &ev, &t) == -1);
+}
+
+ATF_TC(timer_create_real);
+ATF_TC_HEAD(timer_create_real, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), "
+ "SIGEV_SIGNAL");
+}
+
+ATF_TC_BODY(timer_create_real, tc)
+{
+ timer_signal_create(CLOCK_REALTIME, false);
+}
+
+ATF_TC(timer_create_mono);
+ATF_TC_HEAD(timer_create_mono, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), "
+ "SIGEV_SIGNAL");
+}
+
+ATF_TC_BODY(timer_create_mono, tc)
+{
+ timer_signal_create(CLOCK_MONOTONIC, false);
+}
+
+ATF_TC(timer_create_real_expire);
+ATF_TC_HEAD(timer_create_real_expire, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks timer_create(2) with CLOCK_REALTIME and sigevent(3), "
+ "SIGEV_SIGNAL, with expiration");
+}
+
+ATF_TC_BODY(timer_create_real_expire, tc)
+{
+ timer_signal_create(CLOCK_REALTIME, true);
+}
+
+ATF_TC(timer_create_mono_expire);
+ATF_TC_HEAD(timer_create_mono_expire, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr",
+ "Checks timer_create(2) with CLOCK_MONOTONIC and sigevent(3), "
+ "SIGEV_SIGNAL, with expiration");
+}
+
+ATF_TC_BODY(timer_create_mono_expire, tc)
+{
+ timer_signal_create(CLOCK_MONOTONIC, true);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, timer_create_err);
+ ATF_TP_ADD_TC(tp, timer_create_real);
+ ATF_TP_ADD_TC(tp, timer_create_mono);
+ ATF_TP_ADD_TC(tp, timer_create_real_expire);
+ ATF_TP_ADD_TC(tp, timer_create_mono_expire);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_truncate.c b/contrib/netbsd-tests/lib/libc/sys/t_truncate.c
new file mode 100644
index 000000000000..59193a953f37
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_truncate.c
@@ -0,0 +1,188 @@
+/* $NetBSD: t_truncate.c,v 1.2 2011/08/18 19:48:03 dholland Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_truncate.c,v 1.2 2011/08/18 19:48:03 dholland Exp $");
+
+#include <sys/stat.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+static const char path[] = "truncate";
+static const size_t sizes[] = { 8, 16, 512, 1024, 2048, 4094, 3000, 30 };
+
+ATF_TC_WITH_CLEANUP(ftruncate_basic);
+ATF_TC_HEAD(ftruncate_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of ftruncate(2)");
+}
+
+ATF_TC_BODY(ftruncate_basic, tc)
+{
+ struct stat st;
+ size_t i;
+ int fd;
+
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+ ATF_REQUIRE(fd >= 0);
+
+ for (i = 0; i < __arraycount(sizes); i++) {
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(ftruncate(fd, sizes[i]) == 0);
+ ATF_REQUIRE(fstat(fd, &st) == 0);
+
+ (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]);
+
+ if (sizes[i] != (size_t)st.st_size)
+ atf_tc_fail("ftruncate(2) did not truncate");
+ }
+
+ (void)close(fd);
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(ftruncate_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(ftruncate_err);
+ATF_TC_HEAD(ftruncate_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from ftruncate(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(ftruncate_err, tc)
+{
+ int fd;
+
+ fd = open("/etc/passwd", O_RDONLY, 0400);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, ftruncate(-1, 999) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, ftruncate(fd, 999) == -1);
+
+ (void)close(fd);
+}
+
+ATF_TC_WITH_CLEANUP(truncate_basic);
+ATF_TC_HEAD(truncate_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of truncate(2)");
+}
+
+ATF_TC_BODY(truncate_basic, tc)
+{
+ struct stat st;
+ size_t i;
+ int fd;
+
+ fd = open(path, O_RDWR | O_CREAT, 0600);
+ ATF_REQUIRE(fd >= 0);
+
+ for (i = 0; i < __arraycount(sizes); i++) {
+
+ (void)memset(&st, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(truncate(path, sizes[i]) == 0);
+ ATF_REQUIRE(fstat(fd, &st) == 0);
+
+ (void)fprintf(stderr, "truncating to %zu bytes\n", sizes[i]);
+
+ if (sizes[i] != (size_t)st.st_size)
+ atf_tc_fail("truncate(2) did not truncate");
+ }
+
+ (void)close(fd);
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(truncate_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(truncate_err);
+ATF_TC_HEAD(truncate_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test errors from truncate(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(truncate_err, tc)
+{
+#ifndef __NetBSD__
+ char buf[PATH_MAX];
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, truncate((void *)-1, 999) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EISDIR, truncate("/etc", 999) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, truncate("/a/b/c/d/e/f/g", 999) == -1);
+
+ errno = 0;
+#ifdef __NetBSD__
+ ATF_REQUIRE_ERRNO(EACCES, truncate("/usr/bin/fpr", 999) == -1);
+#else
+ snprintf(buf, sizeof(buf), "%s/truncate_test.root_owned",
+ atf_tc_get_config_var(tc, "srcdir"));
+ ATF_REQUIRE_ERRNO(EACCES, truncate(buf, 999) == -1);
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, ftruncate_basic);
+ ATF_TP_ADD_TC(tp, ftruncate_err);
+ ATF_TP_ADD_TC(tp, truncate_basic);
+ ATF_TP_ADD_TC(tp, truncate_err);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c b/contrib/netbsd-tests/lib/libc/sys/t_ucontext.c
new file mode 100644
index 000000000000..27d6740ba50e
--- /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 000000000000..748cbdcf1ada
--- /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 000000000000..8d9466881cba
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_unlink.c
@@ -0,0 +1,162 @@
+/* $NetBSD: t_unlink.c,v 1.2 2014/04/21 18:05:17 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_unlink.c,v 1.2 2014/04/21 18:05:17 martin Exp $");
+
+#include <sys/stat.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+
+static char path[] = "unlink";
+
+ATF_TC_WITH_CLEANUP(unlink_basic);
+ATF_TC_HEAD(unlink_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of unlink(2)");
+}
+
+ATF_TC_BODY(unlink_basic, tc)
+{
+ const size_t n = 512;
+ size_t i;
+ int fd;
+
+ for (i = 0; i < n; i++) {
+
+ fd = open(path, O_RDWR | O_CREAT, 0666);
+
+ ATF_REQUIRE(fd != -1);
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1);
+ }
+}
+
+ATF_TC_CLEANUP(unlink_basic, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(unlink_err);
+ATF_TC_HEAD(unlink_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of unlink(2)");
+}
+
+ATF_TC_BODY(unlink_err, tc)
+{
+ char buf[PATH_MAX + 1];
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ errno = 0;
+#ifdef __FreeBSD__
+ ATF_REQUIRE_ERRNO(EISDIR, unlink("/") == -1);
+#else
+ ATF_REQUIRE_ERRNO(EBUSY, unlink("/") == -1);
+#endif
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENAMETOOLONG, unlink(buf) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, unlink("/a/b/c/d/e/f/g/h/i/j/k/l/m") == -1);
+}
+
+ATF_TC_CLEANUP(unlink_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(unlink_fifo);
+ATF_TC_HEAD(unlink_fifo, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test unlink(2) for a FIFO");
+}
+
+ATF_TC_BODY(unlink_fifo, tc)
+{
+
+ ATF_REQUIRE(mkfifo(path, 0666) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(ENOENT, open(path, O_RDONLY) == -1);
+}
+
+ATF_TC_CLEANUP(unlink_fifo, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(unlink_perm);
+ATF_TC_HEAD(unlink_perm, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test permissions with unlink(2)");
+ atf_tc_set_md_var(tc, "require.user", "unprivileged");
+}
+
+ATF_TC_BODY(unlink_perm, tc)
+{
+ int rv;
+
+ errno = 0;
+ rv = unlink("/etc");
+ ATF_REQUIRE_MSG(rv == -1 && (errno == EACCES || errno == EPERM),
+ "unlinking a directory did not fail with EPERM or EACCESS; "
+ "unlink() returned %d, errno %d", rv, errno);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EACCES, unlink("/root/.profile") == -1);
+}
+
+ATF_TC_CLEANUP(unlink_perm, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, unlink_basic);
+ ATF_TP_ADD_TC(tp, unlink_err);
+ ATF_TP_ADD_TC(tp, unlink_fifo);
+ ATF_TP_ADD_TC(tp, unlink_perm);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/sys/t_write.c b/contrib/netbsd-tests/lib/libc/sys/t_write.c
new file mode 100644
index 000000000000..a3783cb5deee
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/sys/t_write.c
@@ -0,0 +1,236 @@
+/* $NetBSD: t_write.c,v 1.2 2011/10/19 16:19:30 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2001, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_write.c,v 1.2 2011/10/19 16:19:30 jruoho Exp $");
+
+#include <sys/uio.h>
+#ifdef __NetBSD__
+#include <sys/syslimits.h>
+#endif
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef __FreeBSD__
+#include <limits.h>
+#endif
+
+static void sighandler(int);
+
+static bool fail = false;
+static const char *path = "write";
+
+static void
+#ifdef __FreeBSD__
+sighandler(int signo __unused)
+#else
+sighandler(int signo)
+#endif
+{
+ fail = false;
+}
+
+ATF_TC_WITH_CLEANUP(write_err);
+ATF_TC_HEAD(write_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks errors from write(2)");
+}
+
+ATF_TC_BODY(write_err, tc)
+{
+ char rbuf[3] = { 'a', 'b', 'c' };
+ char wbuf[3] = { 'x', 'y', 'z' };
+ int fd;
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, write(-1, wbuf, sizeof(wbuf)) == -1);
+
+ fd = open(path, O_RDWR | O_CREAT);
+
+ if (fd >= 0) {
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(0, write(fd, wbuf, 3) == 3);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, write(fd, wbuf, SIZE_MAX) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EFAULT, write(fd, (void *)-1, 1) == -1);
+
+ /*
+ * Check that the above bogus write(2)
+ * calls did not corrupt the file.
+ */
+ ATF_REQUIRE(lseek(fd, 0, SEEK_SET) == 0);
+ ATF_REQUIRE(read(fd, rbuf, 3) == 3);
+ ATF_REQUIRE(memcmp(rbuf, wbuf, 3) == 0);
+
+ (void)close(fd);
+ (void)unlink(path);
+ }
+}
+
+ATF_TC_CLEANUP(write_err, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(write_pipe);
+ATF_TC_HEAD(write_pipe, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks for EPIPE from write(2)");
+}
+
+ATF_TC_BODY(write_pipe, tc)
+{
+ int fds[2];
+
+ ATF_REQUIRE(pipe(fds) == 0);
+ ATF_REQUIRE(signal(SIGPIPE, sighandler) == 0);
+
+ ATF_REQUIRE(write(fds[1], "x", 1) != -1);
+ ATF_REQUIRE(close(fds[0]) == 0);
+
+ errno = 0;
+ fail = true;
+
+ if (write(fds[1], "x", 1) != -1 || errno != EPIPE)
+ atf_tc_fail_nonfatal("expected EPIPE but write(2) succeeded");
+
+ ATF_REQUIRE(close(fds[1]) == 0);
+
+ if (fail != false)
+ atf_tc_fail_nonfatal("SIGPIPE was not raised");
+}
+
+ATF_TC_WITH_CLEANUP(write_pos);
+ATF_TC_HEAD(write_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks that write(2) "
+ "updates the file position");
+}
+
+ATF_TC_BODY(write_pos, tc)
+{
+ const size_t n = 123;
+ size_t i;
+ int fd;
+
+ fd = open(path, O_RDWR | O_CREAT);
+ ATF_REQUIRE(fd >= 0);
+
+ for (i = 0; i < n; i++) {
+ ATF_REQUIRE(write(fd, "x", 1) == 1);
+ ATF_REQUIRE(lseek(fd, 0, SEEK_CUR) == (off_t)(i + 1));
+ }
+
+ ATF_REQUIRE(close(fd) == 0);
+ ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(write_pos, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC_WITH_CLEANUP(write_ret);
+ATF_TC_HEAD(write_ret, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks return values from write(2)");
+}
+
+ATF_TC_BODY(write_ret, tc)
+{
+ const size_t n = 99;
+ char buf[123];
+ size_t i, j;
+ int fd;
+
+ fd = open(path, O_WRONLY | O_CREAT);
+ ATF_REQUIRE(fd >= 0);
+
+ (void)memset(buf, 'x', sizeof(buf));
+
+ for (i = j = 0; i < n; i++)
+ j += write(fd, buf, sizeof(buf));
+
+ if (j != n * 123)
+ atf_tc_fail("inconsistent return values from write(2)");
+
+ (void)close(fd);
+ (void)unlink(path);
+}
+
+ATF_TC_CLEANUP(write_ret, tc)
+{
+ (void)unlink(path);
+}
+
+ATF_TC(writev_iovmax);
+ATF_TC_HEAD(writev_iovmax, tc)
+{
+ atf_tc_set_md_var(tc, "timeout", "10");
+ atf_tc_set_md_var(tc, "descr",
+ "Checks that file descriptor is properly FILE_UNUSE()d "
+ "when iovcnt is greater than IOV_MAX");
+}
+
+ATF_TC_BODY(writev_iovmax, tc)
+{
+ ssize_t retval;
+
+ (void)printf("Calling writev(2, NULL, IOV_MAX + 1)...\n");
+
+ errno = 0;
+ retval = writev(2, NULL, IOV_MAX + 1);
+
+ ATF_REQUIRE_EQ_MSG(retval, -1, "got: %zd", retval);
+ ATF_REQUIRE_EQ_MSG(errno, EINVAL, "got: %s", strerror(errno));
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, write_err);
+ ATF_TP_ADD_TC(tp, write_pipe);
+ ATF_TP_ADD_TC(tp, write_pos);
+ ATF_TP_ADD_TC(tp, write_ret);
+ ATF_TP_ADD_TC(tp, writev_iovmax);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/t_cdb.c b/contrib/netbsd-tests/lib/libc/t_cdb.c
new file mode 100644
index 000000000000..5e88e6523a26
--- /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 000000000000..de68690a2432
--- /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 000000000000..e04060367143
--- /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 000000000000..66b1735131ed
--- /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 000000000000..8092361dbc36
--- /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 000000000000..99871ffdc4b6
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/time/t_strptime.c
@@ -0,0 +1,281 @@
+/* $NetBSD: t_strptime.c,v 1.1 2011/01/13 00:14:10 pgoyette Exp $ */
+
+/*-
+ * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by David Laight.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__COPYRIGHT("@(#) Copyright (c) 2008\
+ The NetBSD Foundation, inc. All rights reserved.");
+__RCSID("$NetBSD: t_strptime.c,v 1.1 2011/01/13 00:14:10 pgoyette Exp $");
+
+#include <time.h>
+
+#include <atf-c.h>
+
+static void
+h_pass(const char *buf, const char *fmt, int len,
+ int tm_sec, int tm_min, int tm_hour, int tm_mday,
+ int tm_mon, int tm_year, int tm_wday, int tm_yday)
+{
+ struct tm tm = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL };
+ const char *ret, *exp;
+
+ exp = buf + len;
+ ret = strptime(buf, fmt, &tm);
+
+#ifdef __FreeBSD__
+ ATF_CHECK_MSG(ret == exp,
+ "strptime(\"%s\", \"%s\", tm): incorrect return code: "
+ "expected: %p, got: %p", buf, fmt, exp, ret);
+
+#define H_REQUIRE_FIELD(field) \
+ ATF_CHECK_MSG(tm.field == field, \
+ "strptime(\"%s\", \"%s\", tm): incorrect %s: " \
+ "expected: %d, but got: %d", buf, fmt, \
+ ___STRING(field), field, tm.field)
+#else
+ ATF_REQUIRE_MSG(ret == exp,
+ "strptime(\"%s\", \"%s\", tm): incorrect return code: "
+ "expected: %p, got: %p", buf, fmt, exp, ret);
+
+#define H_REQUIRE_FIELD(field) \
+ ATF_REQUIRE_MSG(tm.field == field, \
+ "strptime(\"%s\", \"%s\", tm): incorrect %s: " \
+ "expected: %d, but got: %d", buf, fmt, \
+ ___STRING(field), field, tm.field)
+#endif
+
+ H_REQUIRE_FIELD(tm_sec);
+ H_REQUIRE_FIELD(tm_min);
+ H_REQUIRE_FIELD(tm_hour);
+ H_REQUIRE_FIELD(tm_mday);
+ H_REQUIRE_FIELD(tm_mon);
+ H_REQUIRE_FIELD(tm_year);
+ H_REQUIRE_FIELD(tm_wday);
+ H_REQUIRE_FIELD(tm_yday);
+
+#undef H_REQUIRE_FIELD
+}
+
+static void
+h_fail(const char *buf, const char *fmt)
+{
+ struct tm tm = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, NULL };
+
+#ifdef __FreeBSD__
+ ATF_CHECK_MSG(strptime(buf, fmt, &tm) == NULL, "strptime(\"%s\", "
+ "\"%s\", &tm) should fail, but it didn't", buf, fmt);
+#else
+ ATF_REQUIRE_MSG(strptime(buf, fmt, &tm) == NULL, "strptime(\"%s\", "
+ "\"%s\", &tm) should fail, but it didn't", buf, fmt);
+#endif
+}
+
+ATF_TC(common);
+
+ATF_TC_HEAD(common, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks strptime(3): various checks");
+}
+
+ATF_TC_BODY(common, tc)
+{
+
+#ifdef __FreeBSD__
+ atf_tc_expect_fail("There are various issues with strptime on FreeBSD");
+#endif
+
+ h_pass("Tue Jan 20 23:27:46 1998", "%a %b %d %T %Y",
+ 24, 46, 27, 23, 20, 0, 98, 2, -1);
+ h_pass("Tue Jan 20 23:27:46 1998", "%a %b %d %H:%M:%S %Y",
+ 24, 46, 27, 23, 20, 0, 98, 2, -1);
+ h_pass("Tue Jan 20 23:27:46 1998", "%c",
+ 24, 46, 27, 23, 20, 0, 98, 2, -1);
+ h_pass("Fri Mar 4 20:05:34 2005", "%a %b %e %H:%M:%S %Y",
+ 24, 34, 5, 20, 4, 2, 105, 5, -1);
+ h_pass("5\t3 4 8pm:05:34 2005", "%w%n%m%t%d%n%k%p:%M:%S %Y",
+ 21, 34, 5, 20, 4, 2, 105, 5, -1);
+ h_pass("Fri Mar 4 20:05:34 2005", "%c",
+ 24, 34, 5, 20, 4, 2, 105, 5, -1);
+
+ h_pass("x20y", "x%Cy", 4, -1, -1, -1, -1, -1, 100, -1, -1);
+ h_pass("x84y", "x%yy", 4, -1, -1, -1, -1, -1, 84, -1, -1);
+ h_pass("x2084y", "x%C%yy", 6, -1, -1, -1, -1, -1, 184, -1, -1);
+ h_pass("x8420y", "x%y%Cy", 6, -1, -1, -1, -1, -1, 184, -1, -1);
+ h_pass("%20845", "%%%C%y5", 6, -1, -1, -1, -1, -1, 184, -1, -1);
+ h_fail("%", "%E%");
+
+ h_pass("1980", "%Y", 4, -1, -1, -1, -1, -1, 80, -1, -1);
+ h_pass("1980", "%EY", 4, -1, -1, -1, -1, -1, 80, -1, -1);
+
+ h_pass("0", "%S", 1, 0, -1, -1, -1, -1, -1, -1, -1);
+ h_pass("59", "%S", 2, 59, -1, -1, -1, -1, -1, -1, -1);
+ h_pass("60", "%S", 2, 60, -1, -1, -1, -1, -1, -1, -1);
+ h_pass("61", "%S", 2, 61, -1, -1, -1, -1, -1, -1, -1);
+ h_fail("62", "%S");
+}
+
+ATF_TC(day);
+
+ATF_TC_HEAD(day, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks strptime(3): day names");
+}
+
+ATF_TC_BODY(day, tc)
+{
+
+ h_pass("Sun", "%a", 3, -1, -1, -1, -1, -1, -1, 0, -1);
+ h_pass("Sunday", "%a", 6, -1, -1, -1, -1, -1, -1, 0, -1);
+ h_pass("Mon", "%a", 3, -1, -1, -1, -1, -1, -1, 1, -1);
+ h_pass("Monday", "%a", 6, -1, -1, -1, -1, -1, -1, 1, -1);
+ h_pass("Tue", "%a", 3, -1, -1, -1, -1, -1, -1, 2, -1);
+ h_pass("Tuesday", "%a", 7, -1, -1, -1, -1, -1, -1, 2, -1);
+ h_pass("Wed", "%a", 3, -1, -1, -1, -1, -1, -1, 3, -1);
+ h_pass("Wednesday", "%a", 9, -1, -1, -1, -1, -1, -1, 3, -1);
+ h_pass("Thu", "%a", 3, -1, -1, -1, -1, -1, -1, 4, -1);
+ h_pass("Thursday", "%a", 8, -1, -1, -1, -1, -1, -1, 4, -1);
+ h_pass("Fri", "%a", 3, -1, -1, -1, -1, -1, -1, 5, -1);
+ h_pass("Friday", "%a", 6, -1, -1, -1, -1, -1, -1, 5, -1);
+ h_pass("Sat", "%a", 3, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_pass("Saturday", "%a", 8, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_pass("Saturn", "%a", 3, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_fail("Moon", "%a");
+ h_pass("Sun", "%A", 3, -1, -1, -1, -1, -1, -1, 0, -1);
+ h_pass("Sunday", "%A", 6, -1, -1, -1, -1, -1, -1, 0, -1);
+ h_pass("Mon", "%A", 3, -1, -1, -1, -1, -1, -1, 1, -1);
+ h_pass("Monday", "%A", 6, -1, -1, -1, -1, -1, -1, 1, -1);
+ h_pass("Tue", "%A", 3, -1, -1, -1, -1, -1, -1, 2, -1);
+ h_pass("Tuesday", "%A", 7, -1, -1, -1, -1, -1, -1, 2, -1);
+ h_pass("Wed", "%A", 3, -1, -1, -1, -1, -1, -1, 3, -1);
+ h_pass("Wednesday", "%A", 9, -1, -1, -1, -1, -1, -1, 3, -1);
+ h_pass("Thu", "%A", 3, -1, -1, -1, -1, -1, -1, 4, -1);
+ h_pass("Thursday", "%A", 8, -1, -1, -1, -1, -1, -1, 4, -1);
+ h_pass("Fri", "%A", 3, -1, -1, -1, -1, -1, -1, 5, -1);
+ h_pass("Friday", "%A", 6, -1, -1, -1, -1, -1, -1, 5, -1);
+ h_pass("Sat", "%A", 3, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_pass("Saturday", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_pass("Saturn", "%A", 3, -1, -1, -1, -1, -1, -1, 6, -1);
+ h_fail("Moon", "%A");
+
+ h_pass("mon", "%a", 3, -1, -1, -1, -1, -1, -1, 1, -1);
+ h_pass("tueSDay", "%A", 7, -1, -1, -1, -1, -1, -1, 2, -1);
+ h_pass("sunday", "%A", 6, -1, -1, -1, -1, -1, -1, 0, -1);
+#ifdef __NetBSD__
+ h_fail("sunday", "%EA");
+#else
+ h_pass("Sunday", "%EA", 6, -1, -1, -1, -1, -1, -1, 0, -1);
+#endif
+ h_pass("SaturDay", "%A", 8, -1, -1, -1, -1, -1, -1, 6, -1);
+#ifdef __NetBSD__
+ h_fail("SaturDay", "%OA");
+#else
+ h_pass("SaturDay", "%OA", 8, -1, -1, -1, -1, -1, -1, 6, -1);
+#endif
+}
+
+ATF_TC(month);
+
+ATF_TC_HEAD(month, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "Checks strptime(3): month names");
+}
+
+ATF_TC_BODY(month, tc)
+{
+
+ h_pass("Jan", "%b", 3, -1, -1, -1, -1, 0, -1, -1, -1);
+ h_pass("January", "%b", 7, -1, -1, -1, -1, 0, -1, -1, -1);
+ h_pass("Feb", "%b", 3, -1, -1, -1, -1, 1, -1, -1, -1);
+ h_pass("February", "%b", 8, -1, -1, -1, -1, 1, -1, -1, -1);
+ h_pass("Mar", "%b", 3, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_pass("March", "%b", 5, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_pass("Apr", "%b", 3, -1, -1, -1, -1, 3, -1, -1, -1);
+ h_pass("April", "%b", 5, -1, -1, -1, -1, 3, -1, -1, -1);
+ h_pass("May", "%b", 3, -1, -1, -1, -1, 4, -1, -1, -1);
+ h_pass("Jun", "%b", 3, -1, -1, -1, -1, 5, -1, -1, -1);
+ h_pass("June", "%b", 4, -1, -1, -1, -1, 5, -1, -1, -1);
+ h_pass("Jul", "%b", 3, -1, -1, -1, -1, 6, -1, -1, -1);
+ h_pass("July", "%b", 4, -1, -1, -1, -1, 6, -1, -1, -1);
+ h_pass("Aug", "%b", 3, -1, -1, -1, -1, 7, -1, -1, -1);
+ h_pass("August", "%b", 6, -1, -1, -1, -1, 7, -1, -1, -1);
+ h_pass("Sep", "%b", 3, -1, -1, -1, -1, 8, -1, -1, -1);
+ h_pass("September", "%b", 9, -1, -1, -1, -1, 8, -1, -1, -1);
+ h_pass("Oct", "%b", 3, -1, -1, -1, -1, 9, -1, -1, -1);
+ h_pass("October", "%b", 7, -1, -1, -1, -1, 9, -1, -1, -1);
+ h_pass("Nov", "%b", 3, -1, -1, -1, -1, 10, -1, -1, -1);
+ h_pass("November", "%b", 8, -1, -1, -1, -1, 10, -1, -1, -1);
+ h_pass("Dec", "%b", 3, -1, -1, -1, -1, 11, -1, -1, -1);
+ h_pass("December", "%b", 8, -1, -1, -1, -1, 11, -1, -1, -1);
+ h_pass("Mayor", "%b", 3, -1, -1, -1, -1, 4, -1, -1, -1);
+ h_pass("Mars", "%b", 3, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_fail("Rover", "%b");
+ h_pass("Jan", "%B", 3, -1, -1, -1, -1, 0, -1, -1, -1);
+ h_pass("January", "%B", 7, -1, -1, -1, -1, 0, -1, -1, -1);
+ h_pass("Feb", "%B", 3, -1, -1, -1, -1, 1, -1, -1, -1);
+ h_pass("February", "%B", 8, -1, -1, -1, -1, 1, -1, -1, -1);
+ h_pass("Mar", "%B", 3, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_pass("March", "%B", 5, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_pass("Apr", "%B", 3, -1, -1, -1, -1, 3, -1, -1, -1);
+ h_pass("April", "%B", 5, -1, -1, -1, -1, 3, -1, -1, -1);
+ h_pass("May", "%B", 3, -1, -1, -1, -1, 4, -1, -1, -1);
+ h_pass("Jun", "%B", 3, -1, -1, -1, -1, 5, -1, -1, -1);
+ h_pass("June", "%B", 4, -1, -1, -1, -1, 5, -1, -1, -1);
+ h_pass("Jul", "%B", 3, -1, -1, -1, -1, 6, -1, -1, -1);
+ h_pass("July", "%B", 4, -1, -1, -1, -1, 6, -1, -1, -1);
+ h_pass("Aug", "%B", 3, -1, -1, -1, -1, 7, -1, -1, -1);
+ h_pass("August", "%B", 6, -1, -1, -1, -1, 7, -1, -1, -1);
+ h_pass("Sep", "%B", 3, -1, -1, -1, -1, 8, -1, -1, -1);
+ h_pass("September", "%B", 9, -1, -1, -1, -1, 8, -1, -1, -1);
+ h_pass("Oct", "%B", 3, -1, -1, -1, -1, 9, -1, -1, -1);
+ h_pass("October", "%B", 7, -1, -1, -1, -1, 9, -1, -1, -1);
+ h_pass("Nov", "%B", 3, -1, -1, -1, -1, 10, -1, -1, -1);
+ h_pass("November", "%B", 8, -1, -1, -1, -1, 10, -1, -1, -1);
+ h_pass("Dec", "%B", 3, -1, -1, -1, -1, 11, -1, -1, -1);
+ h_pass("December", "%B", 8, -1, -1, -1, -1, 11, -1, -1, -1);
+ h_pass("Mayor", "%B", 3, -1, -1, -1, -1, 4, -1, -1, -1);
+ h_pass("Mars", "%B", 3, -1, -1, -1, -1, 2, -1, -1, -1);
+ h_fail("Rover", "%B");
+
+ h_pass("september", "%b", 9, -1, -1, -1, -1, 8, -1, -1, -1);
+ h_pass("septembe", "%B", 3, -1, -1, -1, -1, 8, -1, -1, -1);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, common);
+ ATF_TP_ADD_TC(tp, day);
+ ATF_TP_ADD_TC(tp, month);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c
new file mode 100644
index 000000000000..6c913a4a4c5a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/dso/h_tls_dlopen.c
@@ -0,0 +1,62 @@
+/* $NetBSD: h_tls_dlopen.c,v 1.5 2013/10/21 19:14:16 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: h_tls_dlopen.c,v 1.5 2013/10/21 19:14:16 joerg Exp $");
+
+#include <atf-c.h>
+#include <unistd.h>
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+extern __thread int var1;
+extern __thread int var2;
+extern __thread int *var3;
+__thread int var5 = 1;
+static __thread pid_t (*local_var)(void) = getpid;
+
+void testf_dso_helper(int x, int y);
+
+void
+testf_dso_helper(int x, int y)
+{
+ var1 = x;
+ var2 = y;
+ var3 = &optind;
+ ATF_CHECK_EQ(local_var, getpid);
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c
new file mode 100644
index 000000000000..a268068b72af
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dlopen.c
@@ -0,0 +1,115 @@
+/* $NetBSD: t_tls_dlopen.c,v 1.3 2012/01/17 20:34:57 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_tls_dlopen.c,v 1.3 2012/01/17 20:34:57 joerg Exp $");
+
+#include <atf-c.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+ATF_TC(t_tls_dlopen);
+
+ATF_TC_HEAD(t_tls_dlopen, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test (un)initialized TLS variables and dlopen");
+}
+
+void (*testf_helper)(int, int);
+
+__thread int var1 = 1;
+__thread int var2;
+__thread int *var3 = &optind;
+int var4_helper;
+__thread int *var4 = &var4_helper;
+
+static void *
+testf(void *dummy)
+{
+ ATF_CHECK_EQ(var1, 1);
+ ATF_CHECK_EQ(var2, 0);
+ ATF_CHECK_EQ(var3, &optind);
+ ATF_CHECK_EQ(var4, &var4_helper);
+ testf_helper(2, 2);
+ ATF_CHECK_EQ(var1, 2);
+ ATF_CHECK_EQ(var2, 2);
+ testf_helper(3, 3);
+ ATF_CHECK_EQ(var1, 3);
+ ATF_CHECK_EQ(var2, 3);
+ ATF_CHECK_EQ(var3, &optind);
+
+ return NULL;
+}
+
+ATF_TC_BODY(t_tls_dlopen, tc)
+{
+ void *handle;
+ pthread_t t;
+
+#ifdef __HAVE_NO___THREAD
+ atf_tc_skip("no TLS support on this platform");
+#endif
+
+ handle = dlopen("h_tls_dlopen.so", RTLD_NOW | RTLD_LOCAL);
+ ATF_REQUIRE(handle != NULL);
+
+ testf_helper = dlsym(handle, "testf_dso_helper");
+ ATF_REQUIRE(testf_helper != NULL);
+
+ testf(NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+
+ dlclose(handle);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_tls_dlopen);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c
new file mode 100644
index 000000000000..1982a9bcc76b
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_dynamic.c
@@ -0,0 +1,107 @@
+/* $NetBSD: t_tls_dynamic.c,v 1.3 2012/01/17 20:34:57 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_tls_dynamic.c,v 1.3 2012/01/17 20:34:57 joerg Exp $");
+
+#include <atf-c.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+ATF_TC(t_tls_dynamic);
+
+ATF_TC_HEAD(t_tls_dynamic, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test (un)initialized TLS variables in dynamic binaries");
+}
+
+void testf_dso_helper(int, int);
+
+extern __thread int var1;
+extern __thread int var2;
+extern __thread pid_t (*dso_var1)(void);
+
+__thread int *var3 = &optind;
+int var4_helper;
+__thread int *var4 = &var4_helper;
+
+static void *
+testf(void *dummy)
+{
+ ATF_CHECK_EQ(var1, 1);
+ ATF_CHECK_EQ(var2, 0);
+ testf_dso_helper(2, 2);
+ ATF_CHECK_EQ(var1, 2);
+ ATF_CHECK_EQ(var2, 2);
+ testf_dso_helper(3, 3);
+ ATF_CHECK_EQ(var1, 3);
+ ATF_CHECK_EQ(var2, 3);
+ ATF_CHECK_EQ(var3, &optind);
+ ATF_CHECK_EQ(var4, &var4_helper);
+ ATF_CHECK_EQ(dso_var1, getpid);
+
+ return NULL;
+}
+
+ATF_TC_BODY(t_tls_dynamic, tc)
+{
+ pthread_t t;
+
+#ifdef __HAVE_NO___THREAD
+ atf_tc_skip("no TLS support on this platform");
+#endif
+
+ testf(NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_tls_dynamic);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c
new file mode 100644
index 000000000000..db0ff16f504a
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static.c
@@ -0,0 +1,95 @@
+/* $NetBSD: t_tls_static.c,v 1.2 2012/01/17 20:34:57 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_tls_static.c,v 1.2 2012/01/17 20:34:57 joerg Exp $");
+
+#include <atf-c.h>
+#include <pthread.h>
+
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+ATF_TC(t_tls_static);
+
+ATF_TC_HEAD(t_tls_static, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Test (un)initialized TLS variables in static binaries");
+}
+
+void testf_helper(void);
+
+__thread int var1 = 1;
+__thread int var2;
+
+static void *
+testf(void *dummy)
+{
+ ATF_CHECK_EQ(var1, 1);
+ ATF_CHECK_EQ(var2, 0);
+ testf_helper();
+ ATF_CHECK_EQ(var1, -1);
+ ATF_CHECK_EQ(var2, -1);
+
+ return NULL;
+}
+
+ATF_TC_BODY(t_tls_static, tc)
+{
+ pthread_t t;
+
+#ifdef __HAVE_NO___THREAD
+ atf_tc_skip("no TLS support on this platform");
+#endif
+
+ testf(NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+
+ pthread_create(&t, 0, testf, 0);
+ pthread_join(t, NULL);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_tls_static);
+
+ return atf_no_error();
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c
new file mode 100644
index 000000000000..841b2bf712e3
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls/t_tls_static_helper.c
@@ -0,0 +1,55 @@
+/* $NetBSD: t_tls_static_helper.c,v 1.2 2012/01/17 20:34:57 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_tls_static_helper.c,v 1.2 2012/01/17 20:34:57 joerg Exp $");
+
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+extern __thread int var1;
+extern __thread int var2;
+
+void testf_helper(void);
+
+void
+testf_helper(void)
+{
+ var1 = -1;
+ var2 = -1;
+}
diff --git a/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c
new file mode 100644
index 000000000000..a5e78ffab977
--- /dev/null
+++ b/contrib/netbsd-tests/lib/libc/tls_dso/h_tls_dynamic.c
@@ -0,0 +1,58 @@
+/* $NetBSD: h_tls_dynamic.c,v 1.5 2013/10/21 19:11:17 joerg Exp $ */
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: h_tls_dynamic.c,v 1.5 2013/10/21 19:11:17 joerg Exp $");
+
+#include <unistd.h>
+#ifdef __NetBSD__
+#include <sys/tls.h>
+#endif
+
+#ifdef __HAVE_NO___THREAD
+#define __thread
+#endif
+
+__thread int var1 = 1;
+__thread int var2;
+
+__thread pid_t (*dso_var1)(void) = getpid;
+
+void testf_dso_helper(int x, int y);
+
+void
+testf_dso_helper(int x, int y)
+{
+ var1 = x;
+ var2 = y;
+}
diff --git a/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c b/contrib/netbsd-tests/lib/libc/ttyio/t_ptm.c
new file mode 100644
index 000000000000..5346898bdfc4
--- /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 000000000000..5a5ec0f988ba
--- /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();
+}